【发布时间】:2019-10-14 15:57:46
【问题描述】:
提取PropertyInfo 似乎会产生不一致的结果,具体取决于所使用的策略。这是我遇到的问题的一个示例:让我们定义这个简单的类层次结构。
abstract class Top { public abstract int Count { get; set; } }
class BelowTop : Top { public override int Count { get; set; } }
我尝试使用反射提取属性Count:
var info1 = typeof(BelowTop).GetProperty("Count");
Console.WriteLine("{0} -> {1}", info1.DeclaringType.Name, info1);
// BelowTop -> Int32 Count
...它告诉我实际声明Count 的类型是具体类BelowTop。
如果我现在尝试从表达式中提取此信息:
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
...反射突然不同意 DeclaringType 应该是相同的属性。
如果我再添加一层,我会继续得到相同的结果:
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
这是一个错误吗?如果不是,这背后的逻辑是什么?如果我不想关心这种差异,如何比较 PropertyInfos?
【问题讨论】:
-
Lambda expression not returning expected MemberInfo 的可能重复项。这是“按设计工作”(尽管意见不同),因为 lambda 中的访问确实是通过
Top发生的(因为它调用了一个虚拟方法),而直接从BelowTop获取属性不会遍历层次结构来查看如果它是一个覆盖 - 该属性是在BelowTop上实现的,所以这就是你得到的。
标签: c# reflection