I have a class like below:
class Foo { public Foo(int x) { ... } }
and I need to pass to a certain method a delegate like this:
delegate Foo FooGenerator(int x);
Is it possible to pass the constructor directly as a FooGenerator
value, without having to type:
delegate(int x) { return new Foo(x); }
?
EDIT: For my personal use, the question refers to .NET 2.0, but hints/responses for 3.0+ are welcome as well.
I'm assuming you would normally do something like this as part of a factory implementation, where the actual types aren't known at compile-time...
First, note that an easier approach may be a post-create init step, then you can use generics:
static T Create<T>({args}) where T : class, ISomeInitInterface, new() { T t = new T(); t.Init(args); return t; }
You can then use MakeGenericMethod
and/or CreateDelegate
.
Otherwise; you can do this with on the fly with 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(); // proof
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(); // proof
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With