I recently came across this syntax:
var projection = myCollection.Select(static f => f.MyProperty);
and it's the first time I'd seen this static
predicate syntax in a Select statement.
That said, I've yet to find any solid documentation on the benefits/drawbacks of this. Can somebody enlighten me?
Thanks!
CodePudding user response:
According to the C# documentation,
Beginning with C# 9.0, you can apply the static modifier to a lambda expression to prevent unintentional capture of local variables or instance state by the lambda
In other news, it just prevents you from accessing the object the lambda was defined in (this
and base
)
EG, this is legal:
return Collection.Select(f =>
{
if (this.Type == "Thing")
return f.Value;
return 0;
}).Sum();
And this is not:
// static declared here...
// vvvvvv
return Collection.Select(static f =>
{
// ...but this instance is referenced here!
// vvvv
if (this.Type == "Thing")
return f.Value;
return 0;
}).Sum();
Summary Benchmarks
public long Benchmark() => Collection.Select(static f => f.Value).Sum();
Method | N | Type | Mean | Error | StdDev | Median | Code Size |
---|---|---|---|---|---|---|---|
NonStatic | 1000 | Class | 21.49 us | 1.560 us | 4.574 us | 18.90 us | 2,663 B |
Static | 1000 | Class | 20.83 us | 1.279 us | 3.750 us | 19.30 us | 2,665 B |
NonStatic | 1000 | Struct | 18.63 us | 1.274 us | 3.756 us | 16.20 us | 1,734 B |
Static | 1000 | Struct | 19.57 us | 1.391 us | 4.035 us | 19.10 us | 1,734 B |
NonStatic | 100000 | Class | 1,505.53 us | 117.721 us | 335.865 us | 1,495.05 us | 1,812 B |
Static | 100000 | Class | 1,530.50 us | 123.061 us | 362.849 us | 1,499.05 us | 1,711 B |
NonStatic | 100000 | Struct | 1,024.84 us | 86.955 us | 255.023 us | 913.40 us | 1,410 B |
Static | 100000 | Struct | 1,040.97 us | 79.565 us | 229.563 us | 951.30 us | 1,309 B |
TL;DR:
No difference in performance (mean differences are within stderror!), while reducing GC pressure. No harm no foul! I'd suggest using this if your code is heavily object oriented to avoid hanging onto "dead" objects through a misbehaving lambda.