对内联事件处理程序参数的好奇
本文关键字:参数 好奇 程序 事件处理 | 更新日期: 2023-09-27 17:59:38
我想知道一些事情。假设我有一个名为SomethingChanged的事件,有两个参数。第一个是触发事件的发送方。第二个只是一个数字。
案例1:
我在SenderClass
:中定义了此事件
public event Action<SenderClass, int> SomethingChanged;
通常情况下,我可以像这样附加事件处理程序:
item.SomethingChanged += (sender, p) =>
{
if (p == 1) sender.F1();
else sender.F2();
};
案例2:
但如果我删除发件人参数:
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中找到那个发送方的?它是使用反射,还是两者都转换为相同的程序集代码?或
这是因为在第二种情况下,您使用的是item
局部变量,它可以从lambda中访问。编译器不需要了解sender
变量,因为它根本没有被使用,也没有被提供,在第二种情况下根本不存在。
从Lambda表达式中的可变范围:
lambda可以引用在定义lambda的封闭方法或类型的作用域中的外部变量。以这种方式捕获的变量被存储在lambda表达式中以供使用,即使变量会超出范围并被垃圾收集。在lambda表达式中使用外部变量之前,必须对其进行明确赋值。
如果你想了解变量捕获是如何发生的,请查看评论中@Sriram提供的链接中的答案。