如何在C#抽象泛型类中初始化带指定Name的泛型属性?
解决方案
针对你的问题,有几种可行的方式能在基类中统一初始化这些属性,避免派生类重复编写代码:
方案1:通过反射创建实例(最简单直接)
既然所有T都继承自DataPropertyBase,且该基类有接受string参数的构造函数,我们可以用Activator.CreateInstance在基类构造函数中反射创建实例,给每个属性赋值固定的Name:
public abstract class DataStructureBase<T> where T : DataPropertyBase { public T prop1 { get; set; } public T prop2 { get; set; } public T prop3 { get; set; } // 其他属性... protected DataStructureBase() { // 利用反射创建T的实例,传入固定Name参数 prop1 = (T)Activator.CreateInstance(typeof(T), "Property A"); prop2 = (T)Activator.CreateInstance(typeof(T), "Property B"); prop3 = (T)Activator.CreateInstance(typeof(T), "Property C"); // 其他属性同理... } }
优缺点:
- 优点:无需修改现有派生类结构,实现最简单,基类完全接管初始化逻辑。
- 缺点:反射会带来少量性能开销(如果你的场景对性能极度敏感需要注意),且编译期无法检查构造函数是否存在(不过你的场景中所有T都继承自DataPropertyBase,风险可控)。
方案2:通过工厂委托实现类型安全初始化
如果你想避免反射的性能损耗,同时保证编译期类型安全,可以让派生类提供一个创建T的工厂方法,基类依赖这个工厂来初始化属性:
public abstract class DataStructureBase<T> where T : DataPropertyBase { public T prop1 { get; set; } public T prop2 { get; set; } public T prop3 { get; set; } // 其他属性... // 定义工厂委托 protected delegate T PropertyFactory(string name); protected DataStructureBase(PropertyFactory factory) { prop1 = factory("Property A"); prop2 = factory("Property B"); prop3 = factory("Property C"); // 其他属性同理... } } // 派生类实现示例 public class DataStructureBaseType1 : DataStructureBase<DataPropertyType1> { public DataStructureBaseType1() : base(name => new DataPropertyType1(name)) { } }
优缺点:
- 优点:编译期类型安全,无反射性能损耗。
- 缺点:每个派生类需要在构造函数中传递工厂委托,不过只需要写一次,相比在派生类中初始化几十个属性,代码量还是少很多。
方案3:利用C# 11+抽象静态成员(需调整基类结构)
如果使用C# 11及以上版本,可以给DataPropertyBase定义抽象静态创建方法,让每个派生类实现,基类直接调用该方法初始化属性:
// 给DataPropertyBase添加抽象静态创建方法 public abstract class DataPropertyBase { public string Name { get; init; } protected DataPropertyBase(string name) { this.Name = name; } // 定义抽象静态创建方法(C# 11+支持) public abstract static T Create<T>(string name) where T : DataPropertyBase; } // 派生类实现Create方法 public class DataPropertyType1 : DataPropertyBase { public DataPropertyType1(string name) : base(name) { } public override static DataPropertyType1 Create<DataPropertyType1>(string name) { return new DataPropertyType1(name); } } // 基类中调用静态方法 public abstract class DataStructureBase<T> where T : DataPropertyBase { public T prop1 { get; set; } public T prop2 { get; set; } public T prop3 { get; set; } // 其他属性... protected DataStructureBase() { prop1 = T.Create<T>("Property A"); prop2 = T.Create<T>("Property B"); prop3 = T.Create<T>("Property C"); // 其他属性同理... } }
优缺点:
- 优点:类型安全,无反射,代码结构更规整。
- 缺点:需要C# 11及以上版本支持,且每个
DataProperty派生类需要实现静态Create方法,改动稍大。
总结
如果不想改现有代码结构,优先选方案1;如果追求性能和类型安全,选方案2;如果使用较新的C#版本且愿意调整DataProperty的结构,可选方案3。
内容的提问来源于stack exchange,提问作者aluc_2513
相关产品推荐
相关产品推荐

