List<object> targets = MyEvent.GetInvocationList().Select(d => d.Target).ToList();
Doing this via reflection will be somewhat obfuscated, if even possible, unfortunately, because this syntax:
public event EventHandler MyEvent;
...
MyEvent(this, EventArgs.Empty);
Is syntactic sugar. What this actually does is:
private EventHandler compilerGeneratedName;
public event EventHandler MyEvent
{
add { compilerGeneratedName += value; }
remove { compilerGeneratedName -= value; }
}
...
compilerGeneratedName(this, EventArgs.Empty);
In other words, events have always had the declarative shorthand that properties only recently received. As a result, in order to get at the invocation list you'll have to inspect the private variable, which is named by the compiler (unless, of course, you use the longhand syntax yourself and know the name of the instance variable).
There is no direct way to associate an externally exposed event
construct with a backing handler any more than there is a direct way to tie a property
to a backing variable: namely because there isn't necessarily a one-to-one relationship. Very likely there is, but as a rule it doesn't have to be that way.
You can try using reflection to inspect the private variables that are of the proper EventHandler<>
type on the type that declares the event (note that you'll have to do it at the specific type that declares the event, not on a subclass) and see if you can determine some sort of correlation with the names, but this will be an unreliable solution at best.