La declaración var events = GetType().GetEvents();
le ofrece una lista de los objetos EventInfo
asociados con el tipo actual, no la instancia actual per se. Por lo tanto, el objeto EventInfo
no contiene información sobre la instancia actual y, por lo tanto, no conoce a los delegados cableados.
Para obtener la información que desea, necesita obtener el campo de respaldo para el controlador de eventos en su instancia actual. Así es como:
public class MyClass
{
public event EventHandler MyEvent;
public IEnumerable<MethodInfo> GetSubscribedMethods()
{
Func<EventInfo, FieldInfo> ei2fi =
ei => this.GetType().GetField(ei.Name,
BindingFlags.NonPublic |
BindingFlags.Instance |
BindingFlags.GetField);
return from eventInfo in this.GetType().GetEvents()
let eventFieldInfo = ei2fi(eventInfo)
let eventFieldValue =
(System.Delegate)eventFieldInfo.GetValue(this)
from subscribedDelegate in eventFieldValue.GetInvocationList()
select subscribedDelegate.Method;
}
}
Así que ahora su código de llamada puede tener este aspecto:
class GetSubscribedMethodsExample
{
public static void Execute()
{
var instance = new MyClass();
instance.MyEvent += new EventHandler(MyHandler);
instance.MyEvent += (s, e) => { };
instance.GetSubscribedMethods()
.Run(h => Console.WriteLine(h.Name));
}
static void MyHandler(object sender, EventArgs e)
{
throw new NotImplementedException();
}
}
El resultado de lo anterior es:
MyHandler
<Execute>b__0
Estoy seguro de que puede jig alrededor con el código si desea devolver el delegado en lugar de la información del método, etc.
Espero que esto ayude.
Citando de la respuesta de la más alta votación en su pregunta anterior: "Ahora supongo que se podría tratar de encontrar el cuerpo del '' manejador añadir, descompilarlo y averiguar cómo están siendo los controladores de eventos almacenados, y tráigalos de esa manera ... ** pero no lo hagas **. Estás creando mucho trabajo, solo para romper la encapsulación. Solo ** rediseña tu código ** para que no necesites hacer esto." De todo corazón estoy de acuerdo. –