Sto assumendo che normalmente fare qualcosa di simile come parte di un'implementazione fabbrica, dove i tipi effettivi aren noto al momento della compilazione ...
In primo luogo, si noti che un approccio più semplice può essere un passo di post-creazione, quindi è possibile utilizzare i generici:
static T Create<T>({args}) where T : class, ISomeInitInterface, new() {
T t = new T();
t.Init(args);
return t;
}
È quindi possibile utilizzare MakeGenericMethod
e/o CreateDelegate
.
Altrimenti; puoi farlo al volo con Expression
(3.5) o DynamicMethod
(2.0).
Il Expression
approccio è più facile da codice:
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 (utilizzando 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
fonte
2009-10-21 15:35:23
Interessante domanda. Credo che i costruttori siano effettivamente metodi per quanto riguarda il CLR, ma non conoscerei la sintassi. – Noldorin
Sono interessato: perché vorresti farlo? –
Sospetto che la risposta non sia comunque. – Noldorin