2007-05-21

Generics con tipos anonimos en C# 3.0

Hace unas semanas bajé el Beta 1 de Visual Studio Code Name Orcas, el cual trae soporte para el .NET Framework 3.5 y las herramientas de lenguaje para C# 3.0

Jugando un poco, primero con LINQ y después con los nuevos chiches de los tipos anónimos me encontré con el siguiente problema: pese a que haciendo queries de LINQ los valores de retorno podían venir como un tipo anónimo, yo no podía hacer lo mismo para mis clases.

Básicamente mi motivación era no tener que crear una clase para, por ejemplo, tener una colección de tuplas <Int, String> para poder hacer algo como esto:

(este código no compila. La notacion List<{Int, String}> es product de mi imaginación :D)

List<{Int, String}> miLista = new List<{Int, String}>();
miLista.Add(new { Elem1 = 1, Elem2 = "A" });
miLista.Add(new { Elem1 = 2, Elem2 = "B" });
miLista.Add(new { Elem1 = 3, Elem2 = "C" });

foreach (var tupla in miLista)
{
    Console.WriteLine(tupla.Elem1);
    Console.WriteLine(tupla.Elem2);
}



Le comenté esta duda a Diego Gonzalez y después de unos días me averiguó la forma de poder hacer esto y por que no funcionaba mi idea original. Me dijo que el problema es que los tipos genéricos no pueden ser inferidos en el constructor y es por eso que no se pueden crear las List<T> de esta forma.

Para poder crearlas hubo que hacer una clase auxiliar que infiere los tipos desde métodos estáticos y crea las instancias de las clases genéricas con los tipos ya inferidos (por si no se entendió, aca va un ejemplo):

(este código SI compila!)

using System;
using System.Collections.Generic;
using System.Text;

namespace CollectionsTest
{
    public class CollectionGenerator
    {
        public static List<T> NewList<T>(T witness)
        {
        return new List<T>();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var miLista = CollectionGenerator.NewList(
            new { Elem1 = 1, Elem2 = "A" });

            miLista.Add(new { Elem1 = 1, Elem2 = "A" });
            miLista.Add(new { Elem1 = 2, Elem2 = "B" });
            miLista.Add(new { Elem1 = 3, Elem2 = "C" });

            foreach (var tupla in miLista)
            {
                Console.WriteLine(tupla.Elem1);
                Console.WriteLine(tupla.Elem2);
            }
        }
    }
}


Básicamente, lo que hace el método NewList de la clase CollectionGenerator es inferir el tipo de un testigo de una clase genérica y construir una lista del tipo inferido. Una vez hecho esto, ya podemos usar nuestra lista de objetos de un tipo anónimo!

Espero que les sea útil.

Un saludo!

Z

2007-05-10

VMWare Workstation 6 (o Player 2) vs. Virtual PC 2007

Hace poco me bajé el Beta 1 de Visual Studio Orcas y prefería no destruir mi PC en el intento de probarlo me incliné por la opción de la virtualización.

Como cada vez que hago esto desde Windows, llegué a la dicotomía de si debía usar VMWare (el cual siempre supo dar buenos resultados en el pasado), o el nuevo Virtual PC 2007, del cual me habían hablado muy bien.

Para empezar, me bajé (de forma gratuita) el Virtual PC 2007 y creé una nueva máquina virtual con Windows XP SP2, todas las actualizaciones y Visual Studio Orcas. Para mi sorpresa (y en comparación con las versiones anteriores de Virtual PC) teniendo una VPC con sólo 256MB de RAM, se podía trabajar con total fluidez y soltura, sin frenadas ni grandes tiempos de carga (y decir eso sobre Visual Studio no es poca cosa). Lo único que podía notar a veces es que la máquina host se notaba un poco lenta.

Para mi suerte, después de 2 días (y por pura casualidad) salió la nueva versión de VMWare. Como andaba con un poco de tiempo, decidí probar cual era el mejor de los dos para lo que quería hacer (de por sí, el VMWare arrancaba con la ventaja de que corre Linux sin problemas, cosa que necesito a veces para la facultad). Bajé el VMWare Player 2.0 para Windows y el trial de VMWare Workstation para Linux (después verán para que). El único asunto es que el VMWare Player no tiene ninguna tool para crear nuevas máquinas virtuales. Aquí es donde www.easyvmx.com entra en juego: una página donde uno puede configurar una maquina virtual como quiere, y la genera! Con esto, ya podemos tener una maquina virtual similar a la creada para VPC. Una vez bajada la VM, procedí a instalar Windows XP.

Una vez ya instalado el sistema operativo salta a la luz otra diferencia del VMWare Player con la versión Workstation o Server: la falta de las VMWare Tools, instalables en la máquina Guest. Igualmente, esto tiene una muy simple solución: vamos al archivo .tgz que bajamos de la versión trial para Linux de VMWare Workstation y si buscamos un poco vamos a encontrar un archivo llamado Windows.iso o Linux.iso, los cuales son las imágenes de CD de las VMWare tools para Windows y Linux respectivamente. Montamos la imagen en la VM e instalamos las tools.

Ahora si, ya estamos en igualdad de condiciones para comparar los dos productos. Para ver que me convenía más, decidí correr unos benchmarks. Pese a que estuvieron bastante más parejos que los benchmarks anteriores, VMWare sigue superando a Virtual PC en performance.

Una cosa loca que me paso con los benchmarks es que al hacer un benchmark de disco, VPC sacó incluso más puntaje que la maquina nativa, por lo que pienso que debe estar haciendo alguna trampa en esa categoría…

Como todavía no quería cerrar el veredicto, me puse a usar la VM para ver como era el tiempo de respuesta y usabilidad. En una palabra, excelente. Como dato extra, la maquina host queda bastante más viva al correr la VM que con VPC.

Por lo tanto el veredicto final es: VMWare sigue ofreciendo superior performance, pero ahora es seguido bastante más de cerca por Virtual PC.

¡Hasta la próxima!

Z