martes, 28 de abril de 2015

Preguntas de Entrevista .NET - Qué es Generics?

Bueno continuando con la serie de entradas dedicadas a analizar las preguntas que suelen aparecer en una entrevista para un puesto de desarrollador .NET. La pregunta que voy a intentar responder es la que aparece en casi todas las entrevistas en las que participe y es "Qué es Generics?". Lo primero que se nos viene a la cabeza a la hora de pensar en Generics es las colecciones. Y no esta mal que pensemos eso ya que siempre que se habla de Generics se lo asocia directamente a las listas genéricas que si, utilizan Generics pero no son el concepto de Generics en si mismas.

Entonces, qué es Generics?

Bueno la respuesta es verdaderamente muy sencilla. Generics es una herramienta que nos brinda el framework para separar el comportamiento del tipo de datos. Veamos un ejemplo sencillo que nos va a ayudar a ver mas claramente esto. Supongamos que tenemos la siguiente clase con un método estático que nos retorna cuando dos strings son iguales.

class check
{
    public static bool Compare(string a, string b)
    {
        return a.Equals(b);
    }

}

Como podemos ver es una clase muy sencilla pero si miramos en detalle vemos rápidamente que hay un problema. Este método solo nos sirve para comparar strings, con lo cual si quisiéramos comparar otro tipo de datos deberíamos sobre cargar el método Compare tantas veces como tipos de datos deseados. Y si bien esto funciona como podemos ver el código no queda limpio y el mantenimiento de esto es muy tedioso.

class check
{
    public static bool Compare(string a, string b)
    {
        return a.Equals(b);
    }
    public static bool Compare(int a, int b)
    {
        return a.Equals(b);
    }

    public static bool Compare(DateTime a, DateTime b)
    {
        return a.Equals(b);
    }
}

Entonces existe otra forma de hacer esto de una manera mas "genérica"? 

Si claro, podríamos definir nuestro tipo de dato como object. Y si esto es valido pero nos genera una sobrecarga de boxing y unboxing innecesaria. Para este tipo de cuestiones donde nosotros queremos separar el comportamiento del tipo de dato. Como hacemos estos? bueno lo primero que tenemos que hacer es definir el tipo de dato genérico que vamos a utilizar en nuestro método y eso lo hacemos utilizando los símbolos de < y > definiendo el tipo de dato adentro (generalmente se utiliza la letra T) pero cabe aclarar que podemos poner cualquier identificador ahi como podemos ver en el siguiente código.

class check
{
    public static bool Compare<UNKNOWTYPE>(UNKNOWTYPE a, UNKNOWTYPE b)
    {
        return a.Equals(b);
    }
}

Ahora que tenemos definido nuestro método de manera genérica vamos a ver como tendríamos que invocarlo.

Console.WriteLine("comparo numeros: " + check.Compare<int>(1,2));
Console.WriteLine("comparo strings: " + check.Compare<string>("hola", "hola"));

Como podemos ver ahora nuestro método sin necesidad de cambiarlo funciona con cualquier tipo de datos. Algo importante de aclarar es que el tipo de dato que utilicemos al momento de invocar nuestro método debe ser el mismo de los paramentros (porque así lo definimos). Si hubiéramos querido tipos de datos distintos lo deberíamos haber aclarado en la declaración de nuestro método. Les dejo la prueba con multiple tipos de datos genéricos a ustedes.
Entonces cuando nos encontremos con esta pregunta en una entrevista sin dudarlo debemos explicar que Generics nos brinda la posibilidad de separar nuestro comportamiento del tipo de dato, y esto lo podemos hacer a nivel de clase o de método.

No hay comentarios:

Publicar un comentario