已通过空检查仍抛NullReferenceException?值类型EventHandler异常疑问
异常原因分析与解决方案
核心问题:委托类型签名不匹配
- 目标事件
MyEvent是EventHandler<bool>类型,签名为void(object sender, bool e),第二个参数是值类型bool。 - 但传入
AddEventHandler的是EventHandler类型委托,签名为void(object sender, EventArgs e),第二个参数是引用类型EventArgs。
为什么会抛出NullReferenceException?
通过反射构造EventHandler<bool>实例并绑定到EventHandler方法后,事件触发时CLR会按EventHandler<bool>的签名传递参数:把值类型true传给方法的第二个参数。但你的处理方法期望的是EventArgs引用类型,值类型无法直接转换为不兼容的引用类型,导致CLR无法正确构造参数,最终传递了无效引用(表现为null),触发空引用异常。
本质上这种跨类型委托绑定违反CLR规范,属于非法的委托类型转换,栈布局不匹配才是根本原因,空引用异常只是错误的表现形式之一。
修复方案
修改AddEventHandler方法,适配任意委托类型,保证签名与事件委托类型匹配:
public static void AddEventHandler(EventInfo eventInfo, object client, Delegate handler) { Delegate convertedHandler = Delegate.CreateDelegate(eventInfo.EventHandlerType, handler.Target, handler.Method); eventInfo.AddEventHandler(client, convertedHandler); }
调用时传入正确类型的委托:
AddEventHandler(eventInfo, null, new EventHandler<bool>((s, e) => { Console.WriteLine(e.ToString()); // e是bool值,无需空检查 }));
内容的提问来源于stack exchange,提问作者KBar
相关产品推荐
相关产品推荐

