如何在& quot; sub& quot;中使用lambda表达式参数表达? [英] How to use lambda expression parameter in "sub" expression?

查看:47
本文介绍了如何在& quot; sub& quot;中使用lambda表达式参数表达?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我只是从手工表达开始,所以请问这是一个很简单的问题(或者我误会了什么).

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

然后我知道外部" lambda是这样声明的:

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

我无法解决如何将参数从外部表达式传递"到内部表达式,然后将其强制转换为正确的类型的问题.

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.

任何朝着正确方向的提示都会受到赞赏.

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 []的参数( Expression.Param(typeof(object [])))并将其存储在变量中
  • 对于数组中的每个术语,请使用数组 indexer 获取索引器的表达式,然后使用" Convert "或"cast"(再次输入iPod!)投放
  • 使用 Expression.Invoke ,传递内部表达式以及您在上面生成的indexer + cast
  • 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);


或作为单个表达式:


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

这篇关于如何在&amp; quot; sub&amp; quot;中使用lambda表达式参数表达?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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