BRO1125: Use lambda syntax¶
(s, e) => { } instead of delegate (object s, EventArgs e) { }. Replaces StyleCop SA1130.
Example¶
Before¶
using System;
using System.Collections.Generic;
public class Button
{
public event EventHandler? Clicked;
public void Wire(List<string> log)
{
Clicked += delegate { log.Add("clicked"); };
log.RemoveAll(delegate (string entry) { return entry.Length == 0; });
}
}
After¶
using System;
using System.Collections.Generic;
public class Button
{
public event EventHandler? Clicked;
public void Wire(List<string> log)
{
Clicked += (sender, e) => { log.Add("clicked"); };
log.RemoveAll(entry => { return entry.Length == 0; });
}
}
Why¶
Lambdas are the modern form of anonymous methods; mixing both makes code look older than it is.
How the fix works¶
Like StyleCop's fix: the parameter types are dropped, async stays, and a cast's operand gets parentheses
((Action)(() => { })). A delegate { } without a parameter list gets the delegate's parameter names, made unique
against names in scope and in the body (sender1). The body isn't touched. The lambda is bound in place first: it
must convert to the same delegate type and, as an argument, call the same overload.
Not reported¶
- Calls where the lambda would pick another overload or be ambiguous:
Run(delegate { return 1; })withRun(Func<int>)andRun(Expression<Func<int>>)would call the expression overload. - Anonymous methods without a target type (
var f = delegate (int x) { ... }: a lambda without parameter types has none), parameters withref/out/params, attributes or defaults, a missing parameter list for a delegate withref/outparameters, and comments betweendelegateand the body.
Compared with StyleCop¶
Same positions, except the cases above (StyleCop checks overloads only for arguments, so its fix for a var breaks
the build) and calls like list.ForEach(delegate (int item) { ... }), which StyleCop misses and StyleBro converts.
StyleCop's fix also leaves two spaces after = and pulls a body on its own line up behind =>.