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