【问题标题】:Get compiler generated delegate for an event获取编译器生成的事件委托
【发布时间】:2010-04-08 09:02:48
【问题描述】:

我需要知道哪些处理程序订阅了 ObservableCollection 类的 CollectionChanged 事件。我找到的唯一解决方案是在事件的委托上使用 Delegate.GetInvocationList() 。问题是,我无法让反射找到编译器生成的委托。 AFAIK 委托与事件同名。我使用了以下代码:

PropertyInfo notifyCollectionChangedDelegate = collection.GetType().GetProperty("CollectionChanged", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);

【问题讨论】:

    标签: c# reflection compiler-construction delegates observablecollection


    【解决方案1】:

    它不是一个属性,它是一个字段。这有效:

    using System;
    using System.Collections.ObjectModel;  // Add reference to WindowsBase
    using System.Collections.Specialized;
    using System.Reflection;
    
    namespace ConsoleApplication1 {
      class Program {
        static void Main(string[] args) {
          var coll = new ObservableCollection<int>();
          coll.CollectionChanged += coll_CollectionChanged;
          coll.Add(42);
          FieldInfo fi = coll.GetType().GetField("CollectionChanged", BindingFlags.NonPublic | BindingFlags.Instance);
          NotifyCollectionChangedEventHandler handler = fi.GetValue(coll) as NotifyCollectionChangedEventHandler;
          handler.Invoke(coll, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
    
        static void coll_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
          Console.WriteLine("Changed {0}", e.Action);
        }
      }
    }
    

    不要使用它。

    【讨论】:

      【解决方案2】:

      事件的全部意义在于它们封装了发布/订阅性质而不暴露当前订阅的处理程序。你不需要知道订阅的处理程序——如果你知道,你应该使用你自己的类型而不是ObservableCollection。你想做什么?

      没有什么可以保证存在编译器生成的委托字段。它可能没有使用类似字段的事件声明 - 实际上,支持委托甚至可能根本没有单个字段。 (可能有,因为 ObservableCollection 上的事件并不多 - 但 WinForms 控件使用延迟分配的映射来避免每个事件必须有一个字段,而大多数事件都没有订阅的处理程序。)

      【讨论】:

      • 我的目标是管理对 NotifyCollectionChanged 事件的订阅,但我只需要订阅一次。我不想为每个 ObservableCollection 管理一个布尔字段来保存此信息。 (订阅发生在多次调用的地方。)所以最简单的方法是检查我是否已经订阅了处理程序。要么我在这里遗漏了一些非常简单的东西,要么.net 框架事件确实需要公开一个返回订阅处理程序的属性。 (顺便说一句,我之前发现了一篇描述 WinForms 委托系统的文章,但我需要这个。)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-01
      • 2012-07-09
      相关资源
      最近更新 更多