我有:
event EventHandler MyEvent;
MyEvent += new EventHandler(someHandler);
if(this.GetEvent("MyEvent").GetRaiseMethod() == null)
{
// Always true...
}
但为什么呢?添加处理程序后,不应将GetRaiseMethod()
设置为someHandler
的{{1}}?
答案 0 :(得分:10)
这是C#的一个怪癖,它不支持提升访问器。只添加和删除。其他.NET语言,如VB.NET,F#和C ++ / CLI确实支持它们,它在CLI规范中定义得很好,在那个名称中名为“fire”。
很难解释为什么C#团队跳过它,我从未见过它的好解释。纯粹的推测:它可能与他们希望避免为没有人订阅的事件构建事件参数的成本有关。在GUI框架中很常见。这是一个小小的损失,C#程序员编写标准的引发事件模式以及在忘记检查NRE时诊断NRE时,必须丢失数十万小时。 C#v6中的elvis运算符(?.
)最终变得更容易。
Anyhoo,如果你反映用C#编写的代码,你将永远不会从GetRaiseMethod()得到任何东西。但是,当它用VB.NET,F#或C ++ / CLI编写时,你总是得到一个非null。如果你需要用反射引发事件,你将不得不挖出支持委托变量,这可能很痛苦。如果使用了自动生成的添加/删除访问器,则后备变量与事件具有相同的名称,您可以使用Type.GetField(),使用BindingFlags.NonPublic |来检索它。 BindingFlags.Instance。
答案 1 :(得分:3)
除了“add”和“remove”之外,raise方法是CLI规范中提到的访问器之一 - 但是,大多数事件都不实现此功能。特别是,c#特别不支持这个 - 所以是的:它将始终返回null。