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); }
这种方式绕开了触发方法,直接操作委托实例,兼容性更好,也不容易出现权限问题(只要你能访问到字段)。
总结一下
GetRaiseMethod()返回null是设计逻辑,不是Bug;- 用
GetRaiseMethod(true)可以查找非公共触发方法; - 优先考虑直接调用委托字段的方式,更可靠。
内容的提问来源于stack exchange,提问作者Fabian
相关产品推荐
相关产品推荐

