问题
I need to know what handlers are subsribed to the CollectionChanged event of the ObservableCollection class. The only solution I found would be to use Delegate.GetInvocationList() on the delegate of the event. The problem is, I can't get Reflection to find the compiler generated delegate. AFAIK the delegate has the same name as the event. I used the following piece of code:
PropertyInfo notifyCollectionChangedDelegate = collection.GetType().GetProperty("CollectionChanged", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
回答1:
It is not a property, it is a field. This works:
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);
}
}
}
Don't use it.
回答2:
The whole point of events is that they encapsulate the publish/subscribe nature without exposing the currently subscribed handlers. You shouldn't need to know the subscribed handlers - if you do, you should use your own type instead of ObservableCollection
. What are you trying to do?
There's nothing to guarantee that there is a compiler-generated delegate field. It may not have been declared using a field-like event - indeed, there may not even be a single field for the backing delegate at all. (There probably is, given that there aren't many events on ObservableCollection
- but WinForms controls use a lazily allocated map to avoid having to have one field per event, when most events won't have subscribed handlers.)
来源:https://stackoverflow.com/questions/2598644/get-compiler-generated-delegate-for-an-event