Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LambdaExpression gets incorrect DeclaringType for overriden property

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
like image 244
Torbjörn Hansson Avatar asked Feb 17 '26 21:02

Torbjörn Hansson


1 Answers

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.

like image 99
Servy Avatar answered Feb 20 '26 09:02

Servy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!