BRO1301: Variable names should begin with a lower-case letter¶
Local variables and query range variables are camelCase: total, not Total or _total. Replaces StyleCop
SA1312.
Example¶
Before¶
using System.Collections.Generic;
using System.Linq;
public class Basket
{
public decimal Total(IEnumerable<decimal> prices)
{
decimal Sum = 0;
foreach (var Price in prices)
{
Sum += Price;
}
var _discounted = from P in prices where P > 100 select P * 0.9m;
return Sum - prices.Where(x => x > 100).Sum() + _discounted.Sum();
}
}
After¶
using System.Collections.Generic;
using System.Linq;
public class Basket
{
public decimal Total(IEnumerable<decimal> prices)
{
decimal sum = 0;
foreach (var price in prices)
{
sum += price;
}
var discounted = from p in prices where p > 100 select p * 0.9m;
return sum - prices.Where(x => x > 100).Sum() + discounted.Sum();
}
}
Why¶
C# names locals and parameters in camelCase and everything else in PascalCase, so the case tells you at a glance
whether a name is local to the method. _name is the convention for private fields, not locals.
How the fix works¶
The variable and every use of it are renamed. The new name drops leading underscores and lowers the leading
capitals: Total becomes total, _total becomes total, URL becomes url, and HTMLParser becomes
htmlParser (the capital that starts the next word stays). Words separated by underscores are joined like
BRO1308 joins a field's: RANGE_REP_REG becomes rangeRepReg, Max_Value becomes maxValue.
Checked: local variables (including using, for, foreach, catch, out var, pattern and deconstruction
variables) and query range variables (from, let, join, into). Local constants are PascalCase and aren't
reported.
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 fix only renames when the new name can't change what any code refers to. Checked by syntax over the member that contains the variable, so it errs on the side of skipping: -
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 is already used in the member, for anything: another variable, a field, a property of another
object (
var Value = value;in a setter). - Two names in the member would get the same new name (
Totaland_total). - The variable names an anonymous type member or tuple element by inference (
new { Total },(Total, 2)). The rename would rename the member or element too. - The member contains
#if. Code that isn't compiled for the current target can't be renamed reliably. - Names without a camelCase form: only underscores (
_,___), a digit after the underscores (_1), a keyword (Classwould becomeclass), orfield(Field): in C# 14fieldis a keyword inside property accessors, where a local namedfielddoesn't compile (CS9273). - Names in an expression tree: range variables of a query, and parameters of a lambda, that end up in a
System.Linq.Expressionstree (a query overIQueryable, anExpression<Func<...>>lambda, or a lambda nested in one). The names are data at run time: they show in the expression'sToString()and query providers may use them (Mapster's tests compare a query's text, andfrom Param_0 in ...->param0failed one). StyleCop's SA1312/SA1313 report them. valueinside a property, indexer or event (var Value = 2;in a setter): the accessor's implicitvalueparameter already has that name.
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, a name that keeps
IDE0042 (deconstruct variable declaration, a warning or an error in your settings) from reporting a tuple variable next to it. 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, except for the skipped cases above (names in expression trees among them). StyleCop's fix for SA1312 only lowers the first letter,
can't fix names that start with _, and under dotnet format applies only some of the renames per run.