I assume that you usually do something like this as part of a factory implementation where the actual types are not known at compile time ...
First, note that a simpler approach may be a step after creation, then you can use generics:
static T Create<T>({args}) where T : class, ISomeInitInterface, new() { T t = new T(); t.Init(args); return t; }
Then you can use MakeGenericMethod and / or CreateDelegate .
Otherwise; You can do this on the fly using Expression (3.5) or DynamicMethod (2.0).
The Expression approach is easier to code:
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();
or (using 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();
Marc Gravell Oct 21 '09 at 15:35 2009-10-21 15:35
source share