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
相关产品推荐
相关产品推荐

