new()约束只是编译器强制类型具有public无参构造函数的语法糖,并非设计模式意义上的工厂;它不支持传参、私有/内部构造及静态工厂方法,真正动态创建需用activator.createinstance或表达式树委托缓存,或交由di容器实现解耦。

为什么 new() 约束不是真正的工厂模式
它只是编译器强制要求类型必须有无参公共构造函数,不支持传参、不支持私有/内部构造、不支持静态工厂方法——本质上是个语法糖,不是设计模式意义上的“工厂”。真正需要动态创建带参数对象时,new() 约束直接失效。
常见错误现象:T t = new T(); 编译失败,提示 “‘T’ must be a non-abstract type with a public parameterless constructor”;或者运行时报 MissingMethodException,因为实际类型只有 private T() 或 T(int x)。
-
new()只校验编译期可见的 public 无参构造,不检查运行时实际可用性 - 值类型(如
struct)自动满足该约束,但调用new T()实际触发的是默认初始化(非构造函数调用) - 泛型类或方法若仅依赖
new(),就无法适配 DTO、Entity 等常用类型中常见的私有构造 + 工厂方法场景
绕过 new() 约束:用 Activator.CreateInstance 动态构造
当需要传参、或类型不满足 new() 约束时,Activator.CreateInstance 是最直接的替代方案。但它有性能开销和反射限制,需谨慎使用。
使用场景:从配置读取类型名并实例化、ORM 映射结果集到泛型实体、测试中 mock 泛型依赖。
- 支持带参构造:
Activator.CreateInstance<t>(arg1, arg2)</t>,但要求参数类型和顺序完全匹配 - 对 private 构造函数有效(需配合
BindingFlags.NonPublic | BindingFlags.Instance) - 注意兼容性:
Activator.CreateInstance(Type, object[])在 .NET Core 3.0+ 中性能显著下降,建议缓存ConstructorInfo - 若类型是抽象类或接口,会抛出
MissingMethodException,需提前用Type.IsClass && !Type.IsAbstract校验
示例:
var instance = Activator.CreateInstance(typeof(MyService), "prod", 8080);
高性能替代方案:用 System.Reflection.Emit 或表达式树生成构造委托
频繁调用 Activator.CreateInstance 会导致 GC 压力和 JIT 开销。生产环境应预编译构造逻辑为委托。
推荐用表达式树(更安全、可读性好),避免手写 IL:
- 构建
Expression.New并编译为Func<object... t></object...>,首次调用稍慢,后续极快 - 缓存委托到
ConcurrentDictionary<type delegate></type>,避免重复编译 - 对泛型类型构造,需按闭合类型(如
List<string></string>)单独缓存,不能按开放泛型(List)通用处理 - 表达式树不支持 private 构造函数,仍需回退到
ConstructorInfo.Invoke+BindingFlags
简略示意:
var ctor = typeof(T).GetConstructor(new[] { typeof(string), typeof(int) });<br>var paramExprs = new[] { Expression.Parameter(typeof(string)), Expression.Parameter(typeof(int)) };<br>var newExpr = Expression.New(ctor, paramExprs);<br>var lambda = Expression.Lambda(Expression.Convert(newExpr, typeof(T)), paramExprs).Compile();
真正解耦的工厂模式:用接口 + DI 容器代替泛型约束
如果业务逻辑频繁需要“创建 T”,说明职责已越界——泛型方法不该承担对象生命周期管理。应把创建逻辑外移到具体工厂接口中。
例如定义 IRepositoryFactory<t></t> 或 ITranslator<tin tout></tin>,由 DI 容器注入具体实现。这样既规避了 new() 的局限,又利于单元测试和替换策略。
- ASP.NET Core 中注册:
services.AddSingleton<iworkerfactory workerfactory>()</iworkerfactory>,而非在泛型服务里硬编码new T() - 泛型约束可退化为
where T : class,把实例化责任彻底交给调用方 - 避免在泛型工具类(如
JsonHelper<t></t>)中耦合创建逻辑;JSON 反序列化本身已有JsonSerializerOptions.Converters机制可接管对象构造
底层关键点:new() 约束是泛型系统的轻量级契约,不是对象创建的解决方案。真要动态、灵活、高性能地构造泛型对象,得跳出泛型约束本身,走向委托缓存或依赖注入。











