Skip to content

BRO1142: Do not combine local variables

Each local variable has its own declaration: int a = 1, b; becomes int a = 1; and int b;. Not a StyleCop rule (Roslynator RCS1081, Sonar S1659); BRO1114 (SA1132) does the same for fields.

Example

Before

public class Totals
{
    public int Sum(int[] values)
    {
        int total = 0, count = 0;
        foreach (var value in values)
        {
            total += value;
            count++;
        }

        return count == 0 ? 0 : total;
    }
}

After

public class Totals
{
    public int Sum(int[] values)
    {
        int total = 0;
        int count = 0;
        foreach (var value in values)
        {
            total += value;
            count++;
        }

        return count == 0 ? 0 : total;
    }
}

Why

One declaration per line is easier to read, to change and to review: adding, removing or commenting one variable touches one line, and every variable's type is next to its name.

How the fix works

Every variable gets a declaration with the same modifiers (const, ref) and type, on its own line at the same indentation. A declaration that shares its line with other code (void M() { int a, b; }) is split on that line ({ int a; int b; }), so it converges with BRO1509's expansion in either order.

The SDK's var preference is followed. Where csharp_style_var_for_built_in_types, _when_type_is_apparent or _elsewhere is true with a severity that reports (suggestion, warning, error, or IDE0007 turned on by its own severity key), the new declarations say var (bool a = true, b = true; becomes var a = true; and var b = true;), so IDE0007 doesn't report them. Like the SDK, a built-in type (bool, string) is judged by the first setting, an initializer that names the type (new T(), a cast, as T) by the second, anything else by the third.

Not reported

  • using declarations (using Stream a = ..., b = ...;): the dispose order is part of the code's meaning.
  • for initializers and fixed statements: they aren't local declaration statements, and splitting them would change the scope or not compile.
  • A comment or directive inside the declaration.
  • A declaration where the var preference applies but var can't be written with the same meaning: a variable without an initializer, with null, default or a target-typed new(), or whose initializer has another type (long a = 1, b = 2;). Explicit types there would break the preference, var would change the code (found in spreadcheetah: 32 IDE0007 warnings after a split).

Compared with StyleCop

StyleCop's SA1132 checks fields only. stylebro-migrate turns BRO1142 off (see Rules beyond StyleCop).