lundi 14 octobre 2019

What is the precise meaning of MemberInfo.DeclaringType and why is it inconsistent between reflection through expressions or without them?

Extracting PropertyInfo seems to yield inconsistent results depending on the strategy used. Here is an example of the issue I'm running into: let's define this simple class hierarchy.

abstract class Top { public abstract int Count { get; set; } }
class BelowTop : Top { public override int Count { get; set; } }

I try to extract the property Count using reflection:

var info1 = typeof(BelowTop).GetProperty("Count");
Console.WriteLine("{0} -> {1}", info1.DeclaringType.Name, info1);
// BelowTop -> Int32 Count

... which tells me that the type actually declaring Count is the concrete class BelowTop.

If I now try to extract this information from an expression:

Expression<Func<BelowTop, int>> lambda = b => b.Count;
var info2 = ((MemberExpression)lambda.Body).Member;
Console.WriteLine("{0} -> {1}", info2.DeclaringType.Name, info2);
// Top -> Int32 Count

... reflection suddenly disagrees on the DeclaringType of what should be the same property.

If I add yet another layer I keep getting the same results:

class Bottom : BelowTop { }
var info3 = typeof(Bottom).GetProperty("Count");
Console.WriteLine("{0} -> {1}", info3.DeclaringType.Name, info3);
// BelowTop -> Int32 Count
Expression<Func<Bottom, int>> lambda2 = b => b.Count;
var info4 = ((MemberExpression)lambda2.Body).Member;
Console.WriteLine("{0} -> {1}", info4.DeclaringType.Name, info4);
// Top -> Int32 Count

Is that a bug? If not what is the logic behind this ? How can I compare both PropertyInfos if I don't want to care about this difference?





Aucun commentaire:

Enregistrer un commentaire