You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#反射:如何调用EventInfo?为何GetRaiseMethod始终返回null?

解决EventInfo.GetRaiseMethod()返回null的问题

首先可以明确:这不是C#的Bug,而是GetRaiseMethod()的设计行为导致的,咱们一步步来拆解问题和解决方案。

为什么会返回null?

  • 当你声明常规事件(比如public event PropertyChangedEventHandler PropertyChanged;)时,C#编译器会自动生成私有的add、remove方法,以及一个私有的触发方法(如果你没有显式编写的话)。而GetRaiseMethod()的默认行为是只查找公共的触发方法,所以找不到这些私有/受保护的方法,自然返回null。
  • 如果事件是显式实现的(比如实现接口中的事件),或者你自己编写的触发方法是非公共的,GetRaiseMethod()同样会返回null——因为它的默认重载参数是nonPublic: false,不包含非公共方法的查找。

直接解决:获取非公共触发方法

你可以调用GetRaiseMethod(true),让它包含非公共方法的查找:

MethodInfo eventRaiseMethod = eventInfos[i].GetRaiseMethod(true);
if (eventRaiseMethod != null)
{
    eventRaiseMethod.Invoke(this, arrayOfPropertyChangedArgs);
}

不过要注意:就算找到了这个方法,调用时可能会遇到权限问题(毕竟它是私有的),你需要确保代码有足够的反射权限才能执行成功。

更可靠的替代方案:直接调用事件委托

很多时候,直接获取事件的底层委托字段并调用它会更稳定——不管触发方法是否存在,只要委托有订阅者就能正常执行:

// 获取事件对应的底层委托字段,注意编译器生成的字段名通常和事件名一致,部分版本可能是"_事件名"
FieldInfo eventField = eventInfos[i].DeclaringType.GetField(
    eventInfos[i].Name, 
    BindingFlags.Instance | BindingFlags.NonPublic
);
if (eventField != null)
{
    Delegate eventDelegate = eventField.GetValue(this) as Delegate;
    eventDelegate?.DynamicInvoke(arrayOfPropertyChangedArgs);
}

这种方式绕开了触发方法,直接操作委托实例,兼容性更好,也不容易出现权限问题(只要你能访问到字段)。

总结一下

  1. GetRaiseMethod()返回null是设计逻辑,不是Bug;
  2. 用GetRaiseMethod(true)可以查找非公共触发方法;
  3. 优先考虑直接调用委托字段的方式,更可靠。

内容的提问来源于stack exchange,提问作者Fabian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:47:05