Это интересный. Джеффри Рихтер много говорил об этом в CLR через C # .
С пустой проверкой, как показано ниже: -
var handler = MyEvent;
if (handler != null)
{
handler.Invoke(null, e);
}
Компилятор JIT потенциально может полностью оптимизировать переменную handler
. Тем не менее, команда CLR знает, что многие разработчики используют этот шаблон для генерации событий и встроили эту информацию в JIT-компилятор. Вполне вероятно, что это останется в силе во всех будущих версиях CLR, потому что изменение поведения может нарушить слишком много существующих приложений.
Нет причины, по которой вы не можете написать метод расширения, чтобы выполнить эту работу за вас (это именно то, что я сделал). Обратите внимание, что сам метод может быть встроен в JIT (но временная переменная все равно не будет оптимизирована).
Если вы планируете использовать ваше приложение против другой среды выполнения, например, Mono (который, я подозреваю, в любом случае отражает поведение CLR в этом случае) или некоторая другая экзотическая среда выполнения, которая может появиться, затем вы можете защитить свой код от возможности JIT-вставки, добавив [MethodImplAttribute(MethodImplOptions.NoInlining)]
к вашему методу расширения.
Если вы решите не использовать метод расширения, другой способ защиты от JIT-оптимизации (который рекомендует Джеффри Рихтер) - присвоить значение временной переменной способом, который не может быть оптимизирован компилятором JIT, например
var handler = Interlocked.CompareExchange(ref MyEvent, null, null);