Asumo que normalmente haría algo como esto como parte de una implementación de fábrica, donde los tipos reales aren 't conocido en tiempo de compilación ...
En primer lugar, tenga en cuenta que un enfoque más fácil puede ser un paso de inicialización posterior, luego puede utilizar los genéricos:
static T Create<T>({args}) where T : class, ISomeInitInterface, new() {
T t = new T();
t.Init(args);
return t;
}
Puede usar MakeGenericMethod
y/o CreateDelegate
.
De lo contrario; puede hacerlo sobre la marcha con Expression
(3.5) o DynamicMethod
(2.0).
El Expression
enfoque es más fácil de código:
var param = Expression.Parameter(typeof(int), "val");
var ctor = typeof(Foo).GetConstructor(new[] { typeof(int) });
var lambda = Expression.Lambda<Func<int, Foo>>(
Expression.New(ctor, param), param);
var func = lambda.Compile();
Foo foo = func(123);
string s = foo.ToString(); // proof
o (usando DynamicMethod
):
ConstructorInfo ctor = typeof(Foo).GetConstructor(new[] { typeof(int) });
DynamicMethod dm = new DynamicMethod("Create", typeof(Foo),
new Type[] { typeof(int) }, typeof(Foo), true);
ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Newobj, ctor);
il.Emit(OpCodes.Ret);
Converter<int, Foo> func = (Converter<int, Foo>)
dm.CreateDelegate(typeof(Converter<int, Foo>));
Foo foo = func(123);
string s = foo.ToString(); // proof
Interesante pregunta. Creo que los constructores son métodos efectivos en lo que respecta al CLR, pero no sabría la sintaxis. – Noldorin
Estoy interesado: ¿por qué querrías hacer eso? –
Sospecho que la respuesta es sin embargo. – Noldorin