Home > Net >  static selector/predicate in LINQ statements?
static selector/predicate in LINQ statements?

Time:07-30

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.

  • Related