如何在C#泛型基类中实例化泛型类型?有哪些更简便的实现方案?
方案1:使用new()泛型约束(最适配你的场景,实现最简单)
你代码中写的TEntity属于笔误,修正为和泛型参数一致的TProduct后,直接给泛型参数增加new()约束,即可在基类直接实例化泛型类型,完全不需要定义抽象方法、让每个子类重写:
public abstract class XmlParser<TProduct> where TProduct : ProductBase, new() { private string _parserName; public XmlParser(string parserName) { _parserName = parserName; } public List<TProduct> Parse() { // 直接实例化泛型类型,无需额外抽象方法 TProduct product = new TProduct(); // 后续XML反序列化到product的逻辑 } }
对应的派生类可以直接简化,不需要再实现Instanciate方法:
public class CarXmlParser : XmlParser<Car> { public CarXmlParser() : base("CarParse") {} }
该方案唯一要求是所有继承自ProductBase的产品类(比如Car)必须包含公共无参构造函数,从你现有子类的实现来看已经满足这个条件,直接套用即可。
方案2:工厂委托注入(适配产品类需要带参构造的场景)
如果部分产品类没有无参构造,需要传入参数实例化,可以用工厂委托替代抽象方法,灵活度更高:
public abstract class XmlParser<TProduct> where TProduct : ProductBase { private string _parserName; private Func<TProduct> _productFactory; public XmlParser(string parserName, Func<TProduct> productFactory) { _parserName = parserName; _productFactory = productFactory; } public List<TProduct> Parse() { TProduct product = _productFactory(); // 后续XML反序列化到product的逻辑 } }
对应的派生类实现:
public class CarXmlParser : XmlParser<Car> { public CarXmlParser() : base("CarParse", () => new Car()) {} // 如果Car需要带参构造,直接在委托里传参即可,比如: // public CarXmlParser() : base("CarParse", () => new Car("自定义参数")) {} }
不推荐方案:反射实例化
你也可以用反射直接创建实例,代码如下:
TProduct product = Activator.CreateInstance<TProduct>();
但该方案性能不如前两种,且没有编译时类型校验,运行时可能抛出构造函数不存在的异常,非特殊场景不建议使用。
内容的提问来源于stack exchange,提问作者Hooman Bahreini
相关产品推荐
相关产品推荐

