C# establece genéricos

Las colecciones son un concepto importante en programación orientada a objetos y el soporte integral de C# para colecciones es una de las esencias del lenguaje.

¿Por qué utilizar colecciones genéricas?

Antes de C# 2.0, había dos formas principales de implementar colecciones:

A. Usar listas de matrices

Es intuitivo colocar objetos directamente en ArrayList, pero debido a Los elementos de la colección son todos tipos de objetos, por lo que se debe realizar una tediosa conversión de tipos cada vez.

B. Usar una clase de colección personalizada

Un enfoque común es heredar una clase personalizada de la clase abstracta CollectionBase e implementar una colección fuertemente tipada encapsulando el objeto IList. Este enfoque requiere escribir clases personalizadas correspondientes para cada tipo de colección, lo que requiere mucho trabajo. La aparición de colecciones genéricas resuelve muy bien los problemas anteriores. Crear una colección de un tipo específico solo requiere una línea de código.

¿Qué son los genéricos?

Generic es un elemento nuevo en C# 2.0 (llamado plantilla en C++), que se utiliza principalmente para resolver una serie de problemas similares. Este mecanismo permite pasar el nombre de la clase como parámetro a un tipo genérico y generar el objeto correspondiente. Puede que sea mejor comprender los genéricos (incluidas clases, interfaces, métodos, delegados, etc.). ) como plantilla, la parte variante en la plantilla será reemplazada por el nombre de clase pasado como parámetro, obteniendo así una nueva definición de tipo. Los genéricos son un tema muy amplio, por lo que no lo analizaré en detalle aquí. Los interesados ​​pueden consultar la información relevante.

¿Cómo crear una colección universal?

Utilice principalmente la clase genérica Lista en el sistema. Un espacio de nombres común para crear colecciones. La sintaxis es la siguiente:

Lista < T > Lista oft = nueva Lista < T >()

"t" es el tipo a utilizar, el cual puede ser simple; tipos como string e int también pueden ser un tipo definido por el usuario. Veamos un ejemplo específico.

Defina la clasificación de personas de la siguiente manera:

Personas de clase

{

Cadena privada _ nombre//nombre

private int _ age//Edad

//Crear un objeto persona

Figura pública (nombre de cadena, número entero)

{

Esto. _ nombre = Nombre

Este. _age = edad;

}

//Nombre

Nombre de cadena pública

{

Obtener{ return _ nombre}

}

//Edad

Internet público

{

obtener { return _ edad }

}

}

//Crear un objeto persona

Persona p1 = Nueva persona ("Zhang San", 30) ;

Persona p2 = recién llegado ("Li Si", 20);

Persona p3 = recién llegado ("Wang Wu", 50);

// Crea una colección de objetos de tipo Persona.

Lista < Persona > personas = new Lista < Persona >();

//Coloca el objeto Persona en la colección.

Personas. Añadir(p 1);

Personas. Añadir(p2);

Personas. Add(P3);

//Escribe el nombre de la segunda persona.

Consola. Escribir(personas[1]). Name);

Como puede ver, las colecciones genéricas simplifican enormemente el código de implementación de la colección, lo que le permite crear fácilmente colecciones de tipos específicos. Además, las colecciones genéricas proporcionan una funcionalidad más potente. Veamos cómo clasificar y buscar.

Clasificación general de colecciones

La clasificación se basa en la comparación. Para ordenar, primero compare. Por ejemplo, hay dos números 1 y 2. Para ordenarlos, primero compare los dos números y ordénelos según la comparación. Si quieres comparar objetos, la situación es un poco más complicada.

Por ejemplo, al comparar objetos Persona, puede compararlos por nombre o edad, por lo que debe determinar las reglas de comparación. Un objeto puede tener varias reglas de comparación, pero solo puede haber una regla predeterminada. Las reglas predeterminadas se colocan en la clase en la que se define el objeto. Las reglas de comparación predeterminadas se definen en el método CompareTo, que pertenece a la interfaz genérica comparable. Mire el código a continuación:

Categoría Persona:IComparable

{

//Comparación por edad

Público internacional comparable (Persona p )

{

Devuelve esto. Edad - p.Age;

}

}

El parámetro del método CompareTo es otro objeto del mismo tipo a comparar y el valor de retorno es de tipo int. Si el valor de retorno es mayor que 0, significa que el primer objeto es mayor que el segundo objeto; si es menor que 0, significa que el primer objeto es menor que el segundo objeto; si es 0, los dos objetos son iguales; .

Después de definir las reglas de comparación predeterminadas, puede ordenar la colección mediante el método de clasificación sin parámetros, de la siguiente manera:

//Ordene la colección según las reglas predeterminadas.

Personas. sort();

//Emite el nombre del propietario

foreach (persona p en persona)

{

Consola. WriteLine(p . Name); //La secuencia de salida es "Li Si", "Zhang San", "Wang Wu"

}

En el uso real, a menudo es necesario. Para seguir muchas reglas diferentes, ordena la colección, por lo que es necesario definir otras reglas de comparación, que se pueden definir en el método Compare, que pertenece a la interfaz genérica icomparer. Mire el siguiente código:

Comparador de nombres de clase: IComparer

{

//Instancia de clasificador de almacenamiento

comparador de nombres estáticos públicos Predeterminado = nuevo comparador de nombres();

//Comparar por nombre

Comparación pública int (Persona p1, Persona p2)

{

Regresar al sistema. colecciones . comparer . default . compare(p 1. nombre, p2. nombre);

}

}

Los parámetros del método Comparar son dos de el mismo tipo El objeto a comparar, el tipo de valor de retorno es int y las reglas de procesamiento del valor de retorno son las mismas que las del método CompareTo. comparador. El valor predeterminado devuelve el objeto Comparador incorporado, que se utiliza para comparar dos objetos del mismo tipo.

Ordenemos la colección usando este comparador recién definido:

// Ordene la colección por nombre.

Personas. Sort(NameComparer.Default);

//Ingrese el nombre del propietario

foreach (persona p en persona)

{

Consola. WriteLine(p . Name); //El orden de salida es "Li Si", "Wang Wu" y "Zhang San"

}

También puede ordenar la colección mediante delegación. . Primero, debe definir un método que el delegado llame para almacenar las reglas de comparación. Puedes utilizar métodos estáticos. Mire el siguiente código:

Comparación de personal de clase

{

//Comparación por nombre

Nombre int estático público (Persona p1 , Persona p2)

{

Regresar al sistema. colecciones . comparer . default . compare(p 1. nombre, p2. nombre);

}

}

Los parámetros del método son dos. comparado Objetos del mismo tipo, el tipo de valor de retorno es int y las reglas de procesamiento del valor de retorno son las mismas que las del método CompareTo.

Luego, la colección se clasifica mediante el sistema de delegación universal incorporado. Comparar:

Sistema. Comparar Nombre Comparar = Nuevo Sistema. Comparar(Comparación de personajes. Nombre);

Personas. Ordenar (comparación de nombres);

//Importar el nombre del propietario

foreach (persona p en persona)

{

consola. WriteLine(p . Name); //El orden de salida es "Li Si", "Wang Wu" y "Zhang San"

}

Se puede ver que los dos últimos Se pueden seguir los métodos Las reglas especificadas clasifican la colección, pero el autor prefiere usar el método delegado. Puede considerar colocar varias reglas de comparación en una clase y luego llamarlas de manera flexible.

Buscar en una colección general

Buscar es encontrar elementos de una colección que cumplan ciertos criterios. Puede definir múltiples criterios de búsqueda y llamarlos según sea necesario. Primero, defina los criterios de búsqueda de la siguiente manera:

Palabras de título con apariencia humana

{

//Buscamos personas de mediana edad (más de 40 años)

Edad booleana estática pública (persona p)

{

Si (edad >= 40 años)

Devuelve verdadero

Otro

Devuelve falso

}

}

Las condiciones de búsqueda anteriores se colocan en un método estático y el tipo de retorno del método es booleano, una colección devuelve verdadero si el elemento cumple ciertas condiciones; de lo contrario, devuelve falso. Luego se busca en la colección a través del sistema de delegación universal incorporado. Predicción:

Sistema. Predicado MidAgePredicate = nuevo sistema. Predicado (Predicado de persona. Edad media);

lista personas de mediana edad = personas. find all(midage predicate);

//Muestra los nombres de todas las personas de mediana edad.

foreach(persona p en personal de medio término)

{

Consola. WriteLine(p . Name); //Salida "王五"

}

Extensión de la colección universal

Si quiero obtener los nombres de todas las personas en la colección, separados por comas, ¿cómo hacer eso?

Considerando que las funciones que una sola clase puede proporcionar son limitadas, es natural ampliar la lista < t > clase. Las clases genéricas también son clases, por lo que se pueden ampliar mediante herencia. Mire el siguiente código:

//Defina la clase de colección Personas

Categoría Persona: Lista

{

//Obtener Nombre del propietario de la colección.

Cadena pública GetAllNames()

{

if (this. count == 0)

Devuelve "";

p>

cadena val =

foreach(personal p aquí)

{

val += p.Nombre +",";< / p>

}

Devolver Val. Subcadena (0, val. Longitud-1);

}

}

//Crea y completa la colección de Personas

Personas PersonaCol = nuevas Personas();

PersonaCol. Añadir(p 1);

PersonCol. Añadir(p2);

PersonCol. Add(P3);

//Ingrese el nombre del propietario

Consola. Write (PersonCol. GetAllNames()); //Salida "Zhang San, Li Si, Wang Wu"

Resumen:

Este artículo se centra en la aplicación de la implementación genérica en C# 2.0. Conjuntos y extensiones para configurar funciones. El uso adecuado de colecciones genéricas puede reducir una gran cantidad de trabajo repetitivo y mejorar en gran medida la eficiencia del desarrollo.

De hecho, las colecciones son sólo una aplicación típica de los genéricos. Si quieres saber más sobre los medicamentos genéricos, puedes consultar otra información relevante. Espero que este artículo te sea útil :-)