从其他两个(链接表达式)创建动态表达式lambda [英] Create dynamic Expression lambda from two others (chaining the Expressions)

查看:115
本文介绍了从其他两个(链接表达式)创建动态表达式lambda的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 表达式< Func<标识,对象>> ; fx = _ => _。ID; 

还有一个将对象转换为识别实例的转换lambda:

  ParameterExpression p = Expression.Parameter(typeof(object),o); 
Expression @new = Expression.Lambda(Expression.Convert(p,typeof(Identification)),p);

如何构建一个执行 @new (取出识别实例),并将结果传递到 fx 。我需要 @new 的结果绑定到 fx 的第一个参数,我找不到一个例子。



我需要将结果作为表达式,它应该是类型 Expression< Func< object,object>> ,它应将入站参数转换为标识,然后获取 Id property。

解决方案

首先,请注意,如果键入 @新的适当地,即:

  LambdaExpression @new = ... 

,因为它可以轻松访问 @ new.Body @ new.Parameters ;这样做,
Expression.Invoke 可以在这里有用:

  var combinedParam = Expression.Parameter(typeof(object),o); 
var combined = Expression.Lambda&FunC< object,object>(
Expression.Invoke(fx,
Expression.Invoke(@new,combinedParam)),combinedParam);

虽然对于更干净的表达式,您也可以使用 ExpressionVisitor 完全替换内部表达式:

  var inject = new SwapVisitor(fx.Parameters [0],@new。体).Visit(fx.Body); 
var combined = Expression.Lambda

with:

 code> class SwapVisitor:ExpressionVisitor {
private readonly Expression from,to;
public SwapVisitor(Expression from,Expression to){
this.from = from;
this.to = to;
}
public override表达式访问(表达式节点){
return node == from? to:base.Visit(node);
}
}

这是什么:




  • 检查 fx.Body 树,替换所有 _ (参数)与 @ new.Body (注意,这将包含对 o的引用参数(aka p

  • 然后我们从替换的表达式中构建一个新的lambda,重新使用来自 @new ,确保我们注入的值正确绑定


Given a lambda that takes an Identification object, and returns a property:

Expression<Func<Identification, object>> fx = _ => _.Id;

And a conversion lambda that converts an object into an Identification instance:

ParameterExpression p = Expression.Parameter(typeof(object), "o");
Expression @new = Expression.Lambda(Expression.Convert(p, typeof(Identification)), p);

How do I build a new lambda that executes @new (getting out the Identification Instance) and passes the result into fx. I need @new's result to bind to the first parameter of fx somehow, and I cannot find an example.

I need the result to be an Expression, it should be of type Expression<Func<object, object>> and it should convert the inbound parameter to an Identification and then get the Id property.

解决方案

Firstly, note that this is easier if you type @new appropriately, i.e.:

LambdaExpression @new = ...

since that provides easy access to @new.Body and @new.Parameters; that done, Expression.Invoke can be useful here:

var combinedParam = Expression.Parameter(typeof(object), "o");
var combined = Expression.Lambda<Func<object, object>>(
    Expression.Invoke(fx,
        Expression.Invoke(@new, combinedParam)), combinedParam);

although for a cleaner expression, you can also use ExpressionVisitor to completely replace the inner expressions:

var injected = new SwapVisitor(fx.Parameters[0], @new.Body).Visit(fx.Body);
var combined = Expression.Lambda<Func<object, object>>(injected,@new.Parameters);

with:

class SwapVisitor : ExpressionVisitor {
    private readonly Expression from, to;
    public SwapVisitor(Expression from, Expression to) {
        this.from = from;
        this.to = to;
    }
    public override Expression Visit(Expression node) {
        return node == from ? to : base.Visit(node);
    }
}

what this does is:

  • inspect the fx.Body tree, replacing all instances of _ (the parameter) with the @new.Body (note that this will contain references to the o parameter (aka p)
  • we then build a new lambda from the replaced expression, re-using the same parameters from @new, which ensures that the values we injected will be bound correctly

这篇关于从其他两个(链接表达式)创建动态表达式lambda的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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