c#使用对事件成员的引用

本文关键字:成员 引用 事件 | 更新日期: 2023-09-27 18:20:06

有人知道为什么这不可能吗?如果事件只是一个MulticastDelegate实例,那么您应该能够在代码中引用它。编译器说EventA只能在-=或+=的左侧。

public delegate void MyDelegate();
public event MyDelegate EventA;
public void addHandlerToEvent(MulticastDelegate md,Delegate d){
 md+=d;
}
///
addHandlerToEvent(EventA,new MyDelegate(delegate(){}));

c#使用对事件成员的引用

事件不是多播委托,就像属性不是字段一样。

C#的event语法包装多播委托,通过为添加和删除处理程序委托提供语法糖,使生活更轻松。您的事件定义将编译为以下内容:

private MyDelegate _EventA;
public event MyDelegate EventA
{
    [MethodImpl(MethodImplOptions.Synchronized)]
    add 
    { 
        _EventA = (MyDelegate)Delegate.Combine(_EventA, value);
    }
    [MethodImpl(MethodImplOptions.Synchronized)]
    remove 
    { 
        _EventA = (MyDelegate)Delegate.Remove(_EventA, value);
    }
}

在事件上使用operator +=operator -=时,会调用扩展事件定义中的addremove方法。

这样做是为了隐藏多播委托的内部,但公开了一种实现发布/订阅事件的简单方法。能够获得底层委托(在定义它的类之外)将打破这种有意的封装。

事件是绑定一对添加/删除方法(*)的成员,每个方法都接受与事件签名相对应的委托。默认情况下,C#编译器将为每个事件自动定义一个MultiCast委托字段以及添加和删除成员,这些成员将接受传入的委托并将其添加到MulticastDelegate字段或从该字段中删除。当在定义事件的类之外执行语句myEvent += someMethod;时,它是必需的语法简写,本质上是myEvent.AddHandler(someMethod)myEvent -= someMethod;myEvent.RemoveHandler(someMethod),只是在C#中除了使用+=-=表示法之外,没有任何方法可以调用添加/删除方法。

在定义事件的类中使用+=-=表示法时,情况有点棘手,因为自动生成的事件代码定义的字段与事件同名,并且myEvent += someMethod;的行为会因C#的不同版本而异。

(*)从技术上讲,这是一个三人组,因为一个事件也包括一个"提高"方法,但在实践中,该方法基本上从未使用过。

事件由多播委托支持,是的,但它们的目的是提供观察器模式的实现,其中观察器(在本例中为委托)只能注册(+=)或未注册(-=)。如果在类本身之外可以正常访问支持委托,那么客户端代码可能会干扰在其他地方注册的不相关委托,这可能会把事情搞砸。观察其他事物正在观察所讨论的事件,这也有点偏离了观察者模式的要点。

如果需要对支持委托执行这种操作,则必须在类中执行(在类中,它被视为常规委托而不是事件)。

您还可以显式实现支持委托,并提供一个访问器来注册/注销它:

private EventHandler SomeEvent;
public event EventHandler
{
    add
    {
        SomeEvent += value;
    }
    remove
    {
        SomeEvent -= value;
    }
}

通过这种方式,如果需要,您可以直接访问委托。不过,最好提供对委托的公共访问,以便作为事件订阅/取消订阅(而不是原始委托),否则您可能会遇到委托上的数据竞赛带来的线程安全问题。