Skip to content

BRO1107: Split parameters should start on the line after the declaration

When parameters or arguments span several lines, the first one goes on its own line too, one level deeper than the line with the opening parenthesis. Replaces StyleCop SA1116.

Example

Before

public class Invoice
{
    public Invoice(string number,
        decimal amount)
    {
        Number = number;
        Amount = amount;
    }

    public string Number { get; }

    public decimal Amount { get; }

    public static Invoice Create() => new Invoice("2026-001",
        100m);
}

After

public class Invoice
{
    public Invoice(
        string number,
        decimal amount)
    {
        Number = number;
        Amount = amount;
    }

    public string Number { get; }

    public decimal Amount { get; }

    public static Invoice Create() => new Invoice(
        "2026-001",
        100m);
}

Why

With the first item next to the parenthesis, the items don't line up: the first one sits far to the right of the others, and renaming the method moves it. On its own line, every item starts at the same column.

How the fix works

The first item moves to a new line. The indentation comes from .editorconfig (indent_style, indent_size, tab_width) and defaults to four spaces. The item's later lines (a lambda's block body) move with it, by the same amount. The other items stay where they are. amount; a multi-line string inside keeps its lines. The other items stay where they are, unless BRO1108 is on: once the first item starts a line, BRO1108 wants every item on its own line, so the fix does that in the same step (moving the first item alone can indent the line where it ends deeper than the next item's continuation lines, which a later move would then leave behind).

Checked: parameters of methods, constructors, indexers, delegates, operators, local functions, lambdas and anonymous methods, records and primary constructors; arguments of calls, new, attributes, element access and a primary constructor's base type; array sizes (new int[2, 3]).

Configuration

[*.cs]
# next_line (default, like StyleCop): a split list's first item goes on the line after '('; same_line: it may stay
stylebro_split_list_first_item = next_line

With same_line (or with BRO1107 off: owner's decision, see decisions), BRO1107 reports nothing: a split list may start on the ( line or on the next one. The fix of BRO1108 (items all on one line or each on its own) then keeps a first item that is on the ( line there and puts every other item on its own line, indented like the first item of the list that already starts a line (aligned under the first item or one level deeper, whichever the list does), else one level deeper than the line with the (. Nothing is moved up to the ( line, so aligned lines and line lengths stay as they are.

// BRO1108 with next_line
public decimal Apply(
    decimal price,
    decimal discount,
    decimal minimum)

// BRO1108 with same_line
public decimal Apply(decimal price,
                     decimal discount,
                     decimal minimum)

(Before: public decimal Apply(decimal price, then decimal discount, decimal minimum), aligned under decimal price.)

stylebro_allow_leading_multiline_lambda = true (see BRO1108) leaves a call whose first argument is a multi-line lambda, anonymous method or anonymous object on the ( line, with the other arguments on its closing line (Register(ctx => / { ... } / }, SymbolKind.Field);).

Not reported

  • The first two items on the same line (M(a, b, then c)). That's BRO1108's case.
  • A single item that spans lines, like a lambda: Select(x => then x + 1).
  • A comment or directive between the parenthesis and an item, or between items. The fix rewrites exactly those gaps, so it would have to move or drop the comment.
  • Lists with syntax errors.
  • A list with an item that contains a multi-line string (verbatim, raw or interpolated): see BRO1108.

Compared with StyleCop

StyleCop has no same_line or stylebro_allow_leading_multiline_lambda option. With the default, same results as StyleCop, except that StyleCop 1.2.0-beta.556 doesn't check record parameters, primary-constructor parameters or a primary constructor's base arguments. StyleBro treats them like any other list.

StyleCop's fix leaves a moved lambda's block body at its old indentation (#1620, #3183, open); StyleBro moves it with the lambda. Nested lists (M(N(1, then 2), then 3)) are fixed outer list first, so Fix All gives the same result as fixing them one by one.