There are times when you have to do something fairly simple that turns out to be quite complicated. Maybe you have to reflect on your code and pull something out - sounds easy. Getting a list of methods or attributes attached to property is straightforward and easy to wrap your mind around. Things can get a little bit more complicated while using reflections to manipulate events. You can easily get their list (type.GetEvents()), add another handler (EventInfo.AddEventHandler()) or remove a handler (EventInfo.RemoveEventHandler()). To get a list of attached delegates you have to do something more.

Our event is more like a syntactic sugar, and under hood is a little bit more complex (more about it you can find on this page in a chapter “A shortcut: field-like events”). In my example I’m looking for all events in an particular class and for each of them I’m adding a simple delegate, but only if this event is empty (has no handlers).

TestEventClass instance = new TestEventClass();
foreach (var e in typeof(TestEventClass).GetEvents())
{
    FieldInfo fi = instance.GetType().GetField(e.Name, BindingFlags.NonPublic | BindingFlags.Instance);
    object value = fi.GetValue(instance);
    if (value == null)
    {
        e.AddEventHandler(instance, (TestDelegate)(delegate() {DoSmthg();}));
    }
}

First step is to look for all events in a class. After that we need to get instance field with a name of particular event (notice that this field is private). Then we just need to take a value of it – it’s our System.MulticastDelegate. This class has a GetInvocationList() method that is returning a Delegate[] array.

 

Technorati Tagi: ,