关于内联事件处理程序参数的好奇心

时间:2014-04-23 10:01:34

标签: c# compiler-construction lambda

我对某事感到疑惑。让我们说我有一个名为SomethingChanged的事件,带有2个参数。首先是发送者,它会触发事件。第二个只是一个数字。

案例1:

我在SenderClass中定义了此事件:

public event Action<SenderClass, int> SomethingChanged;

通常我可以像这样附加事件处理程序:

item.SomethingChanged += (sender, p) =>
{
    if (p == 1) sender.F1();
    else sender.F2();
};

案例2:

但如果删除sender参数:

public event Action<int> SomethingChanged;

它不会改变一件事我仍然可以使用它:

item.SomethingChanged += p =>
{
    if (p == 1) item.F1();
    else item.F2();
};

对我来说很明显,通过删除发件人,以下用法不再可行:

item.SomethingChanged += item_SomethingChanged;

private void item_SomethingChanged(SenderClass sender, int p)
{
    if (p == 1) sender.F1();
    else sender.F2();
}

问题:

但我感到好奇的是如何编译器在Case2中找到关于该发件人的内容?它是否使用反射或它们是否都转换为相同的汇编代码?或?

1 个答案:

答案 0 :(得分:3)

那是因为在你的第二种情况下,你使用的是item局部变量,可以从你的lambda访问。编译器不需要找出有关sender变量的信息,因为它根本就没有被使用 - 也没有被提供,在第二种情况下根本就不存在。

来自Variable Scope in Lambda Expressions

  

Lambdas可以引用封闭方法或定义lambda的类型的范围内的外部变量。以这种方式捕获的变量被存储用于lambda表达式,即使变量否则会超出范围并被垃圾收集。必须明确赋值外部变量,然后才能在lambda表达式中使用它。

如果您想了解变量捕获是如何发生的,请在评论中通过@Sriram check the answer from the link provided