none
Obtener árbol de clases por reflexión RRS feed

  • Pregunta

  • Hola, 

    Estoy realizando una aplicación para gestionar ciertos parámetros de configuración, y para ello quiero obtener la descripción de todas las clases, sus herencias y sus métodos. 

    Con las interfaces no tengo problemas, pero cuando quiero obtener la clase base de otra no lo consigo. Este es mi escenario:

    Tengo estas dos clases:

        public class DataModel : BaseModel
        {
            public string Nombre { get; set; }
            public string Apellido { get; set; }
        }
    
        public class BaseModel
        {
            public int Id { get; set; }
        }

    Al consultar DataModel, quiero obtener de alguna manera que hereda de BaseModel (para después obtener también sus propiedades). He probado con Type baseType = t.BaseType pero me devuelve un System.Object haciendo referencia a mscorlib.

    ¿Como puedo obtener BaseModel desde DataModel?

    Un saludo,

    miércoles, 1 de noviembre de 2017 10:38

Respuestas

Todas las respuestas

  • Esta bien como lo tienes, BaseType te devuelve la clase inmediata desde la que heredas. Si no funciona, debe haber algun error por otro sitio, por ejemplo, que la "t" en realidad no se refiera a DataModel sino a BaseModel.

    En la documentacion viene un ejemplo muy claro que puedes copiar y probar:

    https://msdn.microsoft.com/en-us/library/system.type.basetype(v=vs.110).aspx

    miércoles, 1 de noviembre de 2017 13:19
    Moderador
  • Hola Alberto, 

    He probado el ejemplo y me he dado cuenta de que el comportamiento es diferente según la forma de cargar los tipos, es decir:

    Con el ejemplo del link que has puesto:

                 foreach (var t in typeof(DataModel).Assembly.GetTypes())
                {
                    Console.WriteLine("{0} derived from: ", t.FullName);
                    var derived = t;
                    do
                    {
                        derived = derived.BaseType;
                        if (derived != null)
                            Console.WriteLine("   {0}", derived.FullName);
    
                    } while (derived != null);
                    Console.WriteLine();
                }

    El resultado es el esperado (he quitado la parte de Forms):

    WindowsFormsApplication1.DataModel derived from: 
       WindowsFormsApplication1.BaseModel
       System.Object
    
    WindowsFormsApplication1.BaseModel derived from: 
       System.Object

    En cambio, si el assembly le cargamos dinámicamente (que es como lo estoy haciendo):

                string path = @".\WindowsFormsApplication1.exe";
                Assembly assembly = Assembly.LoadFrom(path);
                foreach (var t in assembly.GetTypes())
                {
                    Console.WriteLine("{0} derived from: ", t.FullName);
                    var derived = t;
                    do
                    {
                        derived = derived.BaseType;
                        if (derived != null)
                            Console.WriteLine("   {0}", derived.FullName);
    
                    } while (derived != null);
                    Console.WriteLine();
                }

    El resultado no devuelve el tipo derivado BaseModel:

    WindowsFormsApplication1.DataModel derived from: 
       System.Object

    Como el objetivo de la herramienta es cargar todos los tipos no me valdría.

    Un saludo,

    miércoles, 1 de noviembre de 2017 16:44
  • Investigando un poco por la Red he visto que varios posts indican que Assembly.LoadFrom no realiza la carga en el contexto predeterminado, dando lugar a diversos problemas como por ejemplo el que estás viendo. Recomiendan que en su lugar se use Assembly.Load.

    https://docs.microsoft.com/en-us/dotnet/framework/debug-trace-profile/loadfromcontext-mda

    http://geekswithblogs.net/rupreet/archive/2010/02/16/137988.aspx

    miércoles, 1 de noviembre de 2017 18:33
    Moderador