Property hiding and reflection (C#)

前端 未结 3 902
[愿得一人]
[愿得一人] 2020-12-11 00:53

Declaring a property in a derived class that matches the name of a property in the base class \"hides\" it (unless it overrides it with the override keyword).

相关标签:
3条回答
  • 2020-12-11 01:19

    GetProperties is defined as all public properties of the type.

    You could get their get and set methods using:

    typeof(C).GetMethods()
             .Where(m => m.Name.StartsWith("set_") || m.Name.StartsWith("get_"))
    

    Although this seems like a bad idea, compared to going down the inheritance hierarchy to get the properties.

    0 讨论(0)
  • 2020-12-11 01:19

    I do not think it is possible without traversing the inheritance hierarchy. It does not have to be too much code, though:

        public static IEnumerable<PropertyInfo> GetAllProperties(Type t)
        {
            while (t != typeof(object))
            {
                foreach (var prop in t.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance))
                    yield return prop;
                t = t.BaseType;
            }
        }
    

    Of course, if you know a common basetype you can stop at, instead of object, it will be more efficient. Also; it will take some time to do the reflection, so cache the result. After all, the type information won't change during execution.

    0 讨论(0)
  • 2020-12-11 01:20

    Through reflection, the new keyword only hides the inherited property if the signature matches. I guess reflection matches signatures on property accessors (get_ & set_). It's the reasons why GetProperties() returns B.P and C.P when the return type differ.

    I recently discovered Fasteflect which provides advanced reflection mechanisms.

    I checked and Fasteflect type.Properties returns all the tree of hidden members (P). I think the API consider backing members (virtual/override) and hidden members (new) differently which is a good thing for your 'problem' ;)

    My test with fasterflect :

    class Class1
    {
        public object field1 = null;
    
        public virtual object Property1 { get; set; }
    
        public object Property2 { get; set; }
    
        public string Property3 { get; set; }
    }
    
    class Class2 : Class1
    {
        public new object field1 = null;
    
        public override object Property1 { get; set; }
    
        public new string Property3 { get; set; }
    }
    
    class Class3 : Class2
    {
        public new string Property3 { get; set; }
    }
    

    Filter backing members but returns all hidden members :

    typeof(Class3).Properties(Flags.ExcludeBackingMembers | Flags.Public | Flags.Instance) 
    
    • typeof(Class3).Properties(Flags.ExcludeBackingMembers | Flags.Public | Flags.Instance) Count = 5 System.Collections.Generic.IList
      • [0] {System.String Property3} System.Reflection.PropertyInfo
      • [1] {System.Object Property1} System.Reflection.PropertyInfo
      • [2] {System.String Property3} System.Reflection.PropertyInfo
      • [3] {System.Object Property2} System.Reflection.PropertyInfo
      • [4] {System.String Property3} System.Reflection.PropertyInfo
    0 讨论(0)
提交回复
热议问题