許多開發者以為 where T : new() 讓 new T() 在編譯期產生與具象型別完全相同的 IL 指令。實際上並非如此。
new MyClass<SomeType>()) 驗證 SomeType 是否有**公用無參數建構函式**。否則編譯錯誤 (CS0310)。new T() 編譯為 call !!0 [mscorlib]System.Activator::CreateInstance<!!0>(),即**透過反射在執行期建立實例**。.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// 程式碼大小 15 (0xf)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: call !!0 [mscorlib]System.Activator::CreateInstance<T>()
IL_000c: stfld class T MyClass`1<T>::t
IL_0011: ret
}
Activator.CreateInstance<T>() 涉及反射,比直接 new SomeType() **慢 10~100 倍** (視 .NET 版本與 JIT 優化)。public class Factory<T> where T : new()
{
private static readonly Func<T> _creator = CreateCreator();
private static Func<T> CreateCreator()
{
// 運算式樹編譯為強型別委派,僅第一次呼叫付出反射成本
var ctor = typeof(T).GetConstructor(Type.EmptyTypes);
var lambda = Expression.Lambda>(Expression.New(ctor));
return lambda.Compile();
}
public static T Create() => _creator();
}
public interface IFactory { T Create(); }
public class MyService where T : new()
{
private readonly IFactory _factory;
public MyService(IFactory factory) { _factory = factory; }
public T CreateInstance() => _factory.Create();
}
// 註冊具象工廠 (DI 容器自動解析)
public class ConcreteFactory : IFactory
{
public ConcreteType Create() => new ConcreteType(); // 直接 new,零反射
}
default 建構函式語法 (僅結構體)
struct Point { public int X, Y; }
Point p = new(); // 隱含 new(),結構體無反射開銷
T prototype = new T(); 後續用 MemberwiseClone 複製。where T : new() 是**編譯期約束 + 執行期反射建立**的語法糖。高效能場景請改用**委派快取**、**抽象工廠**或 **DI 容器**注入具象工廠,避免熱路徑反射開銷。