LambdaExpression получает неправильный DeclaringType для переопределенного свойства - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть следующие классы:

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

Я определяю лямбда-выражение:

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

Когда я проверяю DeclaringType для MemberExpression, я получаю тип Foo, а не Bar как я и ожидал.Почему это?

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

1 Ответ

0 голосов
/ 27 ноября 2018

Так что это сложно.Технически Bar является объявлением свойства, и это свойство называется FooProperty.Мы можем убедиться в этом, получив Type из Bar, получив FooProperty информацию и напечатав его декларирующий тип.

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

То, что будетраспечатайте Bar, а не Foo.Таким образом, Bar объявляет свойство, но причина, по которой код, показанный вами, приводит к Foo, заключается в том, что Foo и Bar объявляют свойство с именем FooProperty, но при вызовеsite, он на самом деле не вызывает Bar.FooProperty, он вызывает версию базового типа и позволяет виртуальной диспетчеризации обрабатывать, гарантируя, что свойство, объявленное Bar , является тем, которое фактически выполняется, из двух объявленных свойств.Это означает, что объявление типа свойства, которое называется (это то, что вы вычисляете, когда получаете информацию об элементе из выражения, а не от навигации по типу, как я делал выше): Foo, хотя оба типа объявили свойство с именем FooProperty.

...