C#委托事件为Null引发空引用异常,求原因排查与解决
问题原因与解决建议
问题原因
- 事件无订阅者直接调用:
Main方法中创建的Infoma实例,其Ievent事件未绑定任何处理方法,直接执行Ievent()会触发NullReferenceException。 Fifa类未实例化,且内部Infoma与主实例独立:Fifa构造函数中的事件订阅逻辑从未执行(因为没创建Fifa对象);即便创建Fifa,它内部的Infoma是全新实例,和Main里的Infoma毫无关联,主实例的事件依然无订阅者。
解决建议
1. 避免空引用的基础处理
调用事件前必须确保有订阅者,推荐两种写法:
- 空条件调用:用
?.Invoke()替代直接调用,无订阅者时自动跳过:public void footballers(string name, int no) { Console.WriteLine($"Player Name: {name}, Player NO: {no}"); Ievent?.Invoke(); Console.WriteLine(); } public void coach(string name, string club) { Console.WriteLine($"Coach Name : {name}, Club: {club}"); Ievent?.Invoke(); } - 初始化空委托:声明事件时绑定一个空委托,确保事件永远不为null:
public delegate void Mevent(); public event Mevent Ievent = delegate {};
2. 正确完成事件订阅
根据需求选择以下方式之一:
方式一:直接在Main中订阅
无需依赖Fifa类,直接给主实例绑定处理逻辑:
static void Main(string[] args) { Infoma infoma = new Infoma(); // 订阅事件 infoma.Ievent += () => Console.WriteLine($"This message was generated on {DateTime.Now.ToShortTimeString()}"); infoma.footballers("Messi", 10); infoma.coach("Xavi Hernández", "Barcelona"); Console.ReadLine(); }
方式二:让Fifa复用主实例的Infoma
修改Fifa构造函数,接收外部传入的Infoma实例:
class Fifa { public Fifa(Infoma infoma) { infoma.Ievent += displayevent; } public void displayevent() { Console.WriteLine("This message was generated on " + DateTime.Now.ToShortTimeString()); } }
然后在Main中创建Fifa并传入infoma:
static void Main(string[] args) { Infoma infoma = new Infoma(); Fifa fifa = new Fifa(infoma); // 完成事件订阅 infoma.footballers("Messi", 10); infoma.coach("Xavi Hernández", "Barcelona"); Console.ReadLine(); }
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

