c# - 如何从 EventInfo 中获取委托(delegate)对象?

标签 c# .net reflection

我需要从当前类中获取所有事件,并找出订阅它的方法。 Here I got some answers on how to do that ,但是当我只有 EventInfo 时,我不知道如何获得 delegate

var events = GetType().GetEvents();

foreach (var e in events)
{
    Delegate d = e./*GetDelegateFromThisEventInfo()*/;
    var methods = d.GetInvocationList();
}

是否可以通过 EventInfo 获得委托(delegate)?怎么办?

最佳答案

语句 var events = GetType().GetEvents(); 为您提供与当前类型关联的 EventInfo 对象列表,而不是当前实例本身。所以 EventInfo 对象不包含有关当前实例的信息,因此它不知道连接的委托(delegate)。

要获取所需信息,您需要获取当前实例上事件处理程序的支持字段。方法如下:

public class MyClass
{
    public event EventHandler MyEvent;

    public IEnumerable<MethodInfo> GetSubscribedMethods()
    {
        Func<EventInfo, FieldInfo> ei2fi =
            ei => this.GetType().GetField(ei.Name,
                BindingFlags.NonPublic |
                BindingFlags.Instance |
                BindingFlags.GetField);

        return from eventInfo in this.GetType().GetEvents()
               let eventFieldInfo = ei2fi(eventInfo)
               let eventFieldValue =
                   (System.Delegate)eventFieldInfo.GetValue(this)
               from subscribedDelegate in eventFieldValue.GetInvocationList()
               select subscribedDelegate.Method;
    }
}

所以现在您的调用代码可以如下所示:

class GetSubscribedMethodsExample
{
    public static void Execute()
    {
        var instance = new MyClass();
        instance.MyEvent += new EventHandler(MyHandler);
        instance.MyEvent += (s, e) => { };

        instance.GetSubscribedMethods()
            .Run(h => Console.WriteLine(h.Name));
    }

    static void MyHandler(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }
}

上面的输出是:

MyHandler
<Execute>b__0

如果您希望返回委托(delegate)而不是方法信息等,我相信您可以修改代码。

希望对您有所帮助。

关于c# - 如何从 EventInfo 中获取委托(delegate)对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3783267/

相关文章:

c# - 在 ASP.NET MVC 4 ActionFilterAttribute 中引发异常的正确方法

c# - 分布式深度优先搜索

c# - 在 .net 异常中如何获取带有参数值的堆栈跟踪

c# - .NET 安装包有时无法完全删除以前的版本

c# - 限制什么类型可以通过接口(interface)传递给方法

scala - 从类型中获取类型标签?

c# - 关闭后处理表单

C# 如何取消订阅给定事件的所有事件处理程序?

c# - 为什么 BackgroundWorker 在对委托(delegate)调用 BeginInvoke 时不需要调用 EndInvoke?

scala - Int 类型与 scala.Int 类型