LambdaExpression为重写属性获取了不正确的DeclaringType

时间:2018-11-27 16:25:30

标签: c# linq lambda expression

我有以下课程:

public class Foo
{
    public virtual string FooProperty { get; set; }
}
public class Bar : Foo
{
    public override string FooProperty { get => base.FooProperty; set => base.FooProperty = value; }
}

我定义了一个lambda表达式:

Expression<Func<Bar, string>> expression = (Bar b) => b.FooProperty;

当我检查MemberExpression的DeclaringType时,得到的类型为Foo,而不是我期望的Bar。为什么会这样?

var type = (expression.Body as MemberExpression).Member.DeclaringType;   // returns Foo type

1 个答案:

答案 0 :(得分:2)

所以这是一个棘手的问题。从技术上讲,Bar 声明一个属性,该属性称为FooProperty。我们可以通过获取Type中的Bar,获取FooProperty信息并打印声明类型来看到这一点。

var prop = typeof(Bar).GetProperty("FooProperty");
Console.WriteLine(prop.DeclaringType);

那个将打印出Bar,而不是Foo。因此Bar声明了一个属性,但是,您在Foo中显示的代码的结果是FooBar都声明了一个属性称为FooProperty,但是在调用站点上实际上并没有调用Bar.FooProperty,而是调用基类型的版本,并让虚拟调度处理以确保 Bar声明的属性< / em>是两个声明的属性中实际执行的一个。这意味着被称为的属性的声明类型(当您从表达式获取成员信息而不是像我上面那样从类型导航时,这就是您要计算的) Foo,即使两种类型都声明了名为FooProperty的属性。