我对某事感到疑惑。让我们说我有一个名为SomethingChanged的事件,带有2个参数。首先是发送者,它会触发事件。第二个只是一个数字。
我在SenderClass
中定义了此事件:
public event Action<SenderClass, int> SomethingChanged;
通常我可以像这样附加事件处理程序:
item.SomethingChanged += (sender, p) =>
{
if (p == 1) sender.F1();
else sender.F2();
};
但如果删除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中找到关于该发件人的内容?它是否使用反射或它们是否都转换为相同的汇编代码?或?
答案 0 :(得分:3)
那是因为在你的第二种情况下,你使用的是item
局部变量,可以从你的lambda访问。编译器不需要找出有关sender
变量的信息,因为它根本就没有被使用 - 也没有被提供,在第二种情况下根本就不存在。
来自Variable Scope in Lambda Expressions:
Lambdas可以引用封闭方法或定义lambda的类型的范围内的外部变量。以这种方式捕获的变量被存储用于lambda表达式,即使变量否则会超出范围并被垃圾收集。必须明确赋值外部变量,然后才能在lambda表达式中使用它。
如果您想了解变量捕获是如何发生的,请在评论中通过@Sriram check the answer from the link provided。