martes, 5 de noviembre de 2013

Inferncia de tipos


La inferencia de tipos, es una característica de los lenguajes funcionales  y consiste en la capacidad que tiene el compilador de predecir el tipo de una operación, método, asignación, etc., según los datos facilitados por el desarrollador dentro de la misma sentencia. Este proceso siempre se presenta en tiempo de compilación.
Esta novedad se dio por primera vez dentro del Framework 3.0, una entrega de framework muy poco utilizada y sin correspondiente versión de Visual Studio, por lo que muchos lo señalan como novedad del framework 3.5.

Normalmente la inferencia de tipos se suele achacar a los tipos anónimos (var), pero nosotros intentaremos darle un enfoque más general y trataremos para comenzar su uso con generics, para después verlo con tipos anónimos, y eventos y delegados, avanzadas en Expresiones Lambda, y árboles de expresiones que se escapan de nuestro tema principal.



Recuerda que aquí tienes el indice de todos los posts del Curso de LinQ.


Para intentar demostrar esto, lo mejor es ver unos ejemplos:

Vamos a fijarnos en el primer método genérico que hicimos:

public static void CambiarValores<T>(ref T a, ref T b)
{
    T _a = a;
    T _b = b;

    a = _b;
    b = _a;
}


Si nos fijamos bien, nos damos cuenta que la variable del tipo (T) es la misma para la firma del método y para cada uno de los dos parámetros. Esto quiere decir que el tipo de datos con que hagamos uso de la función tiene que ser el mismo para los 3 datos. Si vemos una llamada normal, está seria así:

int variableUno = 4;
int variableDos = 3;

CambiarValores<int>(ref variableUno, ref variableDos);

Y por supuesto el compilador no nos pondría ningún tipo de pega.

Nota:
En ocasiones, no tenemos que hacer mucho caso al compilador, porque este en su afán de darnos toda la información posible de las acciones disponibles, tiende a confundirnos, y nos muestra siempre la información de añadido de la variable de tipo, aunque esta pueda inferirse.

En la creación de Clases genéricas, no es posible inferir el tipo, aquí tendremos siempre que añadir implícitamente el parámetro de tipo.

En este ejemplo:

public class MiClase<T>
{
    public T MiPropiedad { get; set; }

    public MiClase(T prop)
    {
        this.MiPropiedad = prop;
    } 
}

A la hora de instanciar la clase, aunque hagamos uso del constructor, es imposible inferir el tipo en su instanciación:

MiClase<int> m = new MiClase<int>(1);

Esta ha sido una pequeña introducción de la inferencia de tipos solo para genérics, en los siguientes posts, veremos mucho más sobre el tema. No me he querido adelantar para poder tratarlo más en profundidad en cada uno de los casos.