Styles¶
StyleBro's preset follows StyleCop's defaults: that is the stylecop style, the default. Another style is a second
layer on top of the preset, for code that follows another well-known way of writing C#. There is one: microsoft,
the coding style of
dotnet/runtime, which much of .NET
copies: _camelCase and s_camelCase fields, no this., braces optional on one-line bodies, fields at the top of the type.
<!-- Directory.Build.props -->
<StyleBroPreset>1.0</StyleBroPreset>
<StyleBroStyle>microsoft</StyleBroStyle>
The easiest way to set it up is init:
bro init --style microsoft --write
It writes both properties and the severities of the built-in .NET rules the style needs into .editorconfig (dotnet
format reads rule severities only from there). As always, what your code clearly does wins: with this. on most member
accesses, init turns IDE0003 off instead of removing them; with count instead of _count fields, it writes
stylebro_private_field_naming = camelCase. The report says which conventions it kept.
Plain init suggests the style when your code looks like runtime's (_ and s_ fields, no this.); it never sets it
by itself.
To say in the build which style you use when it's the default, set <StyleBroStyle>stylecop</StyleBroStyle> (init
--style stylecop --write writes it). It changes nothing: the preset already is StyleCop's defaults.
CSharpier isn't a style: it decides who formats the layout, not which conventions the code follows, so it works with
any style. When the repository uses it (a .csharpierrc, the csharpier dotnet tool or the CSharpier.MsBuild
package), init turns off the rules for the layout CSharpier owns, and bro format runs CSharpier after its own
fixes. Details: what init keeps from your code.
How it combines¶
- The style needs the preset: with
<StyleBroPreset>none</StyleBroPreset>it is ignored, with warning STYLEBRO004. Any value other thanstylecop,microsoftornonefails the build (STYLEBRO003).noneand an unset style mean the same asstylecop: the preset alone. - It follows the preset version: it never turns on a rule your
<StyleBroPreset>doesn't have. - Your own
.editorconfigand.globalconfigwin over it, as they win over the preset. bro migrate --write(coming from StyleCop) doesn't use a style: its block follows your StyleCop settings, and it removes<StyleBroStyle>if it finds one.--styleworks withinitonly.
What it sets¶
From runtime's guide, its root .editorconfig and, for StyleBro's rules neither mentions, the StyleCop severities in
runtime's own build (eng/CodeAnalysis.src.globalconfig), read at commit 24543ddd (2026-10-16).
| Runtime's rule | StyleBro |
|---|---|
Private and internal fields _camelCase, static ones s_camelCase (also static readonly); constants PascalCase |
stylebro_private_field_naming = _camelCase, stylebro_internal_field_naming = like_private, stylebro_private_static_field_naming = s_camelCase, stylebro_private_mutable_static_field_naming = s_camelCase (BRO1303, BRO1306) |
| Fields at the top of the type, nothing else ordered | stylebro_member_order_scope = fields_first (BRO1001) |
| Braces may be left out of a one-line body; required when it spans lines or another block of the chain has them | csharp_prefer_braces = when_multiline (BRO1515, BRO1516) |
No this. unless needed |
IDE0003 at warning |
var only where the type is named on the right |
csharp_style_var_* options, IDE0008 a suggestion |
nameof(...) instead of a string |
CA1507 at warning |
Internal and private types sealed or static |
CA1052 at warning (private, internal only), CA1852 a suggestion |
Pattern matching, ??, is null, static local functions, ?.Invoke |
IDE0020, IDE0029, IDE0030, IDE0041, IDE0062, IDE1005 at warning |
Visibility first, usings outside the namespace and sorted with System first, Allman braces, keywords instead of type names, one blank line at most |
the preset already does it; init writes dotnet_sort_system_directives_first = true unless your code clearly doesn't sort its usings |
The rest of runtime's .editorconfig code-style options (object and collection initializers, expression bodies, default
literals, no index and range operators, ...) are set too; their rules are suggestions, shown in the IDE and not applied by
dotnet format, as in runtime's build.
Off in the style, because runtime's build has the StyleCop rules they replace off: comment spacing, empty statements,
combined attributes, constants on the left, constructor initializer and parameter list layout, regions inside members,
one field per declaration, Nullable<T>, empty comments, literal suffixes, anonymous methods, qualified usings, base.,
comments before {, variable and type parameter names, m_ prefixes and underscores in field names, tuple element
casing, trailing commas, unnecessary and precedence parentheses, most blank-line rules (BRO1501-BRO1506, BRO1511,
BRO1513, BRO1518, BRO1519), single-line blocks and accessor layout (BRO1508-BRO1510), and the documentation rules that
reword or add text (BRO1601-BRO1607, BRO1610, BRO1611). StyleBro's rules beyond StyleCop (BRO1133-BRO1151, BRO1408,
BRO1410, BRO1520-BRO1527, BRO1616-BRO1619) are off too: runtime says nothing about them. Turn any of them back on in
.editorconfig (dotnet_diagnostic.BRO1401.severity = warning).
Known differences from runtime¶
- Constant locals are PascalCase in runtime's guide; nothing renames them (BRO1301 leaves local constants alone).
if (x) return;on one line: the guide wants the statement on its own line; nothing moves it.- Non-ASCII characters as
\uXXXX: not checked. - Target-typed
new()only where the type is named on the left: nothing writes the type back intox = new(...). t_thread-static fields: not added ([ThreadStatic]fields keep their names).- A file's own style wins (guide rule 9): StyleBro decides per repository (and per folder through
.editorconfig), not per file. - CA1852 (seal internal types) is a suggestion, not runtime's warning: the SDK's fix seals a type with
virtualmembers without removingvirtual, which doesn't compile. - IDE0003 (remove
this.) is a warning, where runtime's build has it as a suggestion: the guide asks for nothis.. - The file header (the .NET Foundation's license) isn't set: it's runtime's, not a style. BRO1615 and IDE0073 stay your choice.
- Moving fields to the top (
fields_first) keeps blank lines although BRO1505 is off: fields moved together stay together, and the members they leave get a blank line between them where they had one (no}glued to the next member). Blank lines nothing moves past are left as written. - Local functions on one line (
int Square(int v) { return v * v; }): the SDK's formatting (IDE0055, runtime'scsharp_new_line_before_open_brace = allwithcsharp_preserve_single_line_blocks = true) moves the{to the next line and keeps the body on it ({ return v * v; }); a one-line method stays as written. That is the SDK's, not StyleBro's; BRO1509, which expands such blocks, is off in the style.
Versions¶
The style is pinned per StyleBro major version: within 1.x its values for existing rules and settings don't change, also when runtime's guide does (such changes are listed here as differences until 2.0). A minor release decides only its own new rules, behind the preset version, like the preset (see versioning).