jueves, 5 de julio de 2007

Sobre inferencia de tipos

En el post anterior hablé de la inferencia de tipos en las expresiones Lambda, sin embargo esta característica no es exclusiva de estas expresiones y mucho menos del Framework 3.5, existe en el Framework 2 y se encuentra relacionada con los delagados, veamos un ejemplo. List<string> list = new List(); list.Add("Visual Basic Dynamic"); list.Add("IronPython"); list.Add("Ruby"); list.Add("Javascript"); list.ForEach(Console.WriteLine); Este código lo encontré en esta dirección en un muy interesante artículo acerca de iteraciones. Pongamos atención es esta línea list.ForEach(Console.WriteLine); Es justamente donde vemos la inferencia de tipos, pero qué es inferencia de tipos, según el diccionario inferir es deducir algo, bien qué es lo que podemos deducir de esta línea, primero veamos la firma del método ForEach public void ForEach(Action<T> action) Acepta un parámetro del tipo Action<T>, entonces vamos a la definición public delegate void Action<T>(T obj); Es un delegado que acepta un parámetro del tipo T y no retorna nada, por lo tanto la traducción del método ForEach sería un método que acepta un delegado que acepta un parámetro del tipo T y no retorna nada. O sea, podemos pasarle cualquier método que acepta un T (string en este caso) y no retorne nada. Bueno, el método WriteLine de Console justamente acepta string (T para nuestra lista de string) y no retorna nada, por lo tanto el compilador acepta la expresión list.ForEach(Console.WriteLine); Esto es justamente uno de los fundamentos de los delegados, seguramente en poco tiempo voy a escribir algo de eso, por ahora cada vez que vean un método que acepta un delegado del algún tipo miren la definición. Por último como es costumbre vamos a ver el código de ForEach public void ForEach(Action<T> action) { if (action == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match); } for (int i = 0; i < this._size; i++) { action(this._items[i]); } } Como se puede ver en la línea marcada no se hace más que llamar al método que pasamos como parámetro y que debe aceptar T y no regresar nada, en fin, ahora sabemos un poco más como funciona, lo principal es no recordar sino comprender.