Способы создания объектов в C#

1,00
р.
Я знаю 1 способ создать объекта в C#:
public static class ObjectCreator { public static T GetObject() where T : class { return (T)Activator.CreateInstance(typeof(T)) } }
Есть ли более производительные?
Update класс с известными способами:
public class ObjectCreator where T: new() { protected Func V4Lambda
protected Func V5Lambda
public ObjectCreator() { Type sType = typeof(T)
//V4 V4Lambda = Expression.Lambda>(Expression.New(sType)).Compile()
//V5 V5Lambda = DynamicModuleLambdaCompiler.GenerateFactory() }
public T V1() { return (T)Activator.CreateInstance(typeof(T)) }
public T V2() { return new T() }
public T V3() { return CustomActivator.CreateInstance() }
public T V4() { return V4Lambda() }
public T V5() { return V5Lambda() } }
public static class CustomActivator { public static T CreateInstance() where T : new() { return ActivatorImpl.Factory() }
private class ActivatorImpl where T : new() { private static readonly Expression> _expr = () => new T()
public static readonly Func Factory = _expr.Compile() } }
public static class DynamicModuleLambdaCompiler { public static Func GenerateFactory() where T : new() { Expression> expr = () => new T() NewExpression newExpr = (NewExpression)expr.Body
var method = new DynamicMethod( name: "lambda", returnType: newExpr.Type, parameterTypes: new Type[0], m: typeof(DynamicModuleLambdaCompiler).Module, skipVisibility: true)
ILGenerator ilGen = method.GetILGenerator() // Constructor for value types could be null if (newExpr.Constructor != null) { ilGen.Emit(OpCodes.Newobj, newExpr.Constructor) } else { LocalBuilder temp = ilGen.DeclareLocal(newExpr.Type) ilGen.Emit(OpCodes.Ldloca, temp) ilGen.Emit(OpCodes.Initobj, newExpr.Type) ilGen.Emit(OpCodes.Ldloc, temp) }
ilGen.Emit(OpCodes.Ret)
return (Func)method.CreateDelegate(typeof(Func)) } }
Результаты моего тестирования:


Ответ
В следующих статьях Сергея Теплякова
Исследуем new() ограничение в C# Dissecting the new() constraint in C#: a perfect example of a leaky abstraction
делается вывод, что самый быстрый способ создания объекта - это распарсить лямбду в выражение и скомпилировать его:
public static class DynamicModuleLambdaCompiler { public static Func GenerateFactory() where T:new() { Expression> expr = () => new T() NewExpression newExpr = (NewExpression)expr.Body
var method = new DynamicMethod( name: "lambda", returnType: newExpr.Type, parameterTypes: new Type[0], m: typeof(DynamicModuleLambdaCompiler).Module, skipVisibility: true)
ILGenerator ilGen = method.GetILGenerator() // Constructor for value types could be null if (newExpr.Constructor != null) { ilGen.Emit(OpCodes.Newobj, newExpr.Constructor) } else { LocalBuilder temp = ilGen.DeclareLocal(newExpr.Type) ilGen.Emit(OpCodes.Ldloca, temp) ilGen.Emit(OpCodes.Initobj, newExpr.Type) ilGen.Emit(OpCodes.Ldloc, temp) }
ilGen.Emit(OpCodes.Ret)
return (Func)method.CreateDelegate(typeof(Func)) } }
public static class FastActivator where T : new() { /// /// Extremely fast generic factory method that returns an instance /// of the type . /// public static readonly Func Create = DynamicModuleLambdaCompiler.GenerateFactory() }
Method | Mean | StdDev | Gen 0 | ------------------------ |----------- |---------- |------- | ActivatorCreateInstance | 95.0161 ns | 1.0861 ns | 0.0005 | FuncBasedFactory | 6.5741 ns | 0.0608 ns | 0.0034 | FastActivator_T_Create | 5.1715 ns | 0.0466 ns | 0.0034 |