Nuevas características de C# 3.0 en C#.net
1: Variables locales escritas implícitamente
Esta característica es muy simple. En algunas sombras de JavaScript, podemos usar uniformemente la palabra clave "var" para declarar variables locales en lugar de hacerlo. especifique el tipo exacto de la variable. El tipo exacto de la variable se puede inferir del valor inicial cuando se declara la variable. De esta manera, nuestra carga de trabajo de declaración de variables locales se puede simplificar enormemente. Aquí hay un ejemplo: classLocalVariables:AppRunner.AbstractApplication{publicoverridevoidRun(){varintValue=5;varstringValue="Thisisastring";varcustomClass=newLocalVariables();varintArray=newint [. 3]{1,2,3};foreach(varvalueinintArray)Console.WriteLine(value);}}El código anterior se analizará en: classLocalVariables:AppRunner.AbstractApplication{publicoverridevoidRun(){intintValue=5;stringstringValue="Thisisastring " ;LocalVariablescustomClass=newLocalVariables();int[]intArray=newint[3];foreach(intvalueinintArray)Console.WriteLine(value);}} Es importante tener en cuenta que dado que el tipo de variable se infiere del valor inicial de la variable, por lo que al declarar una variable, debe especificar un valor inicial para la variable. Además, las variables no carecen de tipos. Una vez que se inicializa una variable, se determina su tipo y solo puede almacenar un determinado tipo de valor en el futuro. Por ejemplo, se infiere que el tipo de stringValue anterior es una cadena, por lo que la variable. Sólo se puede guardar un valor de tipo cadena.
2: Tipo anónimo
A veces necesitamos guardar temporalmente los resultados intermedios de algunas operaciones, especialmente cuando estos resultados intermedios se componen de varias partes, a menudo declaramos un nuevo tipo para facilitar guardando estos resultados intermedios. A primera vista, esto parece normal, pero si lo piensa detenidamente, encontrará que este nuevo tipo solo sirve para esta función y no se usará en ningún otro lugar. De hecho, es un poco confuso definir un nuevo tipo solo para esta función. problema.
La función de tipo anónimo en C# 3.0 puede resolver muy bien los problemas mencionados anteriormente. A través de tipos anónimos, podemos simplemente usar new { nombre de atributo 1 = valor 1, nombre de atributo 2 = valor 2, .. ..., cree un nuevo tipo directamente en la función en forma de nombre de atributo n = valor n }, vea el siguiente ejemplo: classAnonymousType:AppRunner.AbstractApplication{publicoverridevoidRun(){varanonymousType1=new{CardNumber="10001", Name ="van's",Sex=true};Console.WriteLine(anonymousType1.CardNumber);Console.WriteLinevaranonymousType2=new{CardNumber="10002",Name="martin",Sex=true};anonymousType2=anonymousType1;}}en el El nuevo tipo solo puede tener miembros de campo, y los tipos de estos campos se infieren del tipo del valor inicial.
Si al declarar un nuevo tipo anónimo, los nombres de los campos, el orden y el tipo de valor inicial del nuevo tipo son consistentes, entonces se generará el mismo tipo anónimo. Por lo tanto, los tipos de anónimo1 y anónimo2 en el ejemplo anterior son los mismos. por lo que se puede realizar de forma natural. Asignación de tipoanónimo2=tipoanónimo1.
3: Matrices implícitamente escritas
Esta característica es una extensión de las variables locales implícitamente escritas. Con esta característica, nuestro trabajo de creación de matrices será más simple. Podemos declarar una matriz directamente usando la palabra clave "nuevo []", seguida de una lista de valores iniciales para la matriz. Aquí, no especificamos el tipo de matriz directamente, el tipo de matriz se infiere de la lista de inicialización. classAnonymousTypeArray:AppRunner.AbstractApplication{publicoverridevoidRun(){varintArray=new[]{1,2,3,4,5};vardoubleArray=new[]{3.14,1.414};varanonymousTypeArray=new[]{new{Name="van's ",Sexo=false,Arg=22},new{Name="martin",Sexo=true,Arg=23}};Console.WriteLine(intArray);Console.WriteLine(doubleArray);Console.WriteLine(anonymousTypeArray[0 ].Name);}} En el código anterior, la declaración de la variable anonymTypeArray utiliza tanto las características de las matrices escritas implícitamente como de los tipos anónimos. Primero, se crea el tipo anónimo y luego se usa la lista de valores inicial para inferir el tipo exacto. tipo de matriz.
4: Constructor de objetos
Cuando declaramos una matriz, podemos inicializarla al mismo tiempo, lo que nos ahorra muchos problemas. Sin embargo, al crear un objeto de una clase, este truco Pero no funciona. O llamamos al constructor de esta clase para completar la inicialización del objeto o lo inicializamos manualmente. Ambos métodos son inconvenientes cuando utilizamos un constructor para inicializar un objeto, es posible que necesitemos escribir varias versiones sobrecargadas del constructor para lograr cierta flexibilidad, lo cual es realmente problemático.
La característica de constructor de objetos agregada en C# 3.0 hace que la inicialización de objetos sea extremadamente simple. Podemos inicializar objetos de clase de una manera similar a la inicialización de matrices creando directamente objetos de clase. La expresión va seguida del código de inicialización de la clase. miembros.
Los ejemplos específicos son los siguientes: classPoint{publicintX{get;set;}publicintY{get;set;}publicoverridestringToString(){return"("+X.ToString()+","+Y.ToString()+")" ;} }classRectangle{publicPointP1{get;set;}publicPointP2{get;set;}publicRectangle(){P1=newPoint();P2=newPoint();}publicoverridestringToString(){return "P1:"+P1+",P2 :" +P2;}}classObjectBuilder:AppRunner.AbstractApplication{publicoverridevoidRun(){PointthePoint=newPoint(){X=1,Y=2};Console.WriteLine("Point(X,Y)=",thePoint);RectangletheRectangle =newRectangle (){P1={X=1,Y=1},P2={X=100,Y=200}};Console.WriteLine(theRectangle);}}Cuando definimos los atributos X e Y del Punto clase, solo debemos escribir las declaraciones de acceso get y set de la propiedad. El compilador de C# generará automáticamente códigos de operación get y set predeterminados para nosotros. Esta característica es muy útil cuando necesitamos definir propiedades simples.
Completamos fácilmente la inicialización de la clase Point con la nueva instrucción Point() { X = 1, Y = 2 }. Al crear un objeto de una clase, podemos inicializar el objeto de la clase según sea necesario, siempre que a la expresión de creación de la clase le siga una lista de atributos a inicializar, y solo podemos asignar valores iniciales al atributos que deben inicializarse sin tener que escribir los valores iniciales de los atributos.
En la expresión de inicialización del objeto Rectángulo, primero inicializamos el atributo P1. Sin embargo, el atributo P1 también es un tipo personalizado, por lo que la inicialización del atributo P1 es una expresión de inicialización de otro tipo (Punto). , podemos inicializar tipos más complejos de esta manera.
El artículo anterior presentó cuatro características relativamente simples en C# 3.0, a saber, variables locales escritas implícitamente, tipos anónimos, matrices escritas implícitamente y constructores de objetos. A continuación, presentaré algunas de las más complejas pero también muy poderosas. Se presentan funciones en C# 3.0 para que todos puedan explorarlas rápidamente.
5: Constructor de colecciones
Podemos especificar un valor inicial para la matriz mientras la declaramos, siguiendo directamente la declaración de la matriz con una lista de valores iniciales. Esto simplifica la inicialización de la matriz, pero los tipos de colección que creamos nosotros mismos no pueden disfrutar del mismo tratamiento que las matrices normales. No podemos usar la sintaxis de inicialización de la matriz al crear un objeto de colección personalizado.
La característica del constructor de colecciones agregada en C# 3.0 nos permite disfrutar del mismo tratamiento que una matriz ordinaria, permitiéndonos especificar un valor inicial al crear un objeto de colección. Para hacer esto, debemos permitir que nuestra colección implemente la interfaz ICollection
Los ejemplos de uso son los siguientes: classCollectionInitializer:AppRunner.AbstractApplication{classStringCollection:ICollection
6: Expresión Lambda
El proxy anónimo agregado en C# 2.0 simplifica nuestro trabajo de escribir funciones de procesamiento de eventos, de modo que ya no necesitamos declarar una función separada para vincular el evento. Se determina que solo necesita usar la palabra clave delegada para escribir código de procesamiento de eventos en línea.
C# 3.0 va un paso más allá. A través de expresiones Lambda, podemos escribir código de procesamiento de eventos de una manera más concisa. El nuevo código de procesamiento de eventos Lambda parece una expresión de cálculo, que utiliza el símbolo "=>". conecte los parámetros del evento y el código de manejo de eventos. Puedo escribir así: SomeEvent += parámetros de evento => código de manejo de eventos; el siguiente es un ejemplo completo: choseTAddDelegate
7: Método de extensión
Cuando necesitamos ampliar la funcionalidad de una clase existente, generalmente pensamos en herencia, heredamos la clase existente y luego le agregamos nuevos comportamientos. La característica del método de extensión agregada en C# 3.0 proporciona otra forma de implementar la extensión de funciones. Podemos extender la clase existente sin usar herencia. Este método no genera nuevos tipos, sino agregando nuevos métodos a las clases existentes para completar la expansión funcional.
Al extender una clase existente, necesitamos escribir todos los métodos de extensión en una clase estática. Esta clase estática es equivalente a un contenedor para almacenar métodos de extensión. Todos los métodos de extensión se pueden escribir en Inside. Además, el método de extensión adopta un nuevo método de declaración: nombre del método de extensión del tipo de retorno estático público (este tipo se extenderá sourceObj [, lista de parámetros del método de extensión]). A diferencia del método de declaración del método ordinario, comienza el primer parámetro del método de extensión. con esto Comienza con la palabra clave, seguida del nombre del tipo expandido y luego la lista de parámetros real.
El siguiente es un ejemplo de uso: staticclassExtensions{publicstaticintToInt32(thisstringsource){returnInt32.Parse(source);}publicstaticT[]Slice
El segundo método de extensión es un método genérico, que es una extensión para todos los tipos de matrices. Este método completa la operación de división de la matriz.
Las expresiones Linq en C# 3.0 utilizan una gran cantidad de métodos de extensión para implementar consultas de datos.
8: Expresión de consulta Linq
La característica más compleja agregada en C# 3.0 es la expresión de consulta Linq, que nos permite usar directamente una sintaxis similar a SQL para realizar operaciones de recopilación. lo que nos permite disfrutar de la poderosa función de consulta de datos relacionales.
Las expresiones de consulta de Linq se basan en varias características nuevas de C# 3.0, razón por la cual presenté Linq por última vez.
Veamos un ejemplo: classLinqExpression:AppRunner.AbstractApplication{publicoverridevoidRun(){//Defina la matriz anónima personas y asígnele el valor inicial varpersons=new[]{new{Name="Van's",Sex=false,Age=22 } ,nuevo{Nombre="Martin",Sexo=verdadero,Edad=30},nuevo{Nombre="Jerry",Sexo=false,Edad=24},nuevo{Nombre="Brog",Sexo=false,Edad= 25 },new{Name="Vicky",Sex=true,Age=20}};/*Ejecute una consulta Linq simple para recuperar a todas las personas menores de 24 años. Los resultados de la consulta se colocan en la variable de resultados El tipo. de la variable de resultados es la misma que la matriz personas */varresults=frompinpersonswherep.Age<=24selectp;foreach(varpersoninresults){Console.WriteLineConsole.WriteLine();//Defina la matriz anónima clientes y asígnele un valor inicial/ /La matriz es de tipo anónimo varcustomers=new[] {new{Name="Van's",City="China",Orders=new[]{new{OrderNo=0,OrderName="C#ProgrammingLanguage(SecondEdition)", OrderDate=newDateTime(2007,9,5)}, nuevo{OrderNo=1,OrderName="HeadFirstDesignPatterns(ChineseEdition)",OrderDate=newDateTime(2007,9,15)},new{OrderNo=2,OrderName=Unleashed2.0 (ChineseEdition)",OrderDate=newDateTime(2007,09,18)},new{OrderNo=3,OrderName="TheC++ProgrammingLangauge(SpecialEdition)",OrderDate=newDateTime(2002,9,20)}}},new {Name="Brog",Ciudad="China",Pedidos=nuevo[]{nuevo{OrderNo=0,OrderName="C#ProgrammingLanguage(SecondEdition)",OrderDate=newDateTime(2007,9,15)}}}, nuevo{Name="Vicky",Ciudad="Londres ",Orders=new[]{new{OrderNo=0,OrderName="C++ProgrammingLanguage(SpecialEdition)",OrderDate=newDateTime(2007,9,20)}} }};/*Ejecutar múltiples consultas Linq
Recuperar todos los registros donde la ciudad sea China y la fecha del pedido sea posterior a 2007
El resultado de la consulta es una matriz de tipo anónimo
Contiene el nombre del cliente, el número de pedido, la fecha del pedido y el nombre del pedido en cuatro campos */varsomeCustomers=fromcincustomerswherec.City=="China"fromoinc.Orderswhereo.OrderDate.Year>=2007selectnew{o.OrderNo,o.OrderDate, o.NombrePedido
e};foreach(varcustomerinsomeCustomers){Console.WriteLine(customer.OrderName+","+customer.OrderDate.ToString("D"));}}} En el ejemplo anterior, podemos ver las potentes funciones de la consulta Linq. nos permite realizar consultas simples o consultas multiunión más complejas. Y los resultados de la consulta también pueden ser tipos anónimos personalizados.