如何在C#中正确引用静态列表对象成员并解决CS0206编译错误?
首先,你遇到的CS0206错误原因很直接:C#不允许将属性或索引器作为ref/out参数传递。因为MainObject.A是属性(背后是get_A()方法),不是直接的内存字段,所以编译器不允许用ref修饰它。而且你的核心需求是让SubObject的属性和对应的MainObject同步,完全不需要用ref来实现——我们换两种更合理的方案:
方案1:让SubObject持有MainObject的引用,直接访问其属性
这个方案最简单,SubObject不需要自己存储A/B的值,而是直接通过引用的MainObject获取最新值,天然实现同步。
修改SubObject的代码:
public class SubObject { // 保存对应MainObject的引用 private readonly MainObject _mainSource; // 用属性包装MainObject的属性,自动同步 public bool A => _mainSource.A; public bool B => _mainSource.B; // 构造函数直接接收MainObject实例 public SubObject(MainObject mainSource) { _mainSource = mainSource ?? throw new ArgumentNullException(nameof(mainSource)); } }
然后添加SubObject时,直接传递OriginList里的实例即可:
// 不需要任何ref,直接传实例 MyClass.SubList.Add(new SubObject(MyClass.OriginList[0]));
因为MainObject已经实现了INotifyPropertyChanged,GUI绑定SubObject.A/SubObject.B时,会自动感知到MainObject属性的变化并更新显示。
方案2:订阅MainObject的PropertyChanged事件,同步SubObject的字段
如果你需要SubObject自己存储A/B的值(比如要做额外处理),可以订阅MainObject的PropertyChanged事件,在源属性变化时主动更新自己的字段。
修改SubObject(记得实现INotifyPropertyChanged让GUI感知变化):
using System.ComponentModel; using System.Runtime.CompilerServices; public class SubObject : INotifyPropertyChanged { private readonly MainObject _mainSource; private bool _a; private bool _b; public bool A { get => _a; private set { if (_a != value) { _a = value; NotifyPropertyChanged(); } } } public bool B { get => _b; private set { if (_b != value) { _b = value; NotifyPropertyChanged(); } } } public SubObject(MainObject mainSource) { _mainSource = mainSource ?? throw new ArgumentNullException(nameof(mainSource)); // 初始化初始值 A = _mainSource.A; B = _mainSource.B; // 订阅源对象的属性变化事件 _mainSource.PropertyChanged += MainSource_PropertyChanged; } private void MainSource_PropertyChanged(object sender, PropertyChangedEventArgs e) { // 只关心A和B的变化 if (e.PropertyName == nameof(MainObject.A)) { A = _mainSource.A; } else if (e.PropertyName == nameof(MainObject.B)) { B = _mainSource.B; } } // 实现INotifyPropertyChanged接口 public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
添加SubObject的方式和方案1一样,不需要ref参数。
顺便修复你的代码小错误
注意到MyClass里的SubList getter写错了,应该返回_subList而不是_originList,否则会因为类型不匹配编译失败:
// 原错误代码 static public ObservableCollection<SubObject> SubList { get => _originList; } // 修改后 static public ObservableCollection<SubObject> SubList { get => _subList; }
这两种方案都能完美实现你要的同步效果,而且完全符合C#的设计规范,也规避了ref参数的限制。
内容的提问来源于stack exchange,提问作者Robot Fox

