如何使用拉姆达EX pression参数"分" EX pression? [英] How to use lambda expression parameter in "sub" expression?

查看:157
本文介绍了如何使用拉姆达EX pression参数"分" EX pression?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够建立EX pressions像下面的委托:

I'd like to be able to build expressions like the following delegate:

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

我刚开始学习手工制作EX pressions所以原谅我,如果这是一个相当简单的问题(或者说我误解的东西)。

I'm just starting out with hand made expressions so excuse me if this is a rather simple question (or I'm misunderstanding something).

我知道,创建具有合适类型的构造,我会做到以下几点:

I know that to create the constructor with the right types, I'd do the following:

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);

然后,我知道了外拉姆达是,我认为,声明是这样的:

And then I know the "outer" lambda is, I think, declared like this:

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

我在遇到麻烦缠绕我的头围绕如何从外EX pression通行证的参数内前pression,然后将其转换为正确的类型。

I'm having trouble wrapping my head around how to "pass" the parameter from the outer expression to the inner expression and then cast it to the right type.

任何提示的方向是正确的AP preciated。

Any hints in the right direction are appreciated.

推荐答案

我的iPod,因此无法给出一个完整的例子,此刻:但是:

I'm on iPod, so can't give a full example at the moment: but:

  • 在声明object类型的参数[](防爆pression.Param(typeof运算(对象[]))),并存储在一个变量
  • 从阵列中的每个词,使用数组的索引的获得一个前pression的索引,而转换或者(iPod的!)中投投它
  • 使用防爆pression.Invoke ,通过内部EX pression加上索引+投你上面
  • 生成
  • declare a param of type object[] (Expression.Param(typeof(object[]))) and store that in a variable
  • for each term from the array, use the array indexer to obtain an expression to the indexer, and "Convert" or "cast" (iPod again!) to cast it
  • use Expression.Invoke, passing the inner expression plus the indexer+cast you generated above

我会很乐意做一个完整的例子后,如果您需要(当我在一台PC)

I'll be happy to do a complete example later if you need (when I'm at a 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<Func<object[], object>>(body, args);
var func = outer.Compile();

object[] values = {1, 123.45F, "abc"};
object obj = func(values);
Console.WriteLine(obj);


或单前pression:


Or as a single expression:

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<Func<object[], object>>(body, args);
var func = outer.Compile();

object[] values = {1, 123.45F, "abc"};
object obj = func(values);
Console.WriteLine(obj);

这篇关于如何使用拉姆达EX pression参数&QUOT;分&QUOT; EX pression?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆