我正在开发一个自定义序列化程序,我的边缘案例测试揭示了一个有趣的问题:Type.GetProperties
方法不会从相同签名的基类中返回重新引入的属性。虽然这对于重写属性是预期的,但我必须序列化非虚拟基本属性。
考虑以下示例:
public class Base
{
public int NonvirtualProperty { get; set; } // this property is "lost"
public virtual int VirtualProperty { get; set; }
public int BaseOnlyProperty { get; set; }
}
public class Derived : Base
{
public int NonvirtualProperty { get; set; }
public override int VirtualProperty { get; set; }
public int DerivedOnlyProperty { get; set; }
}
下面的测试演示了该问题:
foreach (var p in typeof(Derived).GetProperties(BindingFlags.Public | BindingFlags.Instance))
Console.WriteLine($"{p.DeclaringType.Name}.{p.Name}");
// Derived.NonvirtualProperty
// Derived.VirtualProperty
// Derived.DerivedOnlyProperty
// Base.BaseOnlyProperty
我希望结果也Base.NonvirtualProperty
。
注意:对于字段和方法,一切正常。这对于方法尤其有趣,因为它们也可以是虚拟的。
注意2::如果Base
和Derived
中的属性类型不同,则基本属性会出现在结果中。
什么是最好,最有效的解决方案?
到目前为止,我的想法(对于处理这种极端情况,它们都显得太丑陋和过于复杂):
DeclaredOnly
绑定标志来获取每个级别的属性,并以某种方式检测它们是非虚拟属性还是虚拟属性的最衍生属性。有没有一种干净的方法可以做到这一点?get_*
/ set_*
方法是否真的是属性。答案 0 :(得分:0)
Imho无法仅通过反映派生类型来获取隐藏的基本属性。遍历继承链应该可以解决问题。
编辑:该问题似乎与Property hiding and reflection (C#)类似 还有一个很好的示例,说明如何使用较少的代码进行遍历,请参阅https://stackoverflow.com/a/2715286/7895292
答案 1 :(得分:-1)
那是因为Derived.NonvirtualProperty
隐藏了Base.NonvirtualProperty
。就像编译器会说的那样。它会建议“如果打算隐藏则使用new关键字”
不能直接访问的证明:
var d = new Derived();
var b = (Base)d;
b.NonvirtualProperty =10;
Console.WriteLine($"{d.NonvirtualProperty}");
给0