I've seen some very good questions on Stack Overflow concerning delegates, events, and the .NET implementation of these two features. One question in particular, "How do C# Events work behind the scenes?", produced a great answer that explains some subtle points very well.
The answer to the above question makes this point:
When you declare a field-like event ... the compiler generates the methods and a private field (of the same type as the delegate). Within the class, when you refer to ElementAddedEvent you're referring to the field. Outside the class, you're referring to the field
An MSDN article linked from the same question ("Field-like events") adds:
The notion of raising an event is precisely equivalent to invoking the delegate represented by the event — thus, there are no special language constructs for raising events.
Wanting to examine further, I built a test project in order to view the IL that an event and a delegate are compiled to:
public class TestClass
{
public EventHandler handler;
public event EventHandler FooEvent;
public TestClass()
{ }
}
I expected the delegate field handler
and the event FooEvent
to compile to roughly the same IL code, with some additional methods to wrap access to the compiler-generated FooEvent
field. But the IL generated wasn't quite what I expected:
.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
}
Since events are nothing more than delegates with compiler-generated add
and remove
methods, I didn't expect to see events treated as anything more than that in IL. But the add and remove methods are defined in a section that begins .event
, not .method
as normal methods are.
My ultimate questions are: if events are implemented simply as delegates with accessor methods, what is the point of having a .event
IL section? Couldn't they be implemented in IL without this by using .method
sections? Is .event
equivalent to .method
?