【发布时间】:2008-10-20 20:35:30
【问题描述】:
我在 Stack Overflow 上看到了一些关于委托、事件和这两个功能的 .NET 实现的非常好的问题。特别是一个问题,“How do C# Events work behind the scenes?”,产生了一个很好的答案,很好地解释了一些微妙的观点。
上述问题的答案说明了这一点:
当你声明一个类似字段的事件时 ...编译器生成方法 和一个私有字段(同类型 作为代表)。课堂内, 当您参考 ElementAddedEvent 你指的是这个领域。外部 类,你指的是 字段
从同一问题(“Field-like events”)链接的 MSDN 文章补充说:
引发事件的概念是 完全等同于调用 事件代表的代表—— 因此,没有特殊的语言 用于引发事件的构造。
为了进一步检查,我构建了一个测试项目,以查看事件和委托编译到的 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 和remove 方法的委托,我没想到会在IL 中看到事件被视为更多。但是添加和删除方法是在以.event 开头的部分中定义的,而不是像普通方法那样在.method 开始。
我的终极问题是:如果事件被简单地实现为具有访问器方法的委托,那么拥有.event IL 部分的意义何在?如果没有这个,它们不能通过使用.method 部分在 IL 中实现吗? .event 是否等同于 .method?
【问题讨论】:
标签: c# .net events delegates cil