C#中无法修改私有set属性?如何复制对象并重置属性
问题分析与解决方案
核心原因
你的属性逻辑存在get和set完全脱节的问题:
- Getter通过
Get<string>("Key", "key")从类的内部数据源(比如私有字典、缓存)读取值; - Setter仅把值赋值给临时变量
tmpValue,完全没有同步到Get<T>读取的数据源里。
所以你显式给属性赋值null,只是修改了tmpValue,但Getter依然从原始数据源取原值,自然看不到变化。
解决方案
1. 能修改类源码的最优方案
修正Setter逻辑,让赋值同步到内部数据源,确保Getter能读取到最新值:
// 假设类内部有一个存储属性值的私有字典_storage private Dictionary<string, object> _storage = new Dictionary<string, object>(); public string Key { get { return _storage.TryGetValue("Key", out var val) ? (string)val : "key"; } private set { tmpValue = value; // 同步到内部存储 _storage["Key"] = value; } }
之后复制对象时:
- 实例化新对象;
- 手动给需要保留的属性赋值;
- 对不需要保留的属性,直接赋值
null(此时Setter会同步到数据源),或者调用类内的重置方法(比如ClearProperty(string key))。
2. 无法修改类源码的折中方案
通过反射直接操作类的内部私有存储:
// 1. 先浅拷贝得到新对象(比如用MemberwiseClone) var newObj = (YourClass)sourceObj.MemberwiseClone(); // 2. 反射获取内部存储字段(假设字段名为_storage) var storageField = typeof(YourClass).GetField( "_storage", BindingFlags.NonPublic | BindingFlags.Instance ); if (storageField != null) { var storage = (Dictionary<string, object>)storageField.GetValue(newObj); // 3. 保留指定属性,其余设为null var keepKeys = new List<string> { "Key" }; // 这里放需要保留的属性对应的键 foreach (var key in storage.Keys.ToList()) { if (!keepKeys.Contains(key)) { storage[key] = null; } } }
注意:反射依赖类的内部实现细节,如果后续类的内部存储字段名或类型变更,代码会失效。
内容的提问来源于stack exchange,提问作者alooparantha
相关产品推荐
相关产品推荐

