Bru*_*oLM 10 .net c# reflection
我需要从当前类中获取所有事件,并找出订阅它的方法.在这里,我得到了一些关于如何做到这一点的答案,但我不知道如何才能得到delegate我所拥有的是什么EventInfo.
var events = GetType().GetEvents();
foreach (var e in events)
{
Delegate d = e./*GetDelegateFromThisEventInfo()*/;
var methods = d.GetInvocationList();
}
Run Code Online (Sandbox Code Playgroud)
是否有可能获得代表EventInfo?怎么样?
Eni*_*ity 12
该语句var events = GetType().GetEvents();将为您EventInfo提供与当前类型关联的对象列表,而不是当前实例本身.因此,该EventInfo对象不包含有关当前实例的信息,因此它不知道有线代理.
要获取所需信息,您需要获取当前实例上事件处理程序的支持字段.这是如何做:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
所以现在你的调用代码看起来像这样:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
上面的输出是:
MyHandler
<Execute>b__0
Run Code Online (Sandbox Code Playgroud)
如果您希望返回代理而不是方法信息等,我相信您可以使用代码进行浏览.
我希望这有帮助.
与Enigmativity类似,可以找到其他类的调用列表,而不仅仅是当前类......
private void testit()
{
WithEvents we = new WithEvents();
we.myEvent += new EventHandler(we_myEvent);
we.myEvent += new EventHandler(we_myEvent2);
foreach (EventInfo ev in we.GetType().GetEvents())
{
FieldInfo fi = we.GetType().GetField(ev.Name, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy);
Delegate del = (Delegate)fi.GetValue(we);
var list = del.GetInvocationList();
foreach (var d in list)
{
Console.WriteLine("{0}", d.Method.Name);
}
}
}
void we_myEvent(object sender, EventArgs e)
{
}
void we_myEvent2(object sender, EventArgs e)
{
}
public class WithEvents
{
public event EventHandler myEvent;
}
Run Code Online (Sandbox Code Playgroud)
...只要在类中声明事件处理程序,就像我们上面看到的那样。但请考虑Control类,其中 EventHandlerList 存储在“Events”属性中,并且每个事件字段名称均以“Event”开头,后跟事件名称。然后是 Form 派生类,它们管理事件的方式似乎有所不同。值得深思。