从其他两个(链接表达式)创建动态表达式lambda [英] Create dynamic Expression lambda from two others (chaining the Expressions)
问题描述
表达式< Func<标识,对象>> ; fx = _ => _。ID;
还有一个将对象转换为识别实例的转换lambda:
ParameterExpression p = Expression.Parameter(typeof(object),o);
Expression @new = Expression.Lambda(Expression.Convert(p,typeof(Identification)),p);
如何构建一个执行 @new $ c的新lambda $ c>(取出识别实例),并将结果传递到
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的引用
参数(akap
) - 然后我们从替换的表达式中构建一个新的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 theo
parameter (akap
) - 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屋!