mardi 25 septembre 2018

Type.GetProperties does not return non-virtual redefined properties from the base type

I'm working on a custom serializer and my edge case tests revealed an interesting issue: Type.GetProperties method does not return reintroduced properties from the base class of the same signature. While this is expected for overridden properties, I have to serialize non-virtual base properties.

Consider the following example:

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; }
}

The test below demonstrates the issue:

foreach (var p in typeof(Derived).GetMethods(BindingFlags.Public | BindingFlags.Instance))
    Console.WriteLine($"{p.DeclaringType.Name}.{p.Name}");

// Derived.NonvirtualProperty
// Derived.VirtualProperty
// Derived.DerivedOnlyProperty
// Base.BaseOnlyProperty

I would expect also Base.NonvirtualProperty in the result.

Note: For fields and methods everything works as expected. This is especially interesting for methods because they also can be virtual.

Note 2: If property types are different in Base and Derived the base property appears in the result.

What would be the best and most efficient solution?

My ideas so far (both of them seem too ugly and overcomplicated for handling such an edge case):

  • Maybe I could obtain properties of each levels by DeclaredOnly and somehow detect if they are either non-virtual ones or the most derived properties of virtual ones. Is there a clean way to do that?
  • Or I could query the methods instead, and check if the returned get_*/set_* methods are really properties.




Aucun commentaire:

Enregistrer un commentaire