C#позволяет нам создавать пользовательские методы доступа к событиям .
Action _custom;
public event Action Custom
{
add { _custom = (Action)Delegate.Combine( _custom, value ); }
remove { _custom = (Action)Delegate.Remove( _custom, value ); }
}
Если вы их не укажете, компилятор создаст их для вас . Спецификация языка C#:
При компиляции события, подобного полю-, компилятор автоматически создает хранилище для хранения делегата и создает средства доступа для события, которое добавить или удалить обработчики событий в поле делегата.
Декомпилированный исходный код с использованием dotPeek для простого public event Action Public;
выглядит следующим образом:
private Action Public;
public event Action Public
{
add
{
Action action = this.Public;
Action comparand;
do
{
comparand = action;
action = Interlocked.CompareExchange(
ref this.Public, comparand + value, comparand);
}
while (action != comparand);
}
remove
{
Action action = this.Public;
Action comparand;
do
{
comparand = action;
action = Interlocked.CompareExchange(
ref this.Public, comparand - value, comparand);
}
while (action != comparand);
}
}
Примечательно, что поле и событие используют одно и то же имя . Это привело некоторых людей к заключению, что информацию о вспомогательном поле во время отражения можно найти, просматривая поле в классе с тем же именем, что и у события. Я реализовал это следующим образом:
public static FieldInfo GetFieldInfo( this EventInfo eventInfo )
{
Contract.Requires( eventInfo != null );
return eventInfo.DeclaringType.GetField(
eventInfo.Name,
BindingFlags.DeclaredOnly | BindingFlags.Instance |
BindingFlags.Public | BindingFlags.NonPublic );
}
Это работает, но вызывает вопрос:Всегда ли гарантируется, что вспомогательное поле события, сгенерированного компилятором, будет использовать то же имя, что и событие?
Невозможно создать пользовательские методы доступа к событиям, которые обращаются к делегату с таким же именем с помощью Visual Studio. В результате появляется сообщение:«Участник с таким именем уже объявлен». Мне интересно, можете ли вы сделать вывод, что любое событие, для которого нет вспомогательного делегата с таким же именем, является событием с пользовательскими средствами доступа.