Я видел несколько очень хороших вопросов о переполнении стека, касающихся делегатов, событий и реализации этих двух функций в .NET. В частности, один вопрос « Как C # Events работает за кулисами? », дал отличный ответ, который очень хорошо объясняет некоторые тонкие моменты.
Ответ на поставленный выше вопрос подтверждает следующее:
Когда вы объявляете событие типа поля
... компилятор генерирует методы
и личное поле (того же типа
как делегат). В классе,
когда вы ссылаетесь на ElementAddedEvent
Вы имеете в виду поле. за пределами
класс, вы имеете в виду
поле
В статье 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? Разве они не могут быть реализованы в IL без этого с помощью секций .method
? .event
эквивалентно .method
?