¿Cómo obtener propiedades base y campos con valores usando la reflexión para trabajar en la jerarquía de clases?

¿Cómo puedo obtener propiedades y campos de clase base usando la reflexión, de modo que pueda subir la jerarquía de clases un nivel a la vez? El objetivo es construir una visualización de árbol que muestre propiedades y campos con valores de cualquier instancia de clase, al igual que la ventana Locales del depurador. Necesito la capacidad de cargar de forma diferida cada instancia base, de modo que cuando se expande un nodo de árbol "base", esas propiedades y campos con valores se pueden mostrar a pedido.

preguntado el 02 de julio de 12 a las 01:07

1 Respuestas

Aquí hay un ejemplo simple que hace lo que especificó. Estoy seguro de que puede modificar esto según sus necesidades específicas o al menos lo orientará en la dirección correcta.

Puede copiar y pegar este ejemplo en una aplicación de consola y establecer algunos puntos de interrupción para ver cómo funciona.

El código en 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

El mismo código en 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;
}

Respondido 09 Jul 12, 17:07

Gracias por el ejemplo, me di cuenta de que simplemente necesitaba usar BaseType. - Juan_Sheares

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.