我在 Stack Overflow 上看到了一些非常好的问题,涉及委托、事件以及这两个功能的 .NET 实现。特别提出一个问题,“C# 事件在幕后如何工作? https://stackoverflow.com/questions/213638/how-do-c-events-work-behind-the-scenes#213651”,给出了一个很好的答案,很好地解释了一些微妙的观点。
上述问题的答案说明了这一点:
当您声明类似字段的事件时
...编译器生成方法
和一个私有字段(相同类型
作为代表)。班级内,
当您引用 ElementAddedEvent 时
你指的是领域。外部
班级,你指的是
场地
同一问题链接的 MSDN 文章(“现场活动 http://msdn.microsoft.com/en-us/library/aa664455.aspx") adds:
引发事件的概念是
完全相当于调用
活动代表代表 —
因此,没有特殊的语言
用于引发事件的构造。
为了进一步检查,我构建了一个测试项目,以便查看事件和委托编译为的 IL:
public class TestClass
{
public EventHandler handler;
public event EventHandler FooEvent;
public TestClass()
{ }
}
我期待代表领域handler
和事件FooEvent
编译为大致相同的 IL 代码,并使用一些附加方法来包装对编译器生成的访问FooEvent
场地。但生成的 IL 并不完全符合我的预期:
.class public auto ansi beforefieldinit TestClass
extends [mscorlib]System.Object
{
.event [mscorlib]System.EventHandler FooEvent
{
.addon instance void TestClass::add_FooEvent(class [mscorlib]System.EventHandler)
.removeon instance void TestClass::remove_FooEvent(class [mscorlib]System.EventHandler)
}
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
// Constructor IL hidden
}
.field private class [mscorlib]System.EventHandler FooEvent
.field public class [mscorlib]System.EventHandler handler
}
由于事件只不过是编译器生成的委托add
and remove
方法,我没想到会看到事件被比 IL 中的处理方式更多。但是添加和删除方法是在开始的部分中定义的.event
, not .method
和正常方法一样。
我的最终问题是:如果事件只是作为具有访问器方法的委托来实现,那么拥有一个事件有什么意义呢?.event
IL部分?如果没有这个,它们不能通过使用 IL 来实现吗?.method
部分?是.event
相当于.method
?