如何在“sub”表达式中使用lambda表达式参数?

我希望能够像下面的委托一样构建表达式:

Func createSomeType1 = (args) => { return new SomeType1((P1)args[0], (P2)args[1], (P3)args[2]); }; 

我刚开始用手工制作的表达式,请原谅我这是一个相当简单的问题(或者我误解了一些问题)。

我知道要使用正确的类型创建构造函数,我会执行以下操作:

 var p1 = Expression.Parameter(typeof(P1)); var p2 = Expression.Parameter(typeof(P2)); var p3 = Expression.Parameter(typeof(P3)); var someType1Exp = Expression.New(constructorInfo, p1, p2, p3); 

然后我知道,“外部”lambda,我认为,这样声明:

 Expression<Func>.Lambda<Func>( someType1Exp, Expression.Parameter(typeof(object[]))); 

我无法绕过如何将参数从外部表达式“传递”到内部表达式,然后将其转换为正确的类型。

任何正确方向的提示都值得赞赏。

我在iPod上,所以现在不能给出一个完整的例子:但是:

  • 声明一个类型为object []( Expression.Param(typeof(object[])) )的参数并将其存储在一个变量中
  • 对于数组中的每个术语,使用数组索引器获取索引器的表达式,并使用“ Convert ”或“ Convert ”(再次使用iPod!)来转换它
  • 使用Expression.Invoke ,传递内部表达式加上上面生成的索引器+转换

如果你需要(我在PC的时候),我会很乐意做一个完整的例子


完整示例:

 Type[] types = new Type[] { typeof(int), typeof(float), typeof(string) }; var constructorInfo = typeof(SomeType).GetConstructor(types); var parameters = types.Select((t,i) => Expression.Parameter(t, "p" + i)).ToArray(); var someType1Exp = Expression.New(constructorInfo, parameters); var inner = Expression.Lambda(someType1Exp, parameters); var args = Expression.Parameter(typeof(object[]), "args"); var body = Expression.Invoke(inner, parameters.Select((p,i) => Expression.Convert(Expression.ArrayIndex(args, Expression.Constant(i)), p.Type)).ToArray()); var outer = Expression.Lambda>(body, args); var func = outer.Compile(); object[] values = {1, 123.45F, "abc"}; object obj = func(values); Console.WriteLine(obj); 

或者作为单个表达式:

 Type[] types = new Type[] { typeof(int), typeof(float), typeof(string) }; var constructorInfo = typeof(SomeType).GetConstructor(types); var args = Expression.Parameter(typeof(object[]), "args"); var body = Expression.New(constructorInfo, types.Select((t,i) => Expression.Convert(Expression.ArrayIndex(args, Expression.Constant(i)), t)).ToArray()); var outer = Expression.Lambda>(body, args); var func = outer.Compile(); object[] values = {1, 123.45F, "abc"}; object obj = func(values); Console.WriteLine(obj);