John_Sheares
John_Sheares

Reputation: 1414

How to get base properties and fields with values using reflection to work up the class hierarchy?

How can I get base class properties and fields using reflection, so that I can work UP the class hierarchy one level at a time? The goal is to build a tree display showing properties and fields with values of any class instance, just like the debugger Locals window. I need the ability to lazy load each base instance, so that when a "base" tree node is expanded, those properties and fields with values can be shown on demand.

Upvotes: 0

Views: 1257

Answers (1)

Randy Dodson
Randy Dodson

Reputation: 252

Here is a simple example which does what you specified. I’m sure you can modify this to your specific needs or at least it will point you in the right direction.

You can copy and paste this example into a console application and set a few breakpoints to see how it works.

The code in VB.Net

Module Module1

    Private Class ClassOne
        Private _One As String
        Private _Two As Integer
        Private _three As Double

        Public Property One() As String
            Get
                Return _One
            End Get
            Set(ByVal value As String)
                _One = value
            End Set
        End Property

        Public Property Two() As Integer
            Get
                Return _Two
            End Get
            Set(ByVal value As Integer)
                _Two = value
            End Set
        End Property

        Public Property Three() As Double
            Get
                Return _three
            End Get
            Set(ByVal value As Double)
                _three = value
            End Set
        End Property
    End Class

    Private Class ClassAlpha
        Inherits ClassOne

        Private _Alpha As String
        Private _Beta As Long

        Public Property Alpha() As String
            Get
                Return _Alpha
            End Get
            Set(ByVal value As String)
                _Alpha = value
            End Set
        End Property

        Public Property Beta() As Long
            Get
                Return _Beta
            End Get
            Set(ByVal value As Long)
                _Beta = value
            End Set
        End Property
    End Class

    Private Class ClassColor
        Inherits ClassAlpha

        Private _Red As String
        Private _Blue As Long

        Public Property Red() As String
            Get
                Return _Red
            End Get
            Set(ByVal value As String)
                _Red = value
            End Set
        End Property

        Public Property Blue() As Long
            Get
                Return _Blue
            End Get
            Set(ByVal value As Long)
                _Blue = value
            End Set
        End Property
    End Class

    Sub Main()
        Dim o As New ClassColor()
        o.Red = "The Color Red"
        o.Blue = 14
        o.Alpha = "The First"
        o.Beta = 202
        o.One = "One"
        o.Two = 2
        o.Three = 3.1415927

        Dim helper As New ReflectionHelper(o)

        Dim list1 = helper.ReflectProperties(helper.BaseClasses(0), o)
        Dim list2 = helper.ReflectProperties(helper.BaseClasses(1), o)
        Dim list3 = helper.ReflectProperties(helper.BaseClasses(2), o)
    End Sub

End Module

Public Class ReflectionHelper
    Private _SourceClass As Object
    Private _BaseClasses As New List(Of Type)

    Public Sub New()
    End Sub

    Public Sub New(source As Object)
        _SourceClass = source

        Dim t As Type = _SourceClass.GetType()
        While (t IsNot Nothing)
            _BaseClasses.Add(t)
            t = t.BaseType
        End While
    End Sub

    Public ReadOnly Property BaseClasses As List(Of Type)
        Get
            Return _BaseClasses
        End Get
    End Property

    Public Function ReflectProperties(ByVal baseClass As Type,
                                      ByVal instance As Object) As List(Of ReflectionHelperProperties)
        Dim result As New List(Of ReflectionHelperProperties)
        For Each prop In baseClass.GetProperties(Reflection.BindingFlags.DeclaredOnly Or
                                                 Reflection.BindingFlags.GetProperty Or
                                                 Reflection.BindingFlags.Instance Or
                                                 Reflection.BindingFlags.Public)
            result.Add(New ReflectionHelperProperties() With {.Name = prop.Name, .InstanceValue = prop.GetValue(instance, Nothing)})
        Next
        Return result
    End Function
End Class

Public Class ReflectionHelperProperties
    Public Name As String
    Public InstanceValue As Object
End Class

The same code in C#

using System;
using System.Collections.Generic;

namespace ConsoleApplication23
{
    class Program
    {
        static void Main(string[] args)
        {
            // create the highest level type
            ClassColor o = new ClassColor();
            o.Red = "The Color Red";
            o.Blue = 14;
            o.Alpha = "The First";
            o.Beta = 202;
            o.One = "One";
            o.Two = 2;
            o.Three = 3.1415927;

            ReflectionHelper helper = new ReflectionHelper(o);

            List<ReflectionHelperProperties> list1 = helper.ReflectProperties(helper.BaseClasses[0], o);
            List<ReflectionHelperProperties> list2 = helper.ReflectProperties(helper.BaseClasses[1], o);
            List<ReflectionHelperProperties> list3 = helper.ReflectProperties(helper.BaseClasses[2], o);
        }
    }
}

public class ClassOne
{
    private string _One;
    private int _Two;

    private double _three;
    public string One {
        get { return _One; }
        set { _One = value; }
    }

    public int Two {
        get { return _Two; }
        set { _Two = value; }
    }

    public double Three {
        get { return _three; }
        set { _three = value; }
    }
}

public class ClassAlpha : ClassOne
{    
    private string _Alpha;    
    private long _Beta;

    public string Alpha {
        get { return _Alpha; }
        set { _Alpha = value; }
    }

    public long Beta {
        get { return _Beta; }
        set { _Beta = value; }
    }
}

public class ClassColor : ClassAlpha
{    
    private string _Red;    
    private long _Blue;

    public string Red {
        get { return _Red; }
        set { _Red = value; }
    }

    public long Blue {
        get { return _Blue; }
        set { _Blue = value; }
    }
}

public class ReflectionHelper
{
    private List<Type> _BaseClasses = new List<Type>();
    public ReflectionHelper()
    {
    }

    public ReflectionHelper(object source)
    {
        // build base types list
        Type t = source.GetType();
        while ((t != null)) {
            _BaseClasses.Add(t);
            t = t.BaseType;
        }
    }

    public List<Type> BaseClasses {
        get { return _BaseClasses; }
    }

    public List<ReflectionHelperProperties> ReflectProperties(Type baseClass, object instance)
    {
        List<ReflectionHelperProperties> result = new List<ReflectionHelperProperties>();
        foreach (System.Reflection.PropertyInfo p in baseClass.GetProperties(System.Reflection.BindingFlags.DeclaredOnly | 
                                                                             System.Reflection.BindingFlags.GetProperty | 
                                                                             System.Reflection.BindingFlags.Instance | 
                                                                             System.Reflection.BindingFlags.Public)) {
            result.Add(new ReflectionHelperProperties {
                Name = p.Name,
                InstanceValue = p.GetValue(instance, null)
            });
        }
        return result;
    }
}

public class ReflectionHelperProperties
{
    public string Name;
    public object InstanceValue;
}

Upvotes: 2

Related Questions