miércoles, 8 de mayo de 2019

HashtableUtil - Pasar una lista tipificada a Hashtable, utilizando Reflection


Lenguaje: C#
Desarrollado para: Aplicación de Consola C#

Clase que permite transformar una lista de valores en Hashtable y todas las listas que tanga asociadas, llamandose recursivamente.


using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;


namespace Util
{
    /// <summary>
    /// Clase que permite transformar un objeto en hashtable
    /// </summary>
    public class HashtableUtil
    {
        /// <summary>
        /// Clase que permite generar un Hashtable de una lista de objetos, por su tipo.
        /// </summary>
        /// <typeparam name="T">Tipo de objeto al que pertenece la lista</typeparam>
        /// <param name="objetos" />
        /// <returns></returns>
        public static Hashtable ObtieneHash<t>(List<t> objetos)
        {
            // obtiene las propiedades del tipo de objeto y las guarda en un arreglo
            PropertyInfo[] props = typeof(T).GetProperties();

            // se ordenan las propiedades por nombre
            Array.Sort(props ,delegate (PropertyInfo propertyInfo1, PropertyInfo propertyInfo2)
            { return propertyInfo1.Name.CompareTo(propertyInfo2.Name); });

            int indexProp = 0;
            // recorre las propiedades, para encontrar el indice de la propiedad "cod_code"
            foreach (PropertyInfo propertyInfo in props)
            {
                if (propertyInfo.Name.ToUpper().Equals("CODCODE")) { break; }
                indexProp++;
            }

            bool usaCorrelativo = false;
            if (indexProp &gt;= props.Length) { usaCorrelativo = true; }


            // se recorre la lista de objetos para guardar los objetos con su codigo asociado
            Hashtable retorno = new Hashtable();
            // indice de las propiedades
            int indice = 0;
            foreach (T obj in objetos)
            {
                //se crean los objetos a utilizar
                Hashtable ht = new Hashtable();
                List<object> lista = new List<object>();

                foreach (PropertyInfo propertyInfo in props)
                {
                    // se obtiene el tipo (type) de la propiedad y se compara con el tipo de la lista
                    Type tipo = ((T)obj).GetType().GetProperty(propertyInfo.Name).PropertyType;
                    if (tipo.Name == lista.GetType().Name)
                    {
                        // si es una lista, se obtiene el valor (T) de la lista
                        Type itemTipo = tipo.GetGenericArguments()[0];
                        // se crea un MethodInfo con el mismo método, pasandole el tipo de la lista
                        MethodInfo mi = typeof(HashtableUtil).GetMethod("ObtieneHash", BindingFlags.Static | BindingFlags.Public);
                        MethodInfo mi2 = mi.MakeGenericMethod(new Type[] { itemTipo });
                        // Invocamos el método con los valores obtenidos de la propiedad
                        ht[propertyInfo.Name] = mi2.Invoke(null, new object[] { ((T)obj).GetType().GetProperty(propertyInfo.Name).GetValue(obj, null) });
                    }
                    else
                    {
                        // si no es una lista, se mete directo el valor del objeto, con su nombre de propiedad.
                        ht[propertyInfo.Name] = ((T)obj).GetType().GetProperty(propertyInfo.Name).GetValue(obj, null);
                    }
                }

                if (usaCorrelativo)
                    retorno[indice.ToString()] = ht;
                else
                {
                    string nombrePropiedad = props[indexProp].Name;
                    // se coloca el código como key en el Hashtable de retorno, asociando su misma hashtable de valores.
                    retorno[((T)obj).GetType().GetProperty(nombrePropiedad).GetValue(obj, null).ToString()] = ht;
                }
                indice++;
            }
            return retorno;

        } 
    }
}

No hay comentarios:

Publicar un comentario