是否可通过继承静态方法调用带参数的子类构造函数创建实例
问题解答
1. 不使用泛型能否实现?
不能。
C#中静态方法属于定义它的类本身,不属于继承体系中的多态成员,父类的静态方法无法自动感知当前调用的子类类型,也不可能动态返回对应子类的实例,所以不借助泛型没有办法实现你要的效果。
2. 泛型实现方案
可以用**奇异递归模板模式(CRTP)**实现,也就是父类为泛型类,类型参数传入子类自身即可:
无参构造场景(编译时安全,无性能损耗)
如果所有子类都有无参构造,直接加new()泛型约束即可,完全不需要在子类中写任何Create相关代码:
// 泛型抽象父类 abstract class Bar<T> where T : Bar<T>, new() { public static T Create() => new T(); } // 子类仅需继承时传入自身作为类型参数 class Foo : Bar<Foo> { // 自动继承静态方法 public static Foo Create() } class Baz : Bar<Baz> { // 同样自动拿到Create方法,无需重复编写 }
调用方式完全符合你的偏好:
something += Foo.Create(); something += Baz.Create();
带参构造场景
如果子类构造需要传参,可以借助Activator.CreateInstance实现,缺点是构造参数的匹配不会在编译时检查,参数不匹配会在运行时报错:
abstract class Bar<T> where T : Bar<T> { // 这里的参数列表和所有子类的构造参数列表保持一致即可 public static T Create(int param1, string param2) { return (T)Activator.CreateInstance(typeof(T), param1, param2); } } class Foo : Bar<Foo> { public Foo(int param1, string param2) { // 初始化逻辑 } }
调用示例:
something += Foo.Create(123, "测试参数");
额外说明
如果既不想用泛型也不想每个子类写重复代码,目前C#没有原生支持的方案,只能考虑用源码生成器在编译时自动给每个子类生成Create方法,复杂度会高很多,一般场景下泛型CRTP的方案已经足够用。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

