C#如何在独立类中监听事件?方案可行性与实践问询
C#跨类事件监听问题解答
实现MyClass2直接订阅事件的方案
当然可以让MyClass2自己完成事件订阅,不用在Main里写中转代码。直接看修改后的代码:
public class MyClass1 { public event EventHandler<DeviceEventArgs> StatusChange; protected virtual void OnStatusChange(DeviceEventArgs e) { StatusChange?.Invoke(this, e); } // 加个触发事件的方法,方便测试 public void SimulateStatusChange(string newStatus) { OnStatusChange(new DeviceEventArgs { Status = newStatus }); } } public class MyClass2 { private readonly MyClass1 _myClass1; // 通过构造函数传入MyClass1实例,内部直接订阅事件 public MyClass2(MyClass1 myClass1) { _myClass1 = myClass1; _myClass1.StatusChange += OnStatusChanged; } // 事件处理逻辑,直接调用状态更新方法 private void OnStatusChanged(object sender, DeviceEventArgs e) { UpdateStatus(e.Status); } public void UpdateStatus(string newStatus) { // 这里写你的状态更新逻辑 Console.WriteLine($"MyClass2状态更新为:{newStatus}"); } // 可选:如果需要取消订阅,加个方法 public void Unsubscribe() { _myClass1.StatusChange -= OnStatusChanged; } } // Main里的调用就很简洁了 void Main() { MyClass1 class1 = new MyClass1(); // 创建MyClass2时传入class1,自动完成订阅 MyClass2 class2 = new MyClass2(class1); // 模拟状态变化,测试效果 class1.SimulateStatusChange("设备在线"); } // 自定义事件参数类 public class DeviceEventArgs : EventArgs { public string Status { get; set; } }
可行性与最佳实践分析
1. 方案完全可行
上面的代码已经实现了你要的效果:MyClass2内部直接监听MyClass1的事件,Main里不用写中转的订阅代码。
2. 两种方式的对比
| 方式 | 优点 | 缺点 |
|---|---|---|
| MyClass2直接订阅 | 逻辑封装在MyClass2内部,Main代码干净 | MyClass2和MyClass1强依赖,易引发内存泄漏(忘记取消订阅时) |
| Main中转订阅 | 两个类完全解耦,灵活度高 | Main需要处理类之间的事件转发,代码稍繁琐 |
3. 怎么选?
- 如果MyClass2的核心工作就是盯着MyClass1的状态变化,那直接订阅的方式更合理,符合单一职责原则。
- 如果后续可能有多个类要监听MyClass1,或者MyClass2需要切换监听不同的类,那维持Main中转的方式更灵活,解耦性更好。
- 新手阶段先把基础的事件订阅逻辑搞明白,复杂的解耦方案(比如事件总线)可以后面再逐步学习。
4. 注意事项
如果用直接订阅的方式,记得在MyClass2不再使用时取消订阅(比如上面的Unsubscribe方法),不然MyClass1的实例会一直持有MyClass2的引用,导致内存无法回收——这点在桌面应用或长期运行的服务端程序里尤其要注意。
总结一下:两种方案都能用,核心看你项目里类的绑定关系和需求。直接订阅适合职责绑定紧密的场景,中转方式适合需要灵活解耦的场景。
内容的提问来源于stack exchange,提问作者Steven Amos
相关产品推荐
相关产品推荐

