Nota del autor

Si la entrada que estás leyendo carece de imágenes, no se ve el vídeo que teóricamente lleva incrustado o el código fuente mostrado aparece sin formato, podéis conocer los motivos aquí. Poco a poco iré restableciendo la normalidad en el blog.
Este blog es un archivo de los artículos situados previamente en Lobosoft.es y ha dejado de ser actualizado. Las nuevas entradas pueden encontrarse en www.lobosoft.es. Un saludo,
Lobosoft.
Mostrando entradas con la etiqueta linq. Mostrar todas las entradas
Mostrando entradas con la etiqueta linq. Mostrar todas las entradas

viernes, 21 de marzo de 2008

Tipos anónimos

Los tipos anónimos constituyen otra de las novedades de C# 3.0, estando fuertemente ligados a la aparición de LINQ. Realmente, los tipos anónimos son tipos class dotados de propiedades públicas de sólo lectura (por ello se les conoce también como tipos anónimos inmutables), no permitiendo ningún otro miembro de clase, como pudieran ser métodos o eventos.


Estos tipos anónimos, que son declarados mediante la palabra reservada ‘var', se inicializan justo en el momento de su creación, ya que el CLR deberá inferir, a partir de esta inicialización, la clase que será asociada a dicho tipo, y usada durante la ejecución del programa. Al ser un tipo class, la inicialización vendrá de la mano de un ‘new', ya que deberemos construir el objeto perteneciente a dicha clase. Como ya apuntábamos, los tipos anónimos tienen su máximo poder de expresión junto a LINQ, permitiéndonos ahorrar código y hacer más claro el que escribamos.



Tipos anónimos


En el código precedente, podemos observar que tras declarar un objeto ‘mitipo' mediante un tipo anónimo, Visual Studio nos permite trabajar con él como si un objeto instancia de cualquier otra clase se tratara incluyendo, mediante reflexión, acceso a las propiedades del objeto, y mostrando información sobre el mismo en el IDE, mediante Intellisense.


Como vemos, el uso de los tipos anónimos nos facilita el desarrollo, evitando la declaración explícita y formal de la clase correspondiente al tipo. La inicialización conjunta a la declaración es necesaria ya que el uso de ‘var' producirá un objeto fuertemente tipado.


Por último, adaptamos uno de los ejemplos del libro C# 3.0 in a Nutshell incorporados a LINQPad para recuperar los valores de la tabla Productos de la base de datos Northwind, incorporada como ejemplo en los productos SQL Server, para mostrar la potencia de los tipos anónimos. En esta tabla se almacena información sobre los productos de nuestra empresa, como su nombre, categoría o precio. Vamos a recuperar en concreto estos tres campos para los pedidos efectuados desde España, y el resultado lo almacenaremos en un objeto denominado ‘spanishProducts'. El código quedaría como:


[csharp]var spanishProducts = from p in Products
let spanishOrders = p.OrderDetails.Where(o => o.Order.ShipCountry == "Spain")
where spanishOrders.Any()
orderby p.ProductName
select new
{
p.ProductName,
p.Category.CategoryName,
TotalValue = spanishOrders.Sum(o => o.UnitPrice * o.Quantity)
};[/csharp]

martes, 18 de marzo de 2008

El juego de la vida de Conway

Preparando material para una introducción a Test-Driven Development , y aficionado como soy desde siempre al aspecto más lúdico del software, pensé en realizar una versión del Juego de la vida basando el desarrollo en la especificación de las reglas de juego mediante las pruebas unitarias. En el Juego de la vida, concebido por el matemático británico J. H. Conway, el jugador se convierte en mero espectador de la evolución que se desarrolla ante sus ojos. Las reglas son muy simples y el resultado apasionante, de ahí mi interés en convertirlo en un ejemplo para el curso. El tablero de juego es una malla de celdas en las que puede haber o no células. Básicamente, el juego se sustenta en lo siguiente:




  • Una célula muerta con exactamente 3 células vecinas vivas "nace" (al turno siguiente estará viva).

  • Una célula viva con 2 ó 3 células vecinas vivas sigue viva, en otro caso muere o permanece muerta (por "soledad" o "superpoblación").


En las referencias, a pie de artículo, se pueden encontrar enlaces a la Wikipedia y otros sitios de internet con más información sobre el juego.


Juego de la vida de Conway


Mi sorpresa fue mayúscula cuando, al buscar referencias a otras implementaciones del juego (como versiones en 3D, o con tableros de características distintas al del juego original), encontré con la versión que recomiendo ahora. Una implementación muy reciente del juego, en .Net 3.5, usando la potencia de LINQ para el manejo de colecciones, y con el código de pruebas unitarias implementado. Y si ya existe la rueda, ¿para qué reinventarla? Tras estudiarlo brevemente, creo que lo usaré para mi curso y, de paso, os lo recomiendo desde el blog, pues siempre me pareció un tema apasionante, tanto desde el punto de vista de la informática como base para la simulación de ecosistemas y evolución de poblaciones.


Ya que también existe una versión en F# y Silverlight (otra de las posibilidades que me planteaba, contando con el conocimiento que respecto a esta última tecnología posee mi amigo Fernando), se me ocurre ahora una versión del juego en 3D, con toda la potencia que ofrece XNA... y es que a este último le tengo, de momento, algo abandonado. A ver si los compañeros de Malvicio se apuntan a esta aventura de la vida.


Para saber más:

martes, 26 de febrero de 2008

Expresiones lambda vs Delegados y métodos anónimos

En la entrada anterior vimos cómo usar las expresiones lambda para formular con una sintaxis compacta y clara una serie de ecuaciones matemáticas en el .Net Framework 3.0 (y 3.5). Avanzamos también la relación existente entre esta notación y la declaración de un delegado y un método anónimo para implementar la misma funcionalidad, y cómo, hasta cierto punto, si las expresiones lambda hubiesen aparecido en la versión anterior del framework, podrían haber suplido la función de los métodos anónimos, brindando además una mayor funcionalidad, como el uso de bloques de código como datos y el uso de árboles de expresión, aspectos en los que profundizaremos más adelante, pues dotan a C# de características propias de la metaprogramación.


El propósito de hoy, sin embargo, es complementar al artículo de ayer, en el que afirmaba la íntima relación existente entre las expresiones lambda y los métodos anónimos y delegados, como avanzaba hace un momento. Para demostrarlo, haremos uso de la excelente herramienta Reflector, de Lutz Roeder, que permite desensamblar código objeto generado para el .Net Framework y mostrarlo en varios de los lenguajes que soporta (C#, VB.Net y el propio IL, entre otros).


Si abrimos, usando Reflector, la DLL correspondiente al ejemplo de ayer, en el que implementábamos una clase que nos ofrecía la funcionalidad de cálculo del interés simple en matemáticas financieras, nos encontraremos con una serie de peculiaridades.



Estructura de la clase Financiera


Como podemos apreciar, en el ensamblado se encuentran, además de los métodos que definimos en la clase, otra serie de métodos y delegados con nombres generados automáticamente. Si comprobamos el contenido de los mismos, pulsando sobre su nombre en el árbol de exploración de Reflector, nos encontraremos con un delegado “vacío”, correspondiente a la expresión lambda que definimos con nuestra ecuación para el interés.


Delegado “Interes”


El analizador de Reflector (botón derecho, y opción analizar) nos indica las dependencias del método y por cuáles otros es usado. En la secuencia de figuras que se muestran a continuación se puede comprobar que nuestra expresión lambda ha sido convertida internamente en un método anónimo y un delegado, ambos privados.




Método que implementa nuestra funcionalidad para el interés simple
La implementación de nuestra funcionalidad inicial



El método abstracto y delegado con sus dependencias
El delegado con sus usos y dependencias

La clase ofrecerá la funcionalidad a través de un delegado público que implementa el tipo genérico System.Func. Finalmente, el código de la clase quedará:



Código de la clase, según el desensamblador


Con ésto hemos demostrado la relación existente entre las expresiones lambda y los delegados y métodos anónimos que indicábamos ayer.

Expresiones Lambda en C#

Ya he hablado en otras ocasiones sobre la incorporación de las expresiones lambda al .Net Framework a partir de su versión 3.0. Este tipo de expresiones, en las que profundizaremos hoy, proporcionan al framework el soporte necesario para el uso de LINQ como lenguaje de consulta casi, diríamos, universal. Lo primero que llama la atención al ver la implementación de las expresiones lambda en .Net es que, de haber aparecido antes, no habrían sido necesarios los métodos anónimos que se incorporaron en la anterior versión del framework (.Net 2.0). Es más, en cierto modo constituyen -entre otras mejoras- un embellecimiento del código y un (permítasenos la licencia de llamarlo así) encapsulamiento del método anónimo y del delegado que lo incluye. Esta relación, y cómo se definen las expresiones lambda, será el tema principal de la entrada de hoy.


En el cálculo del interés simple, dentro del campo de las matemáticas financieras, entran en juego una serie de ecuaciones que deseamos implementar en nuestro código.


Interés = Capital * Tiempo * Tasa de interés
Valor Futuro = Capital * (1 + Tasa * Tiempo)
Capital = Valor Futuro * (1+ Tasa * Tiempo) -1

Si deseáramos implementar estas funciones mediante el uso de métodos anónimos, deberíamos hacerlo a través de un delegado. Por ejemplo, la función que define el Interés podría implementarse como sigue:


[csharp]
private static double MiInteres(double C, int t, float i)
{
return ((C * t) * i);
}
[/csharp]

Para poder asignarla a un delegado, deberíamos tener definido un delegado con su misma firma:


[csharp]public delegate double Func(double C, int t, Single i);[/csharp]

La asignación, entonces, sería automática:


[csharp]Func miInteres1 = MiInteres;[/csharp]

Sin embargo, los métodos anónimos nos brindan un método más compacto y elegante para obtener el mismo resultado:


[csharp]Func miInteres2 = delegate(double C, int t, Single i) { return C * t * i; };[/csharp]

La definición de Func, incluido en el espacio de nombres System.Linq como tipo genérico de delegado, es la que sigue (para un ejemplo con 0, 1 y 2 argumentos):


[csharp]
public delegate TResult Func();
public delegate TResult Func(T1 arg1);
public delegate TResult Func(T1 arg1, T2 arg2);
[/csharp]

Visto esto, ¿cómo podríamos realizar la implementación de nuestras funciones financieras usando expresiones lambda? Vuelvo a incidir en la cercanía de dichas expresiones con los lenguajes funcionales y en que, debido a esta característica, su declaración será compacta y precisa. Comencemos con la misma función que nos ha ocupado hasta este momento, la del cálculo del interés simple. Recordemos que esta función estaba definida como

Interés = Capital * Tiempo * Tasa de interés

La expresión lambda equivalente será
[csharp]
public static Func Interes = (C, t, i) => (C * t * i);
[/csharp]

Como vemos, el C# de los .Net Frameworks 3.0 y 3.5 incluye mediante las expresiones lambda una sintaxis mucho más clara y concisa que el que se conseguía mediante el uso de los métodos anónimos. Una posible implementación de las ecuaciones implicadas en el cálculo del interés podría ser la siguiente:


[csharp]
public static class InteresSimple
{
public static Func Interes =
(C, t, i) => (C * t * i);

public static Func ValorFuturo =
(C, t, i) => (C * (1 + i * t));

public static Func Capital =
(VF, t, i) => (VF * Math.Pow((1 + i * t), -1));
}
[/csharp]

Entre las ventajas que nos aportará el uso de las expresiones lambda frente al de métodos anónimos y delegados se encuentra no sólo la simplicidad y limpieza sintáctica de la expresión, sino también la posiblidad de usar bloques de código como datos (algo inherente a estas expresiones e imposible de conseguir mediante los métodos anónimos), una característica en la que profundizaremos en otra ocasión.

lunes, 18 de febrero de 2008

LINQPad

LINQPad Logo


El gran cambio en el .Net Framework desde la versión 2.0 a la 3.5 ha sido la incorporación de LINQ (Languaje Integrated Query), un lenguaje de consulta que viene a hacer las veces, en cierto modo, de un O/RM para .Net. Con LINQ podemos realizar consultas desde cualquier fuente de datos (BBDD, XML, colecciones de objetos...) y manipular los resultados de las mismas.


Ante este panorama, a los desarrolladores .Net no nos queda más opción que la de ponernos manos a la obra con este nuevo "juguetito", y para ello nada mejor que usar las herramientas adecuadas. Aunque Visual Studio 2008 da soporte a LINQ y los lenguajes que lo usan permiten aprovechar los recursos de IntelliSense y la validación de sentencias en tiempo de compilación, he encontrado un editor mucho más ligero para trabajar con LINQ, el LINQPad. Permite establecer conexión con diversas fuentes de datos, la importación de espacios de nombres y la depuración y ejecución de LINQ. Además, la última versión incorpora más de 200 ejemplos prácticos, listos para ejecutar y aprender LINQ, procedentes del libro C# 3.0 in a Nutshell.


Ahora sí que no tenemos excusa para no aprender LINQ.



LINQPad en ejecución.