C#如何实现跨类监听Main类string属性变更并触发对应事件
实现方案
你这个需求属于典型的**发布-订阅(观察者)**模式场景,C#有两种成熟的实现方式,你可以根据自己的业务场景选择:
方案1:使用内置INotifyPropertyChanged接口(通用推荐)
这个是.NET生态通用的属性变化通知标准,兼容WPF、MAUI等大部分UI框架,通用性最强:
using System.ComponentModel; using System.Runtime.CompilerServices; public class MainClass : INotifyPropertyChanged { private string _employee; public string Employee { get => _employee; set { // 仅当值真实变化时才触发通知,避免无效调用 if (_employee != value) { _employee = value; OnPropertyChanged(); } } } // 内置的属性变化事件 public event PropertyChangedEventHandler PropertyChanged; // 触发通知的方法,CallerMemberName特性会自动获取属性名,无需手动传参 protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
订阅通知示例
你可以在需要监听的地方直接绑定事件,也可以把订阅逻辑封装到监听类内部:
// 初始化实例 MainClass mainInstance = new MainClass(); SecondClass second = new SecondClass(); ThirdClass third = new ThirdClass(); // 绑定订阅,只处理Employee属性的变化 mainInstance.PropertyChanged += (sender, e) => { if (e.PropertyName == nameof(MainClass.Employee)) { second.StringChangedEvent(); third.StringChangedEvent(); } };
如果要把订阅逻辑封装到监听类里,写法如下:
public class SecondClass { // 注册监听 public void Subscribe(MainClass main) { main.PropertyChanged += OnMainPropertyChanged; } private void OnMainPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(MainClass.Employee)) { StringChangedEvent(); } } public void StringChangedEvent() { // 你的业务逻辑 } // 不需要监听时必须取消订阅,避免内存泄漏 public void Unsubscribe(MainClass main) { main.PropertyChanged -= OnMainPropertyChanged; } }
方案2:自定义专属事件(更灵活)
如果你只有Employee这一个属性需要通知,可以自定义专属事件,还可以直接传递新旧值,逻辑更直观:
public class MainClass { private string _employee; public string Employee { get => _employee; set { if (_employee != value) { var oldVal = _employee; _employee = value; // 触发自定义事件,传递新旧值 EmployeeChanged?.Invoke(this, new EmployeeChangeEventArgs(oldVal, value)); } } } // 自定义专属事件 public event EventHandler<EmployeeChangeEventArgs> EmployeeChanged; } // 自定义事件参数,可传递变化前后的值 public class EmployeeChangeEventArgs : EventArgs { public string OldValue { get; } public string NewValue { get; } public EmployeeChangeEventArgs(string oldValue, string newValue) { OldValue = oldValue; NewValue = newValue; } }
订阅示例
mainInstance.EmployeeChanged += (sender, e) => { // 可以直接拿到变化前后的数值 Console.WriteLine($"员工名从 {e.OldValue} 修改为 {e.NewValue}"); second.StringChangedEvent(); third.StringChangedEvent(); };
注意:不再需要监听的时候一定要主动取消事件订阅,否则会导致MainClass实例无法被垃圾回收,出现内存泄漏问题。
内容的提问来源于stack exchange,提问作者CayeHiy
相关产品推荐
相关产品推荐

