El lenguaje de programación C # versión 3.0 se lanzó el 19 de noviembre de 2007 como parte de .NET Framework 3.5 . Incluye nuevas características inspiradas en lenguajes de programación funcionales como Haskell y ML , y está impulsada en gran medida por la introducción del patrón Language Integrated Query (LINQ) en Common Language Runtime. [1] Actualmente no está estandarizado por ninguna organización de estándares .
Características de C # 3.0
LINQ (consulta integrada en el lenguaje)
LINQ es un nuevo lenguaje de consulta extensible y de propósito general específico de Microsoft para muchos tipos de fuentes de datos, incluidas colecciones de objetos simples, documentos XML, bases de datos, etc., que está estrechamente integrado con otras funciones del lenguaje C #. La sintaxis es diferente a la de SQL , pero la toma prestada . Un ejemplo:
int [] matriz = { 1 , 5 , 2 , 10 , 7 };// SELECT cuadrados de todos los números impares de la matriz ordenadas en orden descendente IEnumerable < int > consulta = de x en matriz donde x % 2 == 1 orderby x descendente seleccionar x * x ; // Resultado: 49, 25, 1
Para implementar LINQ, se agregó una gran variedad de métodos nuevos a muchas colecciones a través de la System.Linq.Enumerable
clase. Las expresiones LINQ se traducen para utilizar estas funciones antes de la compilación. Como alternativa, que en ocasiones es más potente o directa, se puede acceder directamente a estas funciones. [2] Al hacerlo, se utilizan más las funciones lambda, que se describen a continuación. Lo siguiente es funcionalmente idéntico al ejemplo anterior.
IEnumerable < int > query = array . Donde ( x => x % 2 == 1 ). OrderByDescending ( x => x ). Seleccione ( x => x * x ); // Resultado: 49, 25, 1 usando 'matriz' como se define en el ejemplo anterior
Inicializadores de objetos
Cliente c = nuevo Cliente (); c . Nombre = "Juan" ;
puede ser escrito
Cliente c = nuevo Cliente { Nombre = "John" };
Inicializadores de colección
MyList list = new MyList (); lista . Agregar ( 1 ); lista . Agregar ( 2 );
Se puede escribir como
MyList list = new MyList { 1 , 2 };
asumiendo que MyList
implementa System.Collections.IEnumerable
y tiene un Add
método público . [3]
Inferencia de tipo de variable local
Inferencia de tipo de variable local :
var x = nuevo Diccionario < cadena , Lista < flotante >> ();
es intercambiable con
Diccionario < cadena , Lista < flotante >> x = nuevo Diccionario < cadena , Lista < flotante >> ();
Esta característica no es solo un azúcar sintáctico conveniente para declaraciones de variables locales más breves, sino que también es necesaria para la declaración de variables de tipos anónimos. Sin embargo, la palabra clave contextual "var" solo puede aparecer dentro de una declaración de variable local.
Tipos anónimos
Los tipos anónimos proporcionan una forma conveniente de encapsular un conjunto de propiedades de solo lectura en un solo objeto sin tener que definir primero explícitamente un tipo. El nombre del tipo lo genera el compilador y no está disponible en el nivel del código fuente. El compilador infiere el tipo de propiedades.
var x = new { FirstName = "John" , LastName = "Doe" };
Los tipos anónimos son tipos de referencia que se derivan directamente de un objeto. El compilador les da un nombre aunque su aplicación no puede acceder a él. Desde la perspectiva del Common Language Runtime, un tipo anónimo no es diferente de cualquier otro tipo de referencia, excepto que no se puede convertir a ningún tipo excepto a object.
Si dos o más tipos anónimos tienen el mismo número y tipo de propiedades en el mismo orden, el compilador los trata como el mismo tipo y comparten la misma información de tipo generada por el compilador. [4]
Expresiones lambda
Las expresiones lambda proporcionan una forma concisa de escribir valores de funciones anónimas de primera clase. Compare el siguiente fragmento de C # 2.0:
listOfFoo . Donde ( delegado ( Foo x ) { retorno x . Tamaño > 10 ; });
con este equivalente de C # 3.0:
listOfFoo . Donde ( x => x . Tamaño > 10 );
En los ejemplos anteriores, las expresiones lambda son simplemente una sintaxis abreviada para delegados anónimos con inferencia de tipo para parámetros y tipo de retorno. Sin embargo, según el contexto en el que se utilicen, un compilador de C # también puede transformar lambdas en AST que luego se pueden procesar en tiempo de ejecución. En el ejemplo anterior, si listOfFoo
no es una colección simple en memoria, sino un contenedor alrededor de una tabla de base de datos, podría usar esta técnica para traducir el cuerpo de la lambda en la expresión SQL equivalente para una ejecución optimizada. De cualquier manera, la expresión lambda en sí se ve exactamente igual en el código, por lo que la forma en que se usa en tiempo de ejecución es transparente para el cliente.
Árboles de expresión
Expresiones como x <= y
, a = b + c
o incluso funciones lambda y otras formas complejas se pueden crear dinámicamente usando árboles de expresión . Gran parte de la funcionalidad la proporcionan los métodos estáticos de la clase System.Linq.Expressions.Expression
. También hay varias clases nuevas en ese espacio de nombres que representan las expresiones y expresiones parciales creadas por esos métodos como objetos de software. Estos incluyen BinaryExpression
, lo que podría representar x <= y
; LambdaExpression
y muchos otros. Cuando se combina con aspectos de la API de reflexión , esta puede ser una herramienta muy poderosa, aunque un poco difícil de escribir y depurar. [5] [6]
Propiedades automáticas
El compilador genera una variable de instancia privada y el descriptor de acceso apropiado y el código dado por el mutador, como:
Nombre de la cadena pública { get ; conjunto privado ; }
Métodos de extensión
Los desarrolladores pueden usar métodos de extensión para agregar nuevos métodos al contrato público de un tipo CLR existente, sin tener que subclasificarlo o recompilar el tipo original. En realidad, los métodos de extensión son una forma de azúcar sintáctica que proporciona la ilusión de agregar nuevos métodos a la clase existente fuera de su definición. La ilusión se logra con la definición de un método estático que es invocable como si fuera un método de instancia, donde el receptor de la llamada (es decir, la instancia) está vinculado al primer parámetro del método, decorado con palabra clave this
.
Los requisitos para un método de extensión son los siguientes:
- Un método de extensión debe definirse en una clase estática.
- Un método de extensión debe definirse como un método estático.
- El primer parámetro de un método de extensión debe tener la siguiente forma, donde tipo es el nombre del tipo que se va a extender:
this type parameterName
- Un método de extensión puede opcionalmente definir otros parámetros para seguir al
this
parámetro.
Esta clase de ejemplo demuestra la definición y el uso de un Left
método de extensión para cadenas:
public static class StringExtensions { public static string Left ( esta cadena s , int n ) { return s . Subcadena ( 0 , n ); } } cadena s = "foo bar" ; s . Izquierda ( 3 ); // igual que StringExtensions.Left (s, 3), que devuelve "foo";
Métodos parciales
Los métodos parciales permiten a los generadores de código generar declaraciones de métodos como puntos de extensión que solo se incluyen en la compilación si alguien realmente los implementa en otra parte de una clase parcial. [7]
Referencias
- ↑ Anderson, Tim (14 de noviembre de 2006). "C # adelantando a Java - El arquitecto principal pinta una imagen optimista de C #" . Desarrollador Reg . El registro . Consultado el 20 de enero de 2007 .
- ^ Walther, Stephen (2008). ASP.NET 3.5 desatado . Indiana, Estados Unidos: SAMS. págs. 916–917 . ISBN 978-0-672-33011-7.
Encuentro que uso la sintaxis del método más que la sintaxis de la consulta porque la sintaxis de la consulta es un subconjunto de la sintaxis del método.
- ^ Torgersen, Mads (10 de octubre de 2006). "¿Qué es una colección?" . El Mellow Reflexiones del Dr. T . Consultado el 18 de junio de 2009 .
- ^ "Tipos anónimos" . Guía de programación de C # . Microsoft . Julio de 2008 . Consultado el 18 de junio de 2009 .
- ^ Walther, Stephen (2008). ASP.NET 3.5 desatado . Indiana, Estados Unidos: SAMS . págs. 950–952 . ISBN 978-0-672-33011-7.
- ^ "Árboles de expresión" . .NET Framework Developer's Guide . Microsoft . Consultado el 26 de abril de 2009 .
- ^ "Clases y métodos parciales" . Guía de programación de C # . Microsoft . Consultado el 28 de abril de 2009 .