我有一个如下所示的类:
class Foo
{
public Foo(int x) { ... }
}
我需要将一个委托传递给某个方法,如下所示:
delegate Foo FooGenerator(int x);
是否可以直接将构造函数作为FooGenerator
值传递,而不必键入:
delegate(int x) { return new Foo(x); }
编辑:供我个人使用,这个问题涉及到.NET 2.0,但也欢迎针对3.0+的提示/回复。
发布于 2009-10-21 21:15:23
不,CLR不允许将委托绑定到ConstructorInfo
。
但是,您可以只创建自己的:
static T Make<T>(Action<T> init) where T : new()
{
var t = new T();
init(t);
return t;
}
用法
var t = Make<Foo>( x => { x.Bar = "bar"; x.Baz = 1; });
发布于 2009-10-21 23:35:23
我假设您通常会在工厂实现中执行类似的操作,其中实际类型在编译时是未知的……
首先,请注意,更简单的方法可能是创建后初始化步骤,然后您可以使用泛型:
static T Create<T>({args}) where T : class, ISomeInitInterface, new() {
T t = new T();
t.Init(args);
return t;
}
然后,您可以使用MakeGenericMethod
和/或CreateDelegate
。
否则,您可以使用Expression
(3.5)或DynamicMethod
(2.0)即时完成此操作。
Expression
方法更易于编码:
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
或者(使用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
发布于 2009-10-21 21:15:23
我认为最简洁的(不需要转移到工厂模式)就是使用匿名方法,如下所示:
delegate Foo FooGenerator(int x);
...
void DoStuff()
{
YourDelegateConsumer(x => new Foo(x));
}
这并没有严格按照您的要求(因为您将委托传递给一个返回新实例的匿名方法,而不是直接委托给构造函数),但我认为您所要求的严格来说是不可能的。
当然,假设您使用的是3.5+
https://stackoverflow.com/questions/1600712
复制相似问题