1

我正在尝试使用ExpressionVisitor来获取表达式的覆盖成员,但它给了我基本的成员。我在这里想念什么?

以下示例重现了此行为:

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

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. 我必须做什么才能找到被覆盖的成员?

我需要它,因为我稍后会读取它的属性,并且它目前正在给我基类而不是派生的属性的属性。

4

1 回答 1

1

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

因此,您的访问者需要返回两者(这里我使用了 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 返回一个或对象MethodInfo,它们都派生自.PropertyInfoFieldInfoMemberInfo

于 2018-10-14T13:25:06.120 回答