Instrukcja var events = GetType().GetEvents();
wyświetla listę obiektów związanych z bieżącym typem, a nie bieżącą instancję jako taką. Tak więc obiekt EventInfo
nie zawiera informacji o bieżącej instancji, a tym samym nie wie o połączonych delegatach.
Aby uzyskać potrzebne informacje, należy uzyskać pole zaplecza obsługi zdarzeń w bieżącej instancji. Oto jak:
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;
}
}
Teraz Twój kod wywołujący może wyglądać następująco:
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();
}
}
Wyjście z powyższego jest:
MyHandler
<Execute>b__0
Jestem pewien, że można jig wokół z kod, jeśli chcesz zwrócić delegata zamiast informacji o metodzie, itp.
Mam nadzieję, że to pomoże.
Cytowanie od najwyższej głosowało odpowiedź na wcześniejsze pytanie: „Teraz załóżmy, że może próbować odnaleźć ciało«Dodaj»obsługi, dekompilować go i wyszło jak obsługi zdarzeń są poddawane zapisane i pobrać je w ten sposób ... ** ale nie rób ** Tworzysz dużo pracy, tylko po to, aby przerwać hermetyzację. ** ** przeprojektuj swój kod **, aby nie było potrzeby Zrób to." Z całego serca się zgadzam. –