BRO1304: Interface names should begin with I¶
Interfaces are named IShape, not Shape. Replaces StyleCop SA1302.
Example¶
Before¶
internal interface Shape
{
double Area();
}
internal class Square : Shape
{
public double Side { get; set; }
public double Area() => Side * Side;
public static double Total(Shape[] shapes)
{
double total = 0;
foreach (Shape shape in shapes)
{
total += shape.Area();
}
return total;
}
}
After¶
internal interface IShape
{
double Area();
}
internal class Square : IShape
{
public double Side { get; set; }
public double Area() => Side * Side;
public static double Total(IShape[] shapes)
{
double total = 0;
foreach (IShape shape in shapes)
{
total += shape.Area();
}
return total;
}
}
Why¶
The I prefix is the .NET convention: it tells you at a glance that a type is a contract, not a class you can
create.
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 interface is renamed everywhere in the solution: declarations (every part of a partial interface), base lists,
types of variables and parameters, typeof, nameof and cref references. The new name is I plus the name with its
first letter capitalized: Shape becomes IShape, iShape becomes IShape, _Shape becomes IShape.
Like StyleCop, only the first letter is checked, so Item is a fine interface name.
The file isn't renamed. dotnet format only changes file contents, so Shape.cs keeps its name; rename it by
hand if you keep file names in sync with type names. Renaming a public interface is a breaking change for code
outside the solution.
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
#ifanywhere in the project: disabled code isn't compiled, so the rename can't follow it (andstylebro-migrate formatformats one target framework at a time). - Public API (unless
stylebro_rename_public_api = true): Interfaces 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. - A name that
nameof(...)produces: the rename would change the string (Ocelot built an HTTP header name withnameof(X_RateLimit_Limit), and a test read a private field withGetField(nameof(_components))). Looked for in the member for variables and parameters, in the type for fields; the fix also looks in the rest of the solution and leaves the warning when it finds one. - 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 where the interface is declared.
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.
- The interface's name appears in a string anywhere in the solution, alone or qualified (
"App.Shape","App.Shape, App"): code can load types by name (Type.GetType, dependency injection, serializers), and the rename would still compile but fail at run time. - A reference somewhere else would see a different type with the new name, for example a file with
using System.Collections;that uses an interfaceEnumerable(it would becomeIEnumerable).
Rename these by hand, or suppress the warning.
Compared with StyleCop¶
Same results as StyleCop. StyleCop's own fix changes nothing under dotnet format.