BRO1309: Element names should begin with an upper-case letter¶
Types, methods, properties, events, enum members and local functions are PascalCase: GetTotal, not getTotal.
Replaces StyleCop SA1300 (except for namespaces).
Example¶
Before¶
internal enum status
{
open,
closed,
}
internal class order
{
public order(status initial)
{
state = initial;
}
public status state { get; private set; }
public void close()
{
if (isOpen())
{
state = status.closed;
}
}
private bool isOpen() => state == status.open;
}
After¶
internal enum Status
{
Open,
Closed,
}
internal class Order
{
public Order(Status initial)
{
State = initial;
}
public Status State { get; private set; }
public void Close()
{
if (IsOpen())
{
State = Status.Closed;
}
}
private bool IsOpen() => State == Status.Open;
}
Why¶
PascalCase for types and members is the .NET convention: everything in the base class library and in almost every library you use is named that way, so code that follows it reads the same as the APIs it calls.
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 name is renamed everywhere in the solution, with its first letter capitalized (and leading underscores dropped):
close becomes Close, _helper becomes Helper. For a type, its constructors and finalizer are renamed too.
A member of an interface or an abstract or virtual member takes its implementations and overrides along (explicit implementations included); without them the code wouldn't compile. Those aren't reported themselves (their name comes from the base, like in StyleCop).
Checked: classes, structs, records, enums, delegates, methods, properties, events, enum members and local functions. Interfaces are BRO1304's, fields BRO1303 and BRO1306-BRO1308's.
Renaming public types and members is a breaking change for code outside the solution, and files aren't
renamed (dotnet format only changes file contents). Names used from non-C# files (XAML, Razor, configuration)
aren't seen by the fix.
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 (a local function:#ifin its member): disabled code isn't compiled, so the rename can't follow it. - Public API (unless
stylebro_rename_public_api = true): Types, methods, properties, events and enum members 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. - Namespaces. Renaming a namespace also changes embedded resource names and breaks folder conventions.
- snake_case names (an underscore after the first letter:
device_id,load_all): usually a wire name (JSON, a protocol), andDevice_idwouldn't be PascalCase either. A leading underscore alone is fine (_helper->Helper). - External methods (
extern,[DllImport],[LibraryImport]): a P/Invoke method's name is the native entry point. - Properties and enum members with attributes, usually serialization settings, and properties of types with a
serializer attribute (
[JsonObject],[DataContract], ...). - Members whose name is part of another member's name, like
itemsnext toShouldSerializeitems()oritemsSpecified: Json.NET and XML serialization pair them by name. - Partial methods (both declarations have to change together), indexers and operators.
- Types with a generated part and their members, like a Razor component's code-behind class (
List.razor.cs): the markup uses those names and its generated half can't be renamed (found in eShopOnWeb). - Members that keep the name of what they override or implement, including members that implement an interface from a library.
- The new name already means something where the element is declared: another member of the type or a base type
(
run()next toRun(int)), or a type or namespace in scope; for types, a type with that name anywhere in the solution. A local function is checked like a local variable (BRO1301).
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 name appears in a string anywhere in the solution. For instance properties and events, and enum members, that
includes appearing inside a longer string, like test JSON: serializers write them by name. Static properties and
events aren't written by serializers: only a string where code reaches a member by name counts for them
(
GetProperty("nbc"), a member-source attribute), not a URL or file name that contains the word (AngleSharp's test assets). For types, a qualified name counts too ("App.order"). - Another property of the type keeps its name because of a string. Then all of the type's properties do: renaming
only some would mix casings and change only part of what a serializer reads and writes (a JSON DTO with
documentin test JSON keepspercentagetoo). - A derived type already has a member with the new name, or some reference would see something else under it.
- Generated code uses the name: a Razor page, or a source generator's output (also a name in one of its strings). Generated code is written again by its tool, so the rename can't change it.
Rename these by hand, or suppress the warning.
Compared with StyleCop¶
Same results as StyleCop, except namespaces and snake_case names (StyleCop reports device_id; its fix would
write Device_id). StyleCop's own fix changes nothing under dotnet format.