创建EventHandler遇错误:'Object'未定义ListCountLastH等字段求助
问题分析与解决方案
让我一步步帮你梳理和解决这些问题:
1. 变量名笔误导致的未初始化问题
首先看你Divergence5min类的OnStateChange方法,这里存在明显的变量名写错问题:
protected override void OnStateChange() { ListCountH = new List<int>(); // 变量名与声明的ListCountLastH不匹配! LastHSwDMI = new List<double>(); }
你声明的列表是ListCountLastH,但初始化的是不存在的ListCountH,这会导致ListCountLastH始终为null,后续调用Add方法时必然触发空引用异常。先把这个笔误修正:
protected override void OnStateChange() { ListCountLastH = new List<int>(); // 修正为正确的变量名 LastHSwDMI = new List<double>(); }
2. 嵌套类访问外部类成员的权限与引用问题
在C#中,嵌套类不会隐式持有外部类的实例引用,所以你直接用base.ListCountLastH或者直接访问外部类成员会报错。另外你后来让Incrementer继承DivergenceList5m,但你的列表成员是在Divergence5min里定义的,这属于类混淆,完全没必要。
正确的做法是:让Incrementer持有外部Divergence5min类的实例引用,通过这个实例访问列表成员。修改代码如下:
public class Divergence5min : Strategy { public int listCountLH; public List<int> ListCountLastH; public List<double> LastHSwDMI; protected override void OnStateChange() { ListCountLastH = new List<int>(); // 修正笔误 LastHSwDMI = new List<double>(); } // 修改嵌套类Incrementer,添加外部类实例的引用 public class Incrementer { private readonly Divergence5min _outerInstance; public event EventHandler ItemAdded; // 构造函数传入外部类实例 public Incrementer(Divergence5min outerInstance) { _outerInstance = outerInstance; } public void AddItem() { // 通过外部类实例访问成员 _outerInstance.ListCountLastH.Add(_outerInstance.listCountLH); ItemAdded?.Invoke(this, EventArgs.Empty); // 更安全的空检查触发方式 } } // 其他原有代码... }
3. 解决"需要对象引用"的错误
你之前遇到的"An object reference is required for the non-static field..."错误,是因为你试图直接访问类的非静态成员(比如DivergenceList5m.ListCountLastH),而不是通过该类的实例。在上面的修改中,我们通过传入外部类的实例,所有成员访问都通过具体的实例_outerInstance进行,已经解决了这个问题。
4. 订阅者类的调用修正
当你创建Incrementer实例时,需要传入Divergence5min的实例,比如在OnBarUpdate逻辑中调用:
protected override void OnBarUpdate() { // 当你的触发条件满足时,创建Incrementer并调用AddItem var incrementer = new Incrementer(this); // 传入当前Divergence5min实例 incrementer.ItemAdded += (s, e) => { /* 这里处理事件逻辑 */ }; incrementer.AddItem(); }
额外优化建议
- 尽量避免将字段设为
public,可以用private或protected,然后提供公共方法来操作列表(比如AddToListCountLastH(int value)),这样能更好地封装逻辑,避免外部直接修改列表导致的意外错误。 - 事件触发时使用
ItemAdded?.Invoke(this, EventArgs.Empty)替代旧的空检查方式,语法更简洁且安全。
内容的提问来源于stack exchange,提问作者Sorin Pascu
相关产品推荐
相关产品推荐

