是否可以使用Reflection is C#来触发事件?说我有这样的情况:
public delegate void SomeEventHandler(object sender, BenArgs e);
class EventHub
{
public event SomeEventHandler SOME_EVENT;
public void fireEvent(String eventName)
{
SomeEventHandler evt = (SomeEventHandler) Delegate.CreateDelegate(typeof(SomeEventHandler), this, eventName);
evt.Invoke(null, null);
}
}
我打电话的意思
EventHub.fireEvent("SOME_EVENT")
然后它会使事件集线器触发SOME_EVENT?我试过这个,只是出现例外情况。
这主要是我的一个好奇心,我知道在这种情况下,我可以轻松地在没有反射的情况下发射事件。
答案 0 :(得分:3)
假设您当前的情况,即:
(this, EventArgs.Empty)
是传递给委托的有效参数。您可以执行以下操作(需要更多参数验证):
public void fireEvent(String eventName)
{
// Get a reference to the backing field
var del = (Delegate)typeof(EventHub)
.GetField(eventName, BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(this);
// Invoke the delegate, it's invocation-list will contain the listeners
if(del != null)
del.DynamicInvoke(this, EventArgs.Empty);
}
用法:
var eHub = new EventHub();
eHub.SOME_EVENT += delegate { Console.WriteLine("SOME_EVENT fired.."); };
eHub.fireEvent("SOME_EVENT");
现在,如果您愿意,可以使用object
上的扩展方法来概括这个想法,但所有这些都是一个非常糟糕的主意。在一般情况下,此问题无法解决,因为无法知道事件是如何“实施”的。 add
和remove
方法中可能存在任意代码,“触发”事件的逻辑也可以是任何内容。甚至可能没有用于存储侦听器的支持多播delgate字段。
在任何情况下,尝试告诉对象发射事件几乎总是一个主要设计缺陷的标志,IMO。如果仍然确实想要这个,那么在你的班级中声明这样的方法会好得多:
public void RaiseXXXEvent() { ... }