C#中如何直接赋值VersionedData且保留原有版本号?
问题解答
C#原生无法直接通过save.Age = 18;的语法实现赋值同时保留原有VersionedData<T>实例的版本号——因为该赋值操作会触发你定义的implicit operator VersionedData<T>(T data),生成一个全新的VersionedData<T>实例(版本号固定为0),覆盖原实例,导致原有版本号丢失。
以下是几种可行的实现思路:
思路1:给VersionedData<T>添加数据更新方法
直接在泛型类中新增一个修改Data的方法,避免创建新实例:
public class VersionedData<T> { public int Version { get; set; } public T Data { get; set; } // 构造函数和隐式转换保留不变 public void UpdateData(T newData) { Data = newData; } }
使用时直接调用方法:
var save = new Save(); save.Age.UpdateData(18);
这种方式逻辑清晰,完全保留原有版本号,且没有歧义。
思路2:修改属性的Setter逻辑适配隐式转换
在Save类的属性Setter中做判断:如果传入的VersionedData<T>实例版本号为0(即通过隐式转换生成的默认实例),则仅更新原有实例的Data,而非替换整个实例:
public class Save { private VersionedData<string> _name = ""; public VersionedData<string> Name { get => _name; set { if (value.Version == 0 && _name != null) { _name.Data = value.Data; } else { _name = value; } } } private VersionedData<int> _age = new(data: 21, version: 1); public VersionedData<int> Age { get => _age; set { if (value.Version == 0 && _age != null) { _age.Data = value.Data; } else { _age = value; } } } }
这样你就能直接用save.Age = 18;的语法赋值,同时保留原有版本号。注意:如果你的业务场景中允许手动创建版本号为0的VersionedData<T>实例,这种方法会产生歧义,需要根据实际需求调整判断逻辑。
思路3:重载自定义运算符
通过重载+=运算符实现类似赋值的语法,同时修改当前实例的Data:
public class VersionedData<T> { public int Version { get; set; } public T Data { get; set; } // 构造函数和隐式转换保留不变 public static VersionedData<T> operator +=(VersionedData<T> instance, T newData) { instance.Data = newData; return instance; } }
使用时语法为:
var save = new Save(); save.Age += 18;
这种方式语法接近直接赋值,且不会创建新实例,版本号得以保留。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

