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#的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 -=
时,会调用扩展事件定义中的add
和remove
方法。
这样做是为了隐藏多播委托的内部,但公开了一种实现发布/订阅事件的简单方法。能够获得底层委托(在定义它的类之外)将打破这种有意的封装。
事件是绑定一对添加/删除方法(*)的成员,每个方法都接受与事件签名相对应的委托。默认情况下,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;
}
}
通过这种方式,如果需要,您可以直接访问委托。不过,最好提供对委托的公共访问,以便作为事件订阅/取消订阅(而不是原始委托),否则您可能会遇到委托上的数据竞赛带来的线程安全问题。