Atajo para instanciar tipos anónimos en C# y VB.NET

Tanto la guía de programación del lenguaje C# 3.0 como la de Visual Basic .NET 9 hablan de que ambos compiladores pueden agilizar la instanciación de tipos anónimos, permitiendo escribir instrucciones realmente concisas, gracias a su capacidad para deducir los nombres de las propiedades a partir de su contexto. Sin embargo son ese tipo de detalles que, al menos un servidor, había pasado por alto a pesar de haberlo visto utilizado más de una vez.

Como sabemos, la creación «normal» de un objeto de tipo anónimo es como sigue, si lo que queremos es inicializar sus propiedades con valores constantes:

  // C#
var o = new { Nombre=»Juan», Edad=23 };

‘ VB.NET
Dim o = New With { .Nombre=»Juan», .Edad=23 }


Sin embargo, muchas veces vamos a inicializar sus miembros con valores tomados de variables o parámetros visibles en el lugar de la instanciación, por ejemplo:

  // C#
public void hacerAlgo(string nombre, int edad)
{
var o = new { nombre=nombre, edad=edad };

}

‘ VB.NET
Public Sub HacerAlgo(ByVal nombre As String, _
ByVal edad As Integer)
Dim o = New With {.nombre = nombre, .edad = edad}

End Sub


Pues bien, es justo en estos casos cuando podemos utilizar una sintaxis más compacta, basada en la capacidad de los compiladores de inferir el nombre de las propiedades del tipo anónimo partiendo de los identificadores de las variables que utilicemos en su inicialización. O en otras palabras, el siguiente código es equivalente al anterior:

  // C#
public void hacerAlgo(string nombre, int edad)
{
var o = new { nombre, edad };

}

‘ VB.NET
Public Sub HacerAlgo(ByVal nombre As String, _
ByVal edad As Integer)
Dim o = New With {nombre, edad}

End Sub



Brad Wilson, un desarrollador del equipo ASP.NET de Microsoft, nos ha recordado hace unos días lo bien que viene este atajo para la instanciación de tipos anónimos utilizados para almacenar diccionarios clave/valor, como los usados en el framework ASP.NET MVC. También es una característica muy utilizada en Linq para el retorno de tipos anónimos que contienen un subconjunto de propiedades de las entidades recuperadas en una consulta.

Publicado en: www.variablenotfound.com.

5 comentarios sobre “Atajo para instanciar tipos anónimos en C# y VB.NET”

  1. Ya que hablas de tipos anónimos te propongo un juego. La pregunta es ¿Como creas un método que permita devolver una lista de un tipo anónimo pasado por parámetro? Es decir, dado
    var tipo = new {ParamA=»Valor»,ParamB=2} como hacer un método que devuelva una lista de estos tipos…

    Unai

  2. ¡Hola, Unai!

    A ver si he entendido bien tu pregunta… se trata de crear un método que, dado un tipo anónimo cualquiera, retorne una lista de dicho tipo, por ejemplo una instancia de un List<tipo>.

    Pues precisamente andaba preparando un futuro post sobre métodos genéricos… 🙂

    El truco es aprovechar la inferencia de tipos en estos métodos, para poder pasarle un anónimo; dado que el compilador sabe en todo momento de qué tipo estamos hablando, no tiene problema en gestionarlo.

    Un poner. Dado este método genérico:

    public List<Tipo> creaLista<Tipo>(Tipo obj)
    {
       return new List<Tipo>();
    }

    Podría usarse así (continuando con tu ejemplo):

    var tipo = new { ParamA = «Valor», ParamB = 2 };
    var listaDeTipos = creaLista(tipo);
    listaDeTipos.Add(tipo);
    listaDeTipos.Add(new { ParamA = «hola», ParamB = 1 });

    En la llamada a creaLista() no es necesario indicar el parámetro genérico, pues el compilador lo deduce del tipo del primer parámetro del método, y éste es el usado para crear la lista que instancia y retorna.

    Obviamente, también podríamos usar el mismo método con un tipo con nombre, como string o int:

    // crea una lista de enteros:
    var listaDeEnteros = creaLista(1);

    listaDeEnteros.Add(2);
    listaDeEnteros.Add(4);

    Saludos y gracias por aportar!

  3. Se que el post ya es un tanto viejo pero es bastante interesante y hace poco tenía la misma duda de Unai.

    Leyendo la solución que das José, aun no veo como develover el objeto listaDeTipos.

    Todo este código está muy bien:

    var tipo = new { ParamA = «Valor», ParamB = 2 };
    var listaDeTipos = creaLista(tipo);
    listaDeTipos.Add(tipo);
    listaDeTipos.Add(new { ParamA = «hola», ParamB = 1 });

    pero no veo como retornar listaDeTipos, de manera que lo pueda utilizar desde otra clase.
    Cómo debería ser la declaración de la función para que devuelva esta lista?

    Yobb

  4. ¡Hola, Yobb!

    El tipo está declarado de forma anónima en ese código, por lo que no podrás utilizarlo fuera de éste, o al menos de forma directa.

    Si quisieras retornar esta lista a un nivel superior supongo deberías retornar un tipo de datos o interfaz más genérico, como IList, u object.

    Saludos.

Responder a unai Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *