C#中如何通过泛型实现无需手动类型检查的对象创建?
通用模板对象创建方案(无需手动类型检查)
给你几个无需手动加类型判断的实现方案,直接适配新增的模板类:
方案1:泛型+反射创建实例(简单直接)
核心思路是利用所有模板类都有List<string>构造函数的特点,用泛型方法配合Activator.CreateInstance自动创建实例,不用写if-else判断类型。
先看模板类定义(保持你原有的结构就行):
public class TemplateA { public TemplateA(List<string> items) { // 你的初始化逻辑 } } public class TemplateB { public TemplateB(List<string> items) { // 你的初始化逻辑 } }
然后改写PopulateItems方法:
public List<T> PopulateItems<T>(List<string> items) where T : class { var result = new List<T>(); // 这里替换成你实际的批量创建逻辑,比如循环N次 for (int i = 0; i < 5; i++) { // 自动调用对应类型的构造函数,传入List<string>参数 var instance = Activator.CreateInstance(typeof(T), items) as T; if (instance != null) { result.Add(instance); } } return result; }
使用的时候直接指定类型就行,新增模板类后直接调用,不用改方法:
var data = new List<string> { "test1", "test2" }; var templateAList = PopulateItems<TemplateA>(data); var templateBList = PopulateItems<TemplateB>(data); // 新增TemplateC后,直接写PopulateItems<TemplateC>(data)即可
方案2:统一接口+工厂模式(适合复杂项目)
如果后续模板类需要更多初始化逻辑,或者要管理对象生命周期,可以让所有模板类实现统一接口,再配合工厂类实现通用创建。
第一步定义接口:
public interface ITemplate { void Init(List<string> items); }
修改模板类实现接口:
public class TemplateA : ITemplate { public void Init(List<string> items) { // 初始化逻辑 } } public class TemplateB : ITemplate { public void Init(List<string> items) { // 初始化逻辑 } }
然后写通用工厂类:
public class TemplateFactory { // 如果用依赖注入,可以在这里注入IServiceProvider,方便管理实例 private readonly IServiceProvider? _serviceProvider; public TemplateFactory(IServiceProvider? serviceProvider = null) { _serviceProvider = serviceProvider; } public T Create<T>(List<string> items) where T : class, ITemplate { // 用依赖注入获取实例,或者直接反射创建 var template = _serviceProvider?.GetService<T>() ?? Activator.CreateInstance<T>(); template.Init(items); return template; } public List<T> PopulateItems<T>(List<string> items, int count) where T : class, ITemplate { var result = new List<T>(); for (int i = 0; i < count; i++) { result.Add(Create<T>(items)); } return result; } }
使用方式:
var factory = new TemplateFactory(); var data = new List<string> { "test1", "test2" }; var templateAList = factory.PopulateItems<TemplateA>(data, 5); // 新增TemplateC后,只要实现ITemplate,直接调用factory.PopulateItems<TemplateC>(data, 5)
方案3:表达式树优化性能(适合高频调用场景)
如果担心反射的性能问题,可以用表达式树提前编译构造函数委托,第一次调用后后续性能和直接new差不多。
先写一个静态创建器类:
public static class TemplateCreator<T> { private static readonly Func<List<string>, T> _createInstance; static TemplateCreator() { // 查找当前类型的List<string>构造函数 var constructor = typeof(T).GetConstructor(new[] { typeof(List<string>) }); if (constructor == null) { throw new InvalidOperationException($"{typeof(T)} 必须有接受List<string>的构造函数"); } // 编译构造函数为委托 var param = Expression.Parameter(typeof(List<string>), "items"); var newExpr = Expression.New(constructor, param); _createInstance = Expression.Lambda<Func<List<string>, T>>(newExpr, param).Compile(); } public static T Create(List<string> items) { return _createInstance(items); } }
然后改写PopulateItems:
public List<T> PopulateItems<T>(List<string> items) { var result = new List<T>(); for (int i = 0; i < 5; i++) { result.Add(TemplateCreator<T>.Create(items)); } return result; }
这个方案兼顾通用性和性能,新增模板类只要符合构造函数要求,直接调用即可。
内容的提问来源于stack exchange,提问作者TheLovelySausage
相关产品推荐
相关产品推荐

