在LINQ语句中什么是静态选择器/谓词?

3

我最近遇到了这种语法:

var projection = myCollection.Select(static f => f.MyProperty);

这是我第一次在Select语句中看到 static 谓词语法。

话虽如此,我还没有找到任何关于其优缺点的可靠文档。有人可以给我解释一下吗?

谢谢!


2
请查看静态匿名函数。动机是避免无意中捕获封闭上下文的状态,这可能导致意外保留捕获对象或意外的额外分配。 - T N
1
不要介意我自己的宣传:理解 C# 委托的成本 - Paulo Morgado
1个回答

2
根据 C# 文档,从 C# 9.0 开始,你可以在 lambda 表达式中应用 static 修饰符,以防止 lambda 意外捕获局部变量或实例状态。此外,它只是防止您访问定义 lambda 的对象(this 和 base)。例如,以下代码是合法的:
return Collection.Select(f =>
{
    if (this.Type == "Thing")
        return f.Value;
    return 0;
}).Sum();

这是与IT技术无关的内容:

//                       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();

摘要基准测试

public long Benchmark() => Collection.Select(static f => f.Value).Sum();

方法 N 类型 平均时间 误差 标准差 中位数 代码大小
非静态 1000 21.49 微秒 1.560 微秒 4.574 微秒 18.90 微秒 2,663 字节
静态 1000 20.83 微秒 1.279 微秒 3.750 微秒 19.30 微秒 2,665 字节
非静态 1000 结构体 18.63 微秒 1.274 微秒 3.756 微秒 16.20 微秒 1,734 字节
静态 1000 结构体 19.57 微秒 1.391 微秒 4.035 微秒 19.10 微秒 1,734 字节
非静态 100000 1,505.53 微秒 117.721 微秒 335.865 微秒 1,495.05 微秒 1,812 字节
静态 100000 1,530.50 微秒 123.061 微秒 362.849 微秒 1,499.05 微秒 1,711 字节
非静态 100000 结构体 1,024.84 微秒 86.955 微秒 255.023 微秒 913.40 微秒 1,410 字节
静态 100000 结构体 1,040.97 微秒 79.565 微秒 229.563 微秒 951.30 微秒 简述:

性能没有差别 (平均差异在标准误范围内!),同时减少垃圾回收的压力。无害无碍!如果你的代码是面向对象的,并且要避免因为行为异常的lambda表达式而卡住“死”对象,我建议使用这个方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接