BRO1305: Type parameter names should begin with T¶
Type parameters are named T or TItem, not Item. Replaces StyleCop SA1314.
Example¶
Before¶
using System;
using System.Collections.Generic;
internal class Cache<Key, Value>
{
private readonly Dictionary<Key, Value> items = new Dictionary<Key, Value>();
public Value Get(Key key, Func<Key, Value> create)
{
if (!items.TryGetValue(key, out var value))
{
value = create(key);
items[key] = value;
}
return value;
}
}
After¶
using System;
using System.Collections.Generic;
internal class Cache<TKey, TValue>
{
private readonly Dictionary<TKey, TValue> items = new Dictionary<TKey, TValue>();
public TValue Get(TKey key, Func<TKey, TValue> create)
{
if (!items.TryGetValue(key, out var value))
{
value = create(key);
items[key] = value;
}
return value;
}
}
Why¶
The T prefix is the .NET convention: in Cache<TKey, TValue> it's clear at a glance which names are type
parameters and which are real types.
Configuration¶
stylebro_rename_public_api = true also renames names other assemblies see (default false, see Not reported; the owner's decision in decisions.md).
How the fix works¶
The type parameter is renamed everywhere it's used, including <typeparam> docs. The new name is T plus the name
with its first letter capitalized: Item becomes TItem, _x becomes TX. A lower-case t that starts a word just
gets capitalized: t becomes T, tKey becomes TKey.
Like StyleCop, only the first letter is checked, so Type is a fine type parameter name.
A type parameter of an abstract, virtual or interface method takes the type parameters of its overrides and implementations along when they have the same name. Those aren't reported themselves (their name comes from the base).
Checked: type parameters of classes, structs, interfaces, records, delegates, methods and local functions.
Not reported¶
- Where IDE1006 is suppressed: after
#pragma warning disable IDE1006(up to itsrestore), or with[SuppressMessage("Style", "IDE1006")]on the declaration, its member or type, or a global one targeting them. Code that opts out of the SDK's naming rules (a file copied from another project) keeps its names. - A new name your SDK naming rule rejects: when the first
dotnet_naming_rulethat covers the symbol is enforced (IDE1006, or the rule's own severity, at suggestion or above) and asks for another style, like_camelCasefor private properties, the name stays (renaming it would only trade this warning for IDE1006). - The name appears in code excluded by
#ifinside the method or type that declares it: disabled code isn't compiled, so the rename would leave it behind and break the target frameworks that compile it (Bogus:Vrenamed toTV, an#if STANDARDbranch keptAction<T, V>). - Public API (unless
stylebro_rename_public_api = true): Type parameters of types and methods that other assemblies see, that is public, protected or protected internal in types that are visible too. Renaming them breaks code outside the solution. Internal code is renamed, also withInternalsVisibleTo. - The new name already means something: a type with that name anywhere in the solution, or a member, type parameter or imported type with that name in scope.
- Partial methods. Both declarations have to be renamed together.
- Type parameters of a type with a generated part, like a Razor component (
@typeparam): its generated half declares them too and can't be renamed.
Reported but not fixed¶
If dotnet format leaves a finding, StyleBro kept it on purpose. The fix looks at the whole solution, other
projects included, which the analyzer can't see, and leaves a change that would break something there: the name in a
string or a nameof (reflection, serialization), a member that would hide it, a use in generated code. It offers no
code action for such a finding, and stylebro-migrate format lists each one with its reason
(Findings kept on purpose); its --verify-no-changes doesn't fail on
them. Change it by hand only after checking those uses, or suppress it or record it in the baseline.
Compared with StyleCop¶
Same results as StyleCop. StyleCop's own fix changes nothing under dotnet format.