Выбор на самом деле не будет между делегатом и событием - это совершенно разные вещи. Однако вы можете предоставить открытое свойство или открытое поле с типом делегата. Я полагаю, это то, что вы на самом деле имеете в виду.
Предположим, Button.Click
было открытым полем или свойством вместо события. Затем один фрагмент кода может подписаться на событие, а другой может написать:
// Invalid with events, valid with properties
button.Click = null;
, таким образом уничтожая оригинальный обработчик событий. Аналогично, другой код также может вызывать обработчики событий:
// Invalid with events, valid with properties
button.Click(this, EventArgs.Empty);
даже если кнопка не была нажата. Это явно нарушение инкапсуляции. Единственная причина выставить Click
другому коду - позволить им регистрировать интерес к нажатию кнопок и регистрировать незаинтересованность позже - и это именно те возможности, которые предоставляют события.
Думайте о событиях как о синтаксическом сахаре вокруг двух методов. Например, если бы у нас не было событий, то Button
, вероятно, будет иметь:
public void AddClickHandler(EventHandler handler)
public void RemoveClickHandler(EventHandler handler)
Нарушение инкапсуляции проходит, но вы теряете некоторые удобства - и каждый должен написать свои собственные методы, подобные этому. События упрощают эту схему, в основном.