您可以使用任何语法class或struct使用以下语法来声明事件:
public class MyClass { // 声明MyClass事件 public event EventHandler MyEvent; // 引发MyEvent事件 public void RaiseEvent() { OnMyEvent(); } }
有一种用于声明事件的扩展语法,其中您可以保存事件的私有实例,并使用add和set访问器定义公共实例。语法与C#属性非常相似。在所有情况下,都应首选上面演示的语法,因为编译器会发出代码来帮助确保多个线程可以安全地向类中的事件添加和删除事件处理程序。
private void OnMyEvent() { EventName?.Invoke(this, EventArgs.Empty); }
private void OnMyEvent() { // 对EventName使用本地,因为另一个线程可以修改 // 当我们检查它是否为null以及 // 引发事件。 var eventName = EventName; // 如果eventName == null,则表示没有事件订阅者, // 因此,我们无法提出该事件。 if(eventName != null) eventName(this, EventArgs.Empty); }
请注意,事件只能通过声明类型引发。客户只能订阅/取消订阅。
对于EventName?.Invoke不支持6.0之前的C#版本,优良作法是在调用之前将事件分配给一个临时变量,如示例中所示,这样可以确保在多个线程执行相同代码的情况下线程安全。否则,NullReferenceException在多个线程使用同一对象实例的某些情况下,可能会引发。在C#6.0中,编译器发出的代码类似于C#6的代码示例中显示的代码。