2015-10-13 1 views
1

Так что, если я что-то вроде этого на моем объявлении события:No-оп подписчик событий в C# - нуль не проверяя избыточные

public event MyDelegate MyEvent = delegate { }; 

я прочитал, что это делает нулевые чеки избыточными, что будет нет- op абонента.

Мне любопытно, как это работает под капотом. Что именно происходит и является ли это хорошей практикой, или я должен придерживаться обычной нулевой проверки перед запуском обработчика событий?

+2

С C# 6.0 вы можете: 'MyEvent? .Invoke' – kevintjuh93

+1

« Я читал это ... »- предоставление ссылки на то, где вы читаете, может помочь тем, кто отвечает на ваш вопрос. – Rotem

ответ

4

Нулевые проверки не сложны из-за дополнительных if - они сложны, потому что они ненадежны в многопоточной среде.

Это компромисс. Если вы ожидаете, что в событии будет только 0-1 делегатов, использование (безопасная) нуль-проверка, вероятно, будет лучше. Если вы ожидаете, что несколько подписчиков, которые будут подписываться и отказаться от подписки, вам будет лучше с «null-delegate». Это означает дополнительный делегат в цепочке вызовов, но это обычно достаточно дешево для большинства случаев использования событий в .NET.

Вы не хотели бы использовать его напр. который имеет 50 различных событий, большинство из которых никогда не имеют подписчика, или ваше поведение изменяется в зависимости от того, есть ли абонент или нет.

Что касается того, что происходит под капотом, ну ... ничего. Это не делает никакой магии. Фокус в том, как += работает с событиями/делегатами.

Если у вас есть событие null и используйте +=, он просто назначает нового делегата событию. Если уже есть делегат, он создаст новый делегат, который представляет собой комбинацию предыдущего делегата и нового. Если вы используете этот нуль-делегат, это просто означает, что всегда есть делегат для объединения. Обычный код для вызова события может выглядеть примерно так:

var ev = Click; 

if (ev != null) ev(); 

Это означает, что если нет подписчика на событие, нет вызова. В случае нуль-делегат, код дополнительно упрощается до

Click(); 

Это всегда означает делегата вызов - по крайней мере, ваш нуль-делегат вызывается. Конечно, это на самом деле ничего не делает, но вы накладные вызовы делегата. Опять же, это редко бывает проблемой, но бывают случаи, когда это неприемлемо.

Смежные вопросы