.NET Framework 4.8与VB.NET下易扩展Immutable类方案是否可行?
问题解答
你的CIC(Constructor Input Class)模式实现方案完全合理,非常适配.NET Framework 4.8的环境限制、面向数据编程(DOP)的思想,以及构造器易扩展的需求,具体分析如下:
方案合理性分析
- 适配.NET Framework 4.8特性限制:由于无法使用C# 9+的Record语法,手动实现只读属性的不可变类是当前环境下的最优选择之一,
ImmutablePerson的只读属性确保了对象状态创建后不可修改,满足线程安全要求。 - 构造器扩展性优秀:新增字段时,仅需在
PersonCIC中添加对应字段/属性,再在ImmutablePerson的构造器中同步赋值即可,无需修改构造器的参数列表——相比传统多参数构造器或重载构造器,这种方式避免了参数膨胀和重载爆炸的问题,扩展成本极低。 - 性能考量到位:选择类作为构造输入而非大结构体,规避了结构体超过16字节时值传递的性能损耗,类的引用传递在参数传递时开销更小,符合你的性能优化诉求。
- 契合面向数据编程思想:
ImmutablePerson作为纯数据载体,仅暴露数据属性无业务行为,完全符合DOP中"数据与行为分离"的核心原则,不可变特性也让多线程环境下的状态管理更简单可预测。
可优化点(进一步完善方案)
虽然当前方案已满足核心需求,可通过以下调整让其更健壮:
规范
PersonCIC的成员定义:将公共字段改为自动属性,更符合C#编码规范,同时保留可赋值能力:public sealed class PersonCIC { public string Name { get; set; } public int Age { get; set; } public string Address { get; set; } }同时可将
PersonCIC的访问修饰符设为internal,限制其仅在类库内部使用,避免外部代码随意修改或滥用这个构造输入类。添加构造参数校验:由于不可变对象创建后无法修改状态,必须在构造阶段确保数据合法性,比如:
public ImmutablePerson(PersonCIC person) { if (person == null) throw new ArgumentNullException(nameof(person)); Name = string.IsNullOrWhiteSpace(person.Name) ? throw new ArgumentException("姓名不能为空", nameof(person.Name)) : person.Name; Age = person.Age < 0 ? throw new ArgumentOutOfRangeException(nameof(person.Age), "年龄不能为负数") : person.Age; Address = person.Address ?? string.Empty; }实现值相等性逻辑:不可变对象通常需要按内容比较而非引用比较,重写
Equals和GetHashCode,或实现IEquatable<ImmutablePerson>接口:public sealed class ImmutablePerson : IEquatable<ImmutablePerson> { public string Name { get; } public int Age { get; } public string Address { get; } public ImmutablePerson(PersonCIC person) { // 带校验的构造逻辑... } public bool Equals(ImmutablePerson other) { if (other == null) return false; return Name == other.Name && Age == other.Age && Address == other.Address; } public override bool Equals(object obj) { return Equals(obj as ImmutablePerson); } public override int GetHashCode() { return HashCode.Combine(Name, Age, Address); } public static bool operator ==(ImmutablePerson left, ImmutablePerson right) { return EqualityComparer<ImmutablePerson>.Default.Equals(left, right); } public static bool operator !=(ImmutablePerson left, ImmutablePerson right) { return !(left == right); } }VB.NET兼容性确认:当前
ImmutablePerson的只读属性在VB.NET中可正常访问(VB.NET支持ReadOnly属性的语法兼容),无需额外调整即可在VSTO插件中使用。
内容的提问来源于stack exchange,提问作者DotNET Afficionado
相关产品推荐
相关产品推荐

