Я недавно понял, что С# 'event' действительно есть. Честно говоря, это не совсем так. Подводя итоги: Ключевое слово event - это просто модификатор, который применяется только к делегатам.
Итак, все "волшебство" события - это действия делегата. Это. Я прочитал много документации Microsoft, но нет предложения, которое суммируется таким образом так лаконично. Чтобы продолжить мои выводы, делегат, класс и структура находятся на одном уровне. Это способы определения "объекта". Я не имею в виду "объект", как в типе, а инкапсулированную концепцию "что-то". Подобно тому, как слово "объект" используется при написании объектно-ориентированного программирования.
В любом случае, "объекты" имеют определенные модификаторы. Например, запечатанный, readonly, virtual, static и т.д. Этот список можно найти здесь. В случае с делегатом у него есть дополнительное событие, называемое событием. Событие делает так, что когда делегат объявляется частью класса, он предоставляет только методы добавить и удалить в соответствии с модификатором доступа, данным этому событию. Эти методы определяются аналогичным образом для get и set свойства. Другие операции делегата (назначение, доступ для чтения, вызов метода и т.д.) Разрешены только в классе, в котором объявлен делегат события. Другое, что мне интересно, это то, что все делегаты имеют методы Invoke, BeginInvoke и EndInvoke, но вы не можете просматривать их в Visual Studio, и я не могу найти документацию, описывающую их...
Хорошо. Итак, зная все это, , в чем преимущество использования ключевого слова event, кроме как изменить доступ к делегату? Похоже, во многих случаях мне было бы лучше просто объявить делегат без ключевого слова event. В последнее время я столкнулся с тем, что хотел создать абстрактный базовый класс, содержащий 2 события. Любой класс, полученный из этого базового класса, должен иметь возможность использовать события, подобные их собственным, подобно любому другому объекту класса, который подвергается производному классу (он же не-частный, если только производный класс не находится в другом сборка, и объект был объявлен внутренним).
В принципе, я хотел, чтобы производные классы использовали эти события как свои собственные. Единственный способ сделать это состоял в том, чтобы выставить подпорную переменную событий как защищенную, поэтому производные классы могли поднять события. Глядя на код, это казалось довольно глупым, поскольку я в основном определял делегата дважды; один раз в качестве защищенного поля, а другой - как публичное событие. Я думал,
Не лучше ли мне создать класс под названием Event, у которого есть параметр действия в конструкторе? Возвращаемое действие эквивалентно Raise, которое многие сделали в качестве метода расширения для делегатов, где он проверяет, является ли делегат нулевым, а затем вызывает делегата. Единственными общедоступными методами Event были Add и Remove для добавления делегатов и их удаления из базового делегата (+ =, - =). Классы могут иметь эти события как свойства, такие как
public Event SomethingHappened { get; private set; }
чтобы только этот класс мог повторно назначить событие. Или публичное поле для чтения было бы столь же эффективным. Параметр out, возвращаемый конструктором, сохраняется классом и вызывается, когда класс хочет поднять событие. Я знаю, что это обходное решение hokey, но оно выполнит эту работу и позволит событиям не просто передаваться в качестве аргументов, но позволять производным классам вызывать метод Raise, если базовый класс определяет его как защищенный.
TL;DR: