I have following classes:
public class Foo
{
public virtual string FooProperty { get; set; }
}
public class Bar : Foo
{
public override string FooProperty { get => base.FooProperty; set => base.FooProperty = value; }
}
I define a lambda expression:
Expression<Func<Bar, string>> expression = (Bar b) => b.FooProperty;
When I check the DeclaringType of the MemberExpression I get type Foo and not Bar like I expected. Why is this?
var type = (expression.Body as MemberExpression).Member.DeclaringType; // returns Foo type
So this is a tricky one. Technically Bar is declaring a property, and that property is called FooProperty. We can see this by getting the Type of Bar, getting it's FooProperty info and printing its declaring type.
var prop = typeof(Bar).GetProperty("FooProperty");
Console.WriteLine(prop.DeclaringType);
That will print out Bar, not Foo. So Bar is declaring a property, but, the reason the code you showed results in Foo is that both Foo and Bar declare a property called FooProperty, but on the call site it's not actually calling Bar.FooProperty, it's calling out to the base type's version and letting virtual dispatch handle ensuring that the property that Bar declared is the one that actually executes, of the two declared properties. This means that the declaring type of the property that is called (which is what you're computing when you get the member info from the expression, rather than from navigating the type, as I did above) is Foo, even though both types have declared a property called FooProperty.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With