表达式树复制或转换

如何转换表单的ExpressionTree

Expression<Func> exp = p => p.Age > 50; 

 Expression<Func> exp2 = p => p.Age > 50; 

其中POCO1和POCO2是C#对象,并且都具有Int32 Age属性

好吧,您可以创建将替换参数引用和修补程序成员访问表达式的自定义表达式访问者

 class Converter { class ConversionVisitor : ExpressionVisitor { private readonly ParameterExpression newParameter; private readonly ParameterExpression oldParameter; public ConversionVisitor(ParameterExpression newParameter, ParameterExpression oldParameter) { this.newParameter = newParameter; this.oldParameter = oldParameter; } protected override Expression VisitParameter(ParameterExpression node) { return newParameter; // replace all old param references with new ones } protected override Expression VisitMember(MemberExpression node) { if (node.Expression != oldParameter) // if instance is not old parameter - do nothing return base.VisitMember(node); var newObj = Visit(node.Expression); var newMember = newParameter.Type.GetMember(node.Member.Name).First(); return Expression.MakeMemberAccess(newObj, newMember); } } public static Expression> Convert( Expression> e ) { var oldParameter = e.Parameters[0]; var newParameter = Expression.Parameter(typeof(TTo), oldParameter.Name); var converter = new ConversionVisitor(newParameter, oldParameter); var newBody = converter.Visit(e.Body); return Expression.Lambda>(newBody, newParameter); } } class A { public int Value { get; set; } } class B { public int Value { get; set; } } Expression> f = x => x.Value; var f2 = Converter.Convert(f); 

粗略步骤:


   获取表达式将其转换为BinaryExpression 
   获取左操作数将其转换为MemberExpression 
   获取属性所属的基础类型  
   如果可以,将其更改为新类型。 

你猜到的这种类型是没有二传手的属性。

 Expression> exp1 = o => this.ActualHeight>50; var type = ((MemberExpression)((BinaryExpression)exp1.Body).Left).Expression.Type; 

所以你必须建立一个新的表达式

这是方法

手动为x => x.Child == itemToCompare.Child构建linq表达式

理想情况下 – 你没有。 创建一个描述Age属性的接口,并构建表达式以引用 。 如果您无法修改POCO类型,请使用Go这样的语言,其中接口是隐式的:-)。