No hay derecho. Mientras en Borland se lucha todavía a brazo partido para añadir a Delphi.NET, aunque sea, el soporte para tipos genéricos, llega Microsoft y pone sobre la mesa un prototipo completamente funcional con las novedades que se van a añadir a C# 3.0.
El anuncio se ha producido durante la conferencia de programadores que Microsoft celebra anualmente, junto con las novedades relacionadas con Windows Vista, la próxima versión del sistema operativo. Se ha mostrado código como el siguiente:
var q = from cliente in clientes
where cliente.City == "London";
¡Esto es C#, aunque no lo parezca! La cláusula var permite ahora inferir el tipo de la variable local en base a la expresión usada para su inicialización. En este caso, el tipo de la variable q implementa la interfaz IEnumerable, de modo que es posible luego recorrer los registros recuperados en esta estructura de datos. ¿Por qué hay algo que "parece" SQL? Se trata de una nueva construcción sintáctica, que recibe el nombre de Query Expression Pattern (o patrón de expresiones de consultas).
LANGUAGE INTEGRATED QUERY.
Tras esta sorpresa hay una serie de adiciones al lenguaje. Estas son las principales:
- Expresiones lambda
- Tipos anónimos
- Query Expression Pattern
Las expresiones lambda son la extensión natural de los métodos anónimos añadidos a C# 2.0. En aquella versión, podíamos crear un manejador de eventos en línea dentro del código de inicialización:
button1.Click +=
delegate(object sender, EventArgs e)
{ MessageBox.Show("Hi!"); };
Aunque podemos omitirlos en ciertos casos, en general es necesario incluir la declaración de los parámetros del método si queremos poder usarlos. Las expresiones lambda eliminan esta necesidad al formalizarse la técnica de inferencia de tipos en la especificación del lenguaje. Además, si el método anónimo tiene como objetivo devolver un valor de retorno, se puede abreviar el bloque de instrucciones mediante la expresión que hay que evaluar. Este es un ejemplo de expresión lambda, en la que todavía se declara el tipo del parámetro:
(Cliente c) => c.City == "London"
En este caso, se genera un tipo delegado que recibe un objeto de tipo Cliente y devuelve un valor lógico. Si el contexto permite deducir el tipo del parámetro, la expresión puede simplificarse así:
c => c.City == "London"
Los tipos anónimos, en combinación con la inferencia de tipos, se utilizan para resolver un viejo problema que planteaba la compatibilidad de lenguajes orientados a objetos con bases de datos relacionales. Cuando ejecutamos una instrucción select en SQL y no utilizamos todas las columnas de la tabla base, o utilizamos expresiones en la cláusula de selección, estamos tratando implícitamente con un nuevo esquema relacional. Si esto lo trasladamos a un lenguaje OOP, estaríamos ante un tipo de datos nuevo generado por la consulta sobre la marcha. Observe ahora lo que nos permite hacer C# 3.0:
var c = new { Nombre = "Ian", Apellidos = "Marteens" };
A la derecha de la asignación tenemos un inicializador de objetos: una instrucción que sirve para crear e inicializar una instancia... ¡de una clase creada sobre la marcha por el compilador! La nueva clase tiene dos propiedades, Nombre y Apellidos, y es a este tipo "sin nombre" al que pertenece la variable q, gracias a la inferencia de tipos.
Para terminar, aunque sea de momento, C# 3.0 introduce un nuevo patrón asociado a una estructura de control del lenguaje. Si ya teníamos patrones asociados a las instrucciones using y foreach, existen ahora una reglas precisas para poder traducir los nuevos bloques de consultas en llamadas a métodos que utilizan con mucha frecuencia expresiones lambda en sus parámetros. Estas nuevas "consultas" soportan una sintaxis muy similar a la de SQL, aunque con unas pocas variaciones. La cláusula from, por ejemplo, es la primera en escribirse, lo cuál es lo lógico: se trata de un defecto bastante molesto de SQL. Otro ejemplo de modificación: la cláusula order by se convierte en orderby, de modo que se evita la sintaxis verborreica que hacía furor en IBM en la decada de los 70.
... Y HAY MUCHO MAS
Por supuesto, estos cuatro párrafos no muestran ni el 5% de todo lo presentado en la PDC2005 sobre C#. En los próximos días, a medida que se sigan desvelando detalles, quiero escribir un par de artículos sobre las novedades en el lenguaje... y de paso, adelantar cómo pueden incorporarse al diseño de Freya.
Por ejemplo, para no tener que reescribir todo el API de acceso a datos para soportar la nueva funcionalidad, Microsoft ha incorporado una característica a C# 3.0 que parece copiada de Delphi.NET: las extensiones de métodos. Este tipo de funcionalidad entra dentro de una categoría conocida en inglés como syntactic sugar: la nata que adorna el pastel. Ya he leído, sin embargo, el comentario partisano de alguno alabando todo lo que C# 3.0 debe a Borland... aunque no haya tantos lobos como pretende el pastorcillo.
Otras novedades, en cambio, tienen mucho mayor calado, como es el caso de los árboles de expresiones (expression trees). Al parecer, C# 3.0 permitirá convertir las expresiones lambda en estructuras de datos, que más adelante pueden convertirse a su vez en código ejecutable. Esto puede ser muy importante para poder transmitir consultas a través de conexión remota, o para generar dinámicamente estos árboles durante una sesión y hacer que persistan hasta la próxima sesión. Esto simplificaría mucho el desarrollo de aplicaciones multicapas potentes y flexibles.
De hecho, otro de los anuncios es que ObjectSpaces, el sistema de clases persistentes experimental que se anunció primero con .NET 2.0 y luego con SQL Server 2005, ha sido abandonado en beneficio de LINQ. En realidad, mucha de la funcionalidad ya experimentada en ObjectSpaces pasa a formar parte de subconjuntos funcionales de LINQ. Se trata de una noticia estupenda.
|