如何在抽象类内部构造当前具体子类类型的新实例
方案对比与优化建议
你当前的实现本身是非常规范且高效的,属于工厂方法模式在继承体系下的典型应用,没有明显缺陷。如果追求更简洁的代码,可以参考以下几种方案:
方案1:保持现有实现(推荐,适合你的场景)
优势
- 完全类型安全,所有校验在编译期完成
- 无任何反射开销,性能达到最优
- 逻辑直观,没有语法黑魔法,后续维护成本极低
不足
- 每个子类需要多写3行左右的工厂方法重写代码,如果你只有
XState、YState两个子类,这点冗余完全可以接受。
方案2:基类反射统一实现(最简写法)
直接在抽象基类中通过运行时类型信息创建对应子类实例,不需要子类重写任何方法:
public abstract class AxisState { // 删掉原来的抽象NewStateOfSameType声明,直接实现 public AxisState NewStateOfSameType(int fieldOne, int fieldTwo) { return (AxisState)Activator.CreateInstance(GetType(), fieldOne, fieldTwo); } public abstract AxisState OverloadMethod(); public abstract AxisState AnotherOverloadMethod(); public AxisState(int fieldOne, int fieldTwo) { // ... } public AxisState NextState(/*...*/) { // ... return NewStateOfSameType(fieldOne, fieldTwo); } // ... }
子类代码可以直接删掉NewStateOfSameType的重写逻辑:
public class XState : AxisState { public XState(int fieldOne, int fieldTwo) : base(fieldOne, fieldTwo) {} // 此处实现其余抽象方法即可 } public class YState : AxisState { public YState(int fieldOne, int fieldTwo) : base(fieldOne, fieldTwo) {} // 此处实现其余抽象方法即可 }
优势
- 代码极简,子类不需要任何额外工厂相关代码
不足
- 存在轻微的反射性能开销,仅在每秒调用数万次以上的场景会有感知
- 子类如果没有匹配的
(int, int)构造函数,只会在运行时报错,没有编译期校验
方案3:反射+泛型缓存(兼顾简洁与高性能)
如果既要代码简洁,又要避免高频调用下的反射性能损耗,可以用泛型缓存预存构造函数委托,首次调用后后续性能接近直接new:
public abstract class AxisState { // 泛型缓存类,每个子类对应唯一的工厂委托缓存 private static class StateFactory<T> where T : AxisState { public static readonly Func<int, int, T> Create = (f1, f2) => (T)Activator.CreateInstance(typeof(T), f1, f2); } public AxisState NewStateOfSameType(int fieldOne, int fieldTwo) { // 利用dynamic动态绑定到对应子类的缓存委托 dynamic self = this; return StateFactory<self>.Create(fieldOne, fieldTwo); } // 其余原有代码保持不变 }
优势
- 子类不需要写额外工厂代码
- 首次调用后后续无反射开销,性能和原生
new几乎一致
不足
- 用到了
dynamic语法,对不熟悉该特性的开发者有一定理解成本 - 依旧没有编译期构造函数匹配校验
选型建议
- 如果你的场景对性能要求极高,或者后续不会新增太多
AxisState子类,直接保留现有实现即可,完全没必要重构。 - 如果追求代码简洁,且该方法调用频率不高,选方案2即可满足需求。
- 如果既要代码简洁又要高性能,选方案3。
内容的提问来源于stack exchange,提问作者directquest
相关产品推荐
相关产品推荐

