为什么静态 lambda (C# 9) 仍然有目标?

tra*_*ter 26 .net c#

C# 9 中引入的静态 lambda 允许我们将 lambda 表达式标记为静态,以防止它捕获实例状态。

但是,当您检查 lambda 上的 .Target 属性时,它仍然被设置,这与您将 Action 设置为没有目标的静态方法时不同。

Action action = static () => Console.WriteLine("test");
if(action.Target != null)
{
    // action unexpectedly holds a reference
}
Run Code Online (Sandbox Code Playgroud)

背景:我正在尝试创建一个事件系统(不依赖于当前的事件语法),它使用弱引用而不需要反射(MethodInfo)。我正在检查 .Target 是否为 null,但这对于静态 lambda 不起作用,其中静态 lambda .Target 设置为嵌套单例。

Jos*_*hua 32

因为静态委托比实例方法的委托慢。

这是直接来自马口的来源:评论问题“静态类中没有捕获的 Lambda 方法生成实例方法”

这是我不久前提出的一个问题,它可以消除执行此操作的需要:[fastthis] Delegate performance being eated by not pass this in private register

原因在于调用约定的内部。所有委托调用都是对委托方法的成员函数调用。在祖先平台中,静态委托仅编译为两条指令(pop并且是jmp间接指令);然而,现代平台在寄存器中而不是在堆栈上传递参数。这意味着实例委托调用可以编译为两条指令(movjmp indirect);然而,静态委托必须编译以生成整个堆栈帧并复制所有参数,以便它可以从参数列表中删除实例参数。