ExpressionVisitor不访问派生类的重写属性

时间:2018-10-14 12:51:17

标签: c# reflection expression-trees

我正在尝试使用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();
}

这将返回Base而不是Derived。我该怎么做才能到达被覆盖的成员?

之所以需要它,是因为我稍后会读取其属性,并且当前正在为我提供基类(而不是派生类)上的属性的属性。

1 个答案:

答案 0 :(得分:1)

如果您想了解成员的类/结构的类型,则需要查看MemberExpression的Expression属性,该属性是包含成员的对象的表达式-在您的情况下,{{ 1}}变量-并获取其类型。

因此,您的访客需要同时返回两者(这里我使用了ValueTuple):

derived

关于访问哪个成员的另一个问题:访问表达式中所有使用过的成员,即所有方法,属性和字段,而node.Member返回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); } } MethodInfo或{ {1}}个对象,这些对象都源自PropertyInfo