EventInfo.GetRaiseMethod()始终为空 [英] EventInfo.GetRaiseMethod() always null

查看:286
本文介绍了EventInfo.GetRaiseMethod()始终为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有:

event EventHandler MyEvent;

MyEvent += new EventHandler(someHandler);

if(this.GetEvent("MyEvent").GetRaiseMethod() == null)
{
  // Always true...
}

但为什么?添加一个处理程序后,不要将 GetRaiseMethod()设置为 someHandler MethodInfo

But why? After I add a handler, shouldn't GetRaiseMethod() be set to someHandler's MethodInfo?

推荐答案

这是一个C#的怪癖,它不支持提升访问者。仅添加和删除。其他.NET语言(如VB.NET,F#和C ++ / CLI)支持它们,并在CLI规范中定义了一个名为fire的定义。

This is a quirk of C#, it doesn't support raise accessors. Only add and remove. Other .NET languages like VB.NET, F# and C++/CLI do support them and it is well defined in the CLI spec, named "fire" in that one.

很难解释为什么C#团队跳过它,我从来没有看到很好的解释。纯粹的猜测:它可能与他们希望避免为没有订阅的事件构建事件参数的成本有关。在GUI框架中很常见。这是一个损失,C#程序员编写标准提升事件模式以及在忘记检查null时诊断NRE时必须丢失数十万小时。 C#v6中的elvis运算符(?。)终于让它变得更容易了。

It is hard to explain why the C# team skipped it, I've never seen a good explanation for it. Pure speculation: it may have had something to do with their desire to avoid the cost of constructing the event arguments for an event that nobody subscribed. Very common in the GUI frameworks. It is a bit of a loss, hundreds of thousands of hours must have been lost by C# programmers writing the standard raise event pattern as well as diagnosing NREs when they forgot to check for null. The elvis operator (?.) in C# v6 finally made it easier.

Anyhoo,你永远不会得到如果您反映使用C#编写的代码,则从GetRaiseMethod()返回null。然而,当使用VB.NET,F#或C ++ / CLI编写时,您总是会获得非空值。如果您需要通过反射来提升事件,那么您将不得不挖掘支持委托变量,这可能会很痛苦。如果使用自动生成的添加/删除访问器,则备份变量与事件具有相同的名称,您可以使用Type.GetField()检索它,使用BindingFlags.NonPublic | BindingFlags.Instance。

Anyhoo, you'll never get anything but null from GetRaiseMethod() if you reflect code written in C#. You'll however always get a non-null when it was written in VB.NET, F# or C++/CLI. You'll have to dig out the backing delegate variable if you need to raise the event with reflection, that can be painful. If the auto-generated add/remove accessors were used then the backing variable has the same name as the event and you can retrieve it with Type.GetField(), using BindingFlags.NonPublic | BindingFlags.Instance.

这篇关于EventInfo.GetRaiseMethod()始终为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆