Objetos anónimos como diccionarios

Publicado 26/5/2009 17:27 por Eduard Tomàs i Avellana

¡Hola!

Cada vez más existen frameworks y librerías que permiten usar objetos anónimos como si de diccionarios se tratase. Esto es muy cómodo porque permite realizar llamadas tal y como:

Foo(new { x = 10, y = 20, Data = "Data" });

Por ejemplo, en ASP.NET MVC no se paran de hacer llamadas parecidas a esta…

Internamente el método Foo utilizará reflection para iterar sobre las propiedades del objeto anónimo que recibe y obtener los datos.

Si tenéis varios métodos que trabajan con IDictionary<string, T> y queréis que se puedan llamar fácilmente usando esta técnica podéis crear un método extensor de IDictionary<string, T> que rellene un diccionario a partir de las propiedades de un objeto… De acuerdo, vuestros métodos no serán invocables directamente pasándoles un objeto anónimo pero al menos los diccionarios se crearán mucho más fácilmente.

Si estáis vagos aquí tenéis un código que uso yo para esto:

public static class DictionaryStringStringExtensions
{
    public static IDictionary<string, T>  FillFromObject<T>(
        this IDictionary<string, T> dictionary,
        object values)
    {
        if (values == null) return dictionary;

        Type type = values.GetType();
        foreach (var property in type.GetProperties())
        {
            if (!dictionary.ContainsKey(property.Name))
            {
                object propValue = property.GetValue(values, null);
                T finalValue = default(T);
                if (property.PropertyType.Equals(typeof(T)))
                {
                    finalValue = (T)property.GetValue(values, null);
                }
                else
                {
                    finalValue = (T)Convert.ChangeType (propValue, 
                        typeof(T),  CultureInfo.CurrentCulture);
                }
                dictionary.Add(property.Name, finalValue);
            }
        }

        return dictionary;
    }
}

El método realiza conversiones básicas entre tipos de propiedades… Así podeis inicializar fácilmente vuestros diccionarios:

var d = new Dictionary<string, int>();
d.FillFromObject(new { col = "10", row = 20.2 });

Saludos!

Archivado en:
Comparte este post:

Comentarios

# re: Objetos anónimos como diccionarios

Tuesday, May 26, 2009 9:44 PM by Santiago

Hola Eduard,

Muy bueno el post. Una posibilidad interesante es cambiar el objeto sobre el que se define el extension method, para que sea directamente el object en lugar del dictionary.

Asi, se podria tener un extension AsDictionary(), aplicable sobre cualquier Object, que internamente instancia un nuevo Dictionary y efectua la misma logica que el FillFromObject.

Todo esto suponiendo que no te molesta la intellisense sobre cualquier Object, en cualquier caso se lo puede marcar con el atributo EditorBrowsable para que no moleste.

Saludos!

# re: Objetos anónimos como diccionarios

Wednesday, May 27, 2009 3:03 PM by Eduard Tomàs i Avellana

Hola Santiago,

Gracias por tus comentarios :)

El enfoque que tu propones, se parece en cierto modo a lo que han hecho con LINQ con el método extensor AsEnumerable() que te permite obtener un IEnumerable<T> a partir de ciertos objetos (p.ej. un DataTable) y así poder usar LINQ sobre estos objetos...

De todos modos, y ahora hablo sin probar, creo que si ponemos el método AsEnumerable<T>() en un objeto, siempre deberás especificar el parámetro genérico T, ya que el compilador no podrá inferirlo nunca. En el caso de FillFromObject<T> el compilador puede inferir el valor de T a partir del diccionario sobre el cual se usa el método.

Vamos, que en el caso de AsDictionary<T> deberías hacer algo así como:

var d = foo.AsDictionary<double>(); // d será un IDictionary<string, double>

Aunque quizá esto tambien sea lo que se busque, claro ;-)

Saludos!