重建表达 [英] Rebuild Expression
问题描述
我有一个表达式: Expression< Func< TheObject,int,bool>> myExpression =(myObj,theType)=> {myObj.Prop>我需要动态地将myExpression重建为一个新的表达式,类型为
Expression< Func< TheObject,bool> ;>
并用具体值123替换第一个表达式中的typeType参数,如:
Expression< Func< TheObject,bool>>> myNewExpression = myObj => {myObj.Prop> 123};
我该怎么做?
Br
Philip
使用简单的表达式替换器很容易:
这是我为自己写的一个...支持简单的替换和多个替换。
使用系统;
使用System.Collections.Generic;
使用System.Linq.Expressions;
//一个简单的表达式访问者用一些其他节点替换一个表达式
//的一些节点。可以使用任何东西,不仅与
// ParameterExpression
public class SimpleExpressionReplacer:ExpressionVisitor
{
public readonly Dictionary< Expression,Expression>取代;
public SimpleExpressionReplacer(Expression from,Expression to)
{
替换=新字典<表达式,表达式> { { 从到 } };
}
public SimpleExpressionReplacer(字典<表达式,表达式>替换)
{
//请注意,我们应该真正从...复制...但是我们将
//忽略这个!
替换=替换;
}
public SimpleExpressionReplacer(IEnumerable< Expression> from,IEnumerable< Expression> to)
{
替换=新词典< Expression,Expression>();
使用(var enu1 = from.GetEnumerator())
使用(var enu2 = to.GetEnumerator())
{
while(true)
{
bool res1 = enu1.MoveNext();
bool res2 = enu2.MoveNext();如果(!res1 ||!res2)
if(!res1&
}
if(!res1)
{
throw new ArgumentException(from short);
}
throw new ArgumentException(to short);
}
Replaces.Add(enu1.Current,enu2.Current);
}
}
}
public override表达式访问(表达式节点)
{
表达式;
if(node!= null&&& Replaces.TryGetValue(node,out to))
{
return base.Visit(to);
}
return base.Visit(node);
}
}
您的TheObject
public class TheObject
{
public int Prop {get;组; }
}
然后你只需要替换表达式正文中的第二个参数并重建 Expression<>
public class Program
{
public static void Main(string [] args)
{
表达式< Func< TheObject,int,bool>> myExpression =(myObj,theType)=> myObj.Prop>方式;
int value = 123;
var body = myExpression.Body;
var body2 = new SimpleExpressionReplacer(myExpression.Parameters [1],Expression.Constant(value))。
表达式< Func< TheObject,bool>> myExpression2 = Expression.Lambda< Func< TheObject,bool>>(body2,myExpression.Parameters [0]);
}
}
I have an expression like: Expression<Func<TheObject, int, bool>> myExpression = (myObj, theType) => { myObj.Prop > theType };
I need to dynamically rebuild myExpression to a new expression of type Expression<Func<TheObject, bool>>
and replace "theType" parameter from the first expression with a concrete value 123 like:
Expression<Func<TheObject, bool>> myNewExpression = myObj => { myObj.Prop > 123 };
How can I do that? Br Philip
With a simple expression replacer it is quite easy:
This is the one I've written for myself... supports simple replaces and multiple replaces.
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
// A simple expression visitor to replace some nodes of an expression
// with some other nodes. Can be used with anything, not only with
// ParameterExpression
public class SimpleExpressionReplacer : ExpressionVisitor
{
public readonly Dictionary<Expression, Expression> Replaces;
public SimpleExpressionReplacer(Expression from, Expression to)
{
Replaces = new Dictionary<Expression, Expression> { { from, to } };
}
public SimpleExpressionReplacer(Dictionary<Expression, Expression> replaces)
{
// Note that we should really clone from and to... But we will
// ignore this!
Replaces = replaces;
}
public SimpleExpressionReplacer(IEnumerable<Expression> from, IEnumerable<Expression> to)
{
Replaces = new Dictionary<Expression, Expression>();
using (var enu1 = from.GetEnumerator())
using (var enu2 = to.GetEnumerator())
{
while (true)
{
bool res1 = enu1.MoveNext();
bool res2 = enu2.MoveNext();
if (!res1 || !res2)
{
if (!res1 && !res2)
{
break;
}
if (!res1)
{
throw new ArgumentException("from shorter");
}
throw new ArgumentException("to shorter");
}
Replaces.Add(enu1.Current, enu2.Current);
}
}
}
public override Expression Visit(Expression node)
{
Expression to;
if (node != null && Replaces.TryGetValue(node, out to))
{
return base.Visit(to);
}
return base.Visit(node);
}
}
Your TheObject
public class TheObject
{
public int Prop { get; set; }
}
Then you only need to replace the 2nd parameter in the body of the expression and rebuild the Expression<>
public class Program
{
public static void Main(string[] args)
{
Expression<Func<TheObject, int, bool>> myExpression = (myObj, theType) => myObj.Prop > theType;
int value = 123;
var body = myExpression.Body;
var body2 = new SimpleExpressionReplacer(myExpression.Parameters[1], Expression.Constant(value)).Visit(body);
Expression<Func<TheObject, bool>> myExpression2 = Expression.Lambda<Func<TheObject, bool>>(body2, myExpression.Parameters[0]);
}
}
这篇关于重建表达的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!