[英]C# Reflection: How to invoke a EventInfo?
如何在EventInfo后面调用事件? 我尝试了以下操作,但“ GetRaiseMethod”始终为“ null”:
MethodInfo eventRaiseMethod = eventInfos[i].GetRaiseMethod();
eventRaiseMethod.Invoke(this, arrayOfPropertyChangedArgs);
谢谢 :)
更新:似乎多数民众赞成在C#中的错误???
仅在实现事件而不覆盖add \\ remove的情况下,“调用”事件才有意义:
class Test {
public event Action TestEvent;
void Invoke() {
// fine
TestEvent();
}
}
但是,使用自定义add \\ remove调用事件的概念没有意义:
class Test {
public event Action TestEvent
{
add { }
remove { }
}
void Invoke() {
// does not compile, invoke what?
TestEvent();
}
}
因此,对于具有“默认”实现的事件,事件调用只是调用基础编译器生成的委托字段的语法糖。
知道这一点,您可以搜索该字段并调用它。 这是一个与事件同名的私有字段:
class Program {
static void Main(string[] args) {
var test = new Test();
test.TestEvent += OnTest;
var backingField = typeof(Test).GetField("TestEvent", BindingFlags.Instance | BindingFlags.NonPublic);
var delegateInstance = (Action)backingField.GetValue(test);
delegateInstance();
}
private static void OnTest() {
Console.WriteLine("Event invoked");
}
}
class Test {
public event Action TestEvent;
}
也就是说,某些.NET语言的编译器可能会为自动实现的事件生成“提高”方法。 如果是这种情况, GetRaiseMethod
将返回该方法。 C#编译器不会那样做。 因此,如果您想安全GetRaiseEvent
,则可以先调用GetRaiseEvent
,如果它返回null,则退回到现场方法。 当然,您应该期望该字段也为空(因为如上所述并非所有事件都可以调用-不需要该字段存在)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.