我需要知道哪些处理程序被包含在ObservableCollection类的CollectionChanged事件中。我找到的唯一解决方案是在事件的委托上使用Delegate.GetInvocationList()。问题是,我无法得到Reflection来查找编译器生成的委托。 AFAIK代表与事件同名。我使用了以下代码:
PropertyInfo notifyCollectionChangedDelegate = collection.GetType().GetProperty("CollectionChanged", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
答案 0 :(得分:4)
它不是属性,而是属性。这有效:
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);
}
}
}
不要使用它。
答案 1 :(得分:1)
事件的重点在于它们封装了发布/订阅性质,而没有公开当前订阅的处理程序。您不应该知道订阅的处理程序 - 如果这样做,您应该使用自己的类型而不是ObservableCollection
。你想做什么?
没有什么可以保证是编译器生成的委托字段。它可能没有使用类似字段的事件声明 - 实际上,甚至可能根本没有单独的字段用于支持委托。 (可能有,假设ObservableCollection
上没有很多事件 - 但WinForms控件使用一个懒惰分配的映射来避免每个事件都有一个字段,而大多数事件都没有订阅处理程序。)< / p>