Results 1 to 7 of 7

Thread: [RESOLVED] Reflection getting property names returns base class properties last

  1. #1

    Thread Starter
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    24,033

    Resolved [RESOLVED] Reflection getting property names returns base class properties last

    Iím using reflection to get the properties from 10 concrete classes that either directly or through inheritance, implement an interface. The properties are returned with the sub type properties listed first. Is there any way to reverse that, so the super type properties are listed first followed by the sub type properties?

  2. #2
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    107,130

    Re: Reflection getting property names returns base class properties last

    The properties are always going to come back that way because that's how the Type class is implemented. GetProperties will return properties declared in the specific type under investigation first, then it's direct base class, then the base class of that and so on. If you want to access them in a different order then you need to either call GetProperties multiple times with different BindingFlags values or else sort the result from a single call to GetProperties. Here are some examples:
    vb.net Code:
    1. Module Module1
    2.  
    3.     Sub Main()
    4.         Dim gc As New Grandchild
    5.         Dim gcType = gc.GetType()
    6.         Dim properties = gcType.GetProperties()
    7.  
    8.         For Each propertyInfo In properties
    9.             Console.WriteLine($"{propertyInfo.DeclaringType.Name}.{propertyInfo.Name}")
    10.         Next
    11.     End Sub
    12.  
    13. End Module
    14.  
    15. Public Class Parent
    16.  
    17.     Public Property A As String
    18.     Public Property D As String
    19.  
    20. End Class
    21.  
    22. Public Class Child
    23.     Inherits Parent
    24.  
    25.     Public Property B As String
    26.     Public Property E As String
    27.  
    28. End Class
    29.  
    30. Public Class Grandchild
    31.     Inherits Child
    32.  
    33.     Public Property C As String
    34.     Public Property F As String
    35.  
    36. End Class
    Output:
    Grandchild.C
    Grandchild.F
    Child.B
    Child.E
    Parent.A
    Parent.D
    vb.net Code:
    1. Dim gc As New Grandchild
    2. Dim gcType = gc.GetType()
    3. Dim properties = gcType.GetProperties().OrderBy(Function(pi) If(pi.DeclaringType Is pi.ReflectedType, 1, 0))
    4.  
    5. For Each propertyInfo In properties
    6.     Console.WriteLine($"{propertyInfo.DeclaringType.Name}.{propertyInfo.Name}")
    7. Next
    Output:
    Child.B
    Child.E
    Parent.A
    Parent.D
    Grandchild.C
    Grandchild.F
    Note that, in this case, inherited properties are listed first and directly declared properties are listed last, but properties declared in the direct base class are still listed before those in base classes further up the hierarchy. If that's OK then this is all you need. If you want to fully reverse the order then you'll need a bit more than that. This will do the job:
    vb.net Code:
    1. Imports System.Reflection
    2. Imports System.Runtime.CompilerServices
    3.  
    4. Module Module1
    5.  
    6.     Sub Main()
    7.         Dim gc As New Grandchild
    8.         Dim gcType = gc.GetType()
    9.         Dim properties = gcType.GetProperties().OrderByDescending(Function(pi) pi.GetDeclarationDepth())
    10.  
    11.         For Each propertyInfo In properties
    12.             Console.WriteLine($"{propertyInfo.DeclaringType.Name}.{propertyInfo.Name}")
    13.         Next
    14.     End Sub
    15.  
    16. End Module
    17.  
    18. Public Module PropertyInfoExtensions
    19.  
    20.     <Extension>
    21.     Public Function GetDeclarationDepth(source As PropertyInfo) As Integer
    22.         Dim derivedType = source.ReflectedType
    23.         Dim baseType = source.DeclaringType
    24.         Dim depth = 0
    25.  
    26.         Do Until derivedType Is baseType
    27.             depth += 1
    28.             derivedType = derivedType.BaseType
    29.         Loop
    30.  
    31.         Return depth
    32.     End Function
    33.  
    34. End Module
    Output:
    Parent.A
    Parent.D
    Child.B
    Child.E
    Grandchild.C
    Grandchild.F

  3. #3
    PowerPoster ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    2,815

    Re: Reflection getting property names returns base class properties last

    nice Jmc
    any way to tell which User has those classes in use? probably just with a UserClass
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  4. #4

    Thread Starter
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    24,033

    Re: Reflection getting property names returns base class properties last

    Your GetDeclarationDepth extension was very useful. Thanks

  5. #5

    Thread Starter
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    24,033

    Re: [RESOLVED] Reflection getting property names returns base class properties last

    Virtual Rep only at the moment

  6. #6
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    107,130

    Re: [RESOLVED] Reflection getting property names returns base class properties last

    Quote Originally Posted by .paul. View Post
    Virtual Rep only at the moment
    I accept chocolate in lieu. You can email it and I'll 3d-print it.

  7. #7
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    107,130

    Re: Reflection getting property names returns base class properties last

    Quote Originally Posted by ChrisE View Post
    nice Jmc
    any way to tell which User has those classes in use? probably just with a UserClass
    I can't imagine how that would be possible through simple Framework functionality. You're talking about IPC, for one thing.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width