views:

102

answers:

3

Hello

Assuming I have an event subscription such as

_vm.PropertyChanged += OnViewModelAmountChanged;

How can I see that method name by reflection the way you can see it in the debugger? I got as far as the line below before I decided I might be in the Twilight Zone

?vm.GetType().GetEvent("PropertyChanged").EventHandlerType.GetMethod("GetInvocationList")

Can someone get me back to Earth? Can this also be done via expressions?

Cheers,
Berryl

+1  A: 

A .Net event is simply a pair of methods named add_Whatever and remove_Whatever. They are not guaranteed to be backed by field.

When you write event EventHandler Whatever; in C#, it will automatically generate a private field with the same name as the event, and add and remove accessors that set the field.

You can inspect these at runtime by using Reflection to get the value of the private field, then callings the public GetInvocationList method of the Delegate class (without reflection).

For non-simple events, including all WinForms events, this approach will not work.

SLaks
Very good answer. I was going to suggest looking for the compiler-generated field but I had totally forgotten about the "event dictionary" pattern used by Windows Forms controls. I wonder why EventInfo has a GetRaiseMethod? It would seem like it could not possibly provide one.
Josh Einstein
@Josh: http://blogs.msdn.com/thottams/archive/2006/03/18/554222.aspx
SLaks
Can you scratch out some code for the reflection bit? I think you're saying I should be able to find a field using "vm.GetType().GetField("PropertyChanged", System.Reflection.BindingFlags.NonPublic)" but that returns null
Berryl
I see it now. I had to go to the base type first. Thanks!
Berryl
+1  A: 

One thing to remember is that an event may customize the add/remove methods for an event. In this case, the containing class could put the delegate into any data structure (a List, e.g.) or even ignore it (though this would be unlikely). The important point is that the delegate could be stored any way the class likes. It would be like trying to find the field that is used to store a Property's value.

dpp
A: 

If you are within the class that declares the event, you can do something like that :

foreach(Delegate d in MyEvent.GetInvocationList())
{
    Console.WriteLine(d.Method.Name);
}
Thomas Levesque
I'm tring to get it from inside a unit test
Berryl