ExpressionVisitor 未访问派生 class 的重写 属性

ExpressionVisitor not visiting overridden property of a derived class

我正在尝试使用 ExpressionVisitor 来获取表达式的重写成员,但它给了我 base 一个。我在这里错过了什么?

以下示例重现此行为:

简单的基本类型和派生类型:

class Base
{
    public virtual string Property { get; set; }
}

class Derived : Base
{
    public override string Property { get; set; }
}

我用这个表达访问者:

internal class DemoVisitor : ExpressionVisitor
{
    private MemberInfo _member;

    public static MemberInfo GetMemberInfo(LambdaExpression expression)
    {
        var visitor = new DemoVisitor();
        visitor.Visit(expression);

        return visitor._member;
    }

    protected override Expression VisitMember(MemberExpression node)
    {
        // invalid member here
        //node.Member.DeclaringType.Name.Dump();
        _member = _member ?? node.Member;

        return base.VisitMember(node);
    }
}

这么叫

void Main()
{
    var derived = new Derived();
    var expression = (Expression<Func<string>>)(() => derived.Property);
    DemoVisitor.GetMemberInfo(expression).DeclaringType.Name.Dump();
}

这个returns Base 而不是Derived。我必须做什么才能到达被覆盖的成员?

我需要它,因为我稍后会阅读它的属性,它目前在基础 class 而不是派生的 属性 上为我提供 属性 的属性。

如果您想知道成员的 class/struct 的类型,您需要查看 MemberExpression 的表达式 属性,它是包含对象的表达式成员 - 在你的例子中是 derived 变量 - 并获取它的类型。

因此您的访问者需要 return 两者(这里我使用了 ValueTuple):

internal class DemoVisitor : ExpressionVisitor
{
    private Type type;
    private MemberInfo _member;

    public static (Type, MemberInfo) GetMemberInfo(LambdaExpression expression)
    {
        var visitor = new DemoVisitor();
        visitor.Visit(expression);

        return (visitor.type, visitor._member);
    }

    protected override Expression VisitMember(MemberExpression node)
    {
        if (_member == null)
        {
          _member = node.Member;
          type = node.Expression.Type;
        }

        return base.VisitMember(node);
    }
}

关于您关于哪个成员被访问的其他问题:表达式中所有使用的成员都被访问,即所有方法、属性和字段,而 node.Member return 是 MethodInfo, PropertyInfoFieldInfo 对象,它们都派生自 MemberInfo.