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<Action>(
ref this.Public, comparand + value, comparand);
}
while (action != comparand);
}
remove
{
Action action = this.Public;
Action comparand;
do
{
comparand = action;
action = Interlocked.CompareExchange<Action>(
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.Это приводит к сообщению: «Участник с тем же именем уже объявлен». Мне интересно, можно ли сделать вывод, что любое событие, для которого недоступен вспомогательный делегат с тем же именем, является событием с пользовательскими средствами доступа.