故如虹,知恩;故如月,知明
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
欢迎加群交流技术

Expression表达式树类型转换

5023人阅读 2021/10/14 22:06 总访问:3840111 评论:0 收藏:0 手机
分类: .NET

问题描述:
Expression<Func<AClass,bool>> expression 如何转成Expression<Func<BClass,bool>> expression 其中类型的属性相同。

解决方法:
使用ExpressionVisitor,去遍历表达式树,然后重建目标类型的表达式

效果如下,可以把Expression<Func<AClass,bool>> 转换成Expression<Func<BClass,bool>>:


代码如下:
测试代码:

public class AClass
{

}

public class BClass
{

}

class Program2
{
    static void Main(string[] args)
    {
        Expression<Func<AClass, bool>> expression = a => true;

        AJExpressionVisitor<BClass> ufExpressionVisitor = new AJExpressionVisitor<BClass>();

        Expression<Func<BClass, bool>> lamdba =
            ufExpressionVisitor.Modify(expression) as Expression<Func<BClass, bool>>;

        Test(lamdba);

    }

    public static void Test(Expression<Func<BClass, bool>> expression)
    {
        //解析.....
    }
}

转换类:

/// <summary>
/// 转换类
/// </summary>
public class AJExpressionVisitor<X> : ExpressionVisitor
{
    /// <summary>
    /// 替换参数
    /// </summary>
    public ParameterExpression pe { get; set; }

    public AJExpressionVisitor()
    {
        var parameter = Expression.Parameter(typeof(X), "a");
        this.pe = parameter;
    }

    /// <summary>
    /// 修改表达式
    /// </summary>
    /// <param name="expression">待修改的表达式</param>
    /// <returns>修改后的表达式</returns>
    public Expression Modify(Expression expression)
    {
        return this.Visit(expression);
    }

    protected override Expression VisitLambda<T>(Expression<T> node)
    {
        return Expression.Lambda(Traverse(node.Body), pe);
    }

    /// <summary>
    /// 遍历转换表达式
    /// </summary>
    /// <param name="expression">表达式</param>
    /// <returns>转换后的表达式</returns>
    private Expression Traverse(Expression expression)
    {
        //二无表达式的处理
        if (expression is BinaryExpression)
        {
            var left = Traverse((expression as BinaryExpression).Left);
            var right = Traverse((expression as BinaryExpression).Right);
            return Expression.MakeBinary((expression as BinaryExpression).NodeType, left, right);
        }
        //成员表达式的处理
        if (expression is MemberExpression)
        {
            MemberExpression me = Expression.Property(pe, (expression as MemberExpression).Member.Name);
            return me;
        }
        //常量表达式的处理
        if (expression is ConstantExpression)
        {
            return expression;
        }
        //方法调用表达式的处理
        if (expression is MethodCallExpression)
        {
            var mcExpression = expression as MethodCallExpression;
            var body = Traverse(mcExpression.Object);

            return Expression.Call(body, mcExpression.Method, mcExpression.Arguments);
        }
        return expression;
    }
}


欢迎加群讨论技术,群:677373950(满了,可以加,但通过不了),2群:656732739

评价