You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何非逆序遍历表达式树以正确获取属性名?

表达式树遍历属性名顺序问题

问题重现

现有以下代码,期望遍历表达式traveler => traveler.Ticket.Number时,控制台按顺序输出Ticket、Number,但实际输出顺序相反:

public class Traveler
{
    public string Name { get; set; }

    public Ticket Ticket { get; set; }
}

public class Ticket
{
    public string Number { get; set; }
}

public void Test()
{
    Expression<Func<Traveler, string>> expr = traveler => traveler.Ticket.Number;

    var visitor = new PropExpressionVisitor();
    visitor.Visit(expr);
}

public class PropExpressionVisitor: ExpressionVisitor
{
    protected override Expression VisitMember(MemberExpression node)
    {
        Console.WriteLine(node.Member.Name);

        return base.VisitMember(node);
    }
}

实际输出:

Number
Ticket

问题原因

ExpressionVisitor的VisitMember方法中,base.VisitMember(node)会优先访问当前MemberExpression的子表达式(即node.Expression)。你的代码先输出当前成员名,再调用基类方法,相当于先处理最内层的属性(Number),再回溯处理上层属性(Ticket),所以顺序是逆的。

对于表达式traveler.Ticket.Number,其表达式树结构是:
MemberExpression(Number) → 子表达式是 MemberExpression(Ticket) → 子表达式是参数traveler

解决方案

调整输出和基类方法调用的顺序:先调用base.VisitMember(node)遍历上层属性,再输出当前成员名。修改后的PropExpressionVisitor如下:

public class PropExpressionVisitor: ExpressionVisitor
{
    protected override Expression VisitMember(MemberExpression node)
    {
        // 先遍历上层属性表达式
        var result = base.VisitMember(node);
        // 再输出当前属性名
        Console.WriteLine(node.Member.Name);
        return result;
    }
}

修改后执行Test方法,控制台会按预期输出:

Ticket
Number

内容的提问来源于stack exchange,提问作者IR Codder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 09:41:29