2008-09-30 12 views
6

he estado aprendiendo acerca de los conceptos básicos de C#, pero no he encontrado una buena explicación de lo que es esto:Cuál es la "< >" sintaxis en C#

var l = new List<string>(); 

No sé lo que el <string> está haciendo o si es el List que está haciendo la magia. También he visto objetos arrojados dentro de las etiquetas < >.

¿Alguien me puede explicar esto con ejemplos, por favor?

Respuesta

24

Esa es la sintaxis genérica para C#.

El concepto básico es que le permite usar un marcador de posición Tipo y sustituir el tipo real real en tiempo de compilación.

Por ejemplo, la manera antigua:

ArrayList foos = new Arraylist(); 
foos.Add("Test"); 

trabajado haciendo tienda ArrayList una lista de System.Objects (El tipo de base para todas las cosas .NET).

Así, al añadir o recuperar un objeto de la lista, el CLR tendría que echarlo a objeto, básicamente, lo que realmente sucede es lo siguiente:

foos.Add("Test" as System.Object); 
string s = foos[1] as String. 

Esto provoca una reducción del rendimiento de la fundición, y también es inseguro porque puedo hacer esto:

ArrayList listOfStrings = new ArrayList(); 
listOfStrings.Add(1); 
listOfStrings.Add("Test"); 

esto compilará bien, a pesar de que puse un número entero en listOfStrings.

Genéricos cambiaron todo esto, ahora el uso de los genéricos que puedo declarar qué tipo mi colección de espera:

List<int> listOfIntegers = new List<int>(); 
List<String> listOfStrings = new List<String>(); 

listOfIntegers.add(1); 

// Compile time error. 
listOfIntegers.add("test"); 

Esto proporciona seguridad en tiempo de compilación tipo, así como evita costosas operaciones de colada.

La forma de aprovechar esto es bastante simple, aunque hay algunos casos avanzados. El concepto básico es hacer que tu clase sea independiente utilizando un marcador de posición de tipo, por ejemplo, si quisiera crear una clase genérica de "Añadir dos cosas".

public class Adder<T> 
{ 
    public T AddTwoThings(T t1, T t2) 
    { 
     return t1 + t2; 
    } 
} 

Adder<String> stringAdder = new Adder<String>(); 
Console.Writeline(stringAdder.AddTwoThings("Test,"123")); 

Adder<int> intAdder = new Adder<int>(); 
Console.Writeline(intAdder.AddTwoThings(2,2)); 

Para una explicación mucho más detallada de los genéricos, no puedo recomendar lo suficiente el libro CLR a través de C#.

+0

fyi la penalización de rendimiento cuando se usa ArrayLists es cuando se producen tipos de valores de boxeo y de desembalaje (estructuras, entradas, flotantes, etc.). No hay una penalización apreciable en el rendimiento al convertir la referencia del objeto en una referencia de cadena. –

+1

Además, es un punto menor, pero los genéricos (o tipos construidos) en .net no se realizan (construyen) hasta el tiempo de ejecución. El compilador solo verifica su código en tiempo de compilación y garantiza que para IList Agregue (T) que la var en 'Add (var)' se puede convertir implícitamente en T. –

+2

El ejemplo AddTwoThings se ha cubierto varias veces en SO, y no es válido. – erikkallen

1

Esto es .NET Generics. El tipo dentro del <> indica el tipo de elemento contenido en la lista.

con ArrayList que tendría que emitir los elementos en el interior ...

int x = (int)myArrayList[4]; 

con la Lista Usted puede evitar ese paso porque el compilador ya sabe el tipo.

int x = myList[4]; 

Los genéricos están disponibles en .NET 2.0 y posterior.

1

Esos son genéricos. Está haciendo una lista que solo contiene cadenas. También puede decir

List<int> 

y obtener una lista que solo contiene entradas.

Los genéricos son un tema enorme, demasiado grandes para una sola respuesta aquí.

+0

Gracias por eso y he editado la pregunta –

+0

NP. Borré mi sugerencia también. En el agujero de la memoria van. –

5

Es genéricos - es una forma de tipo de parametrización. En su ejemplo, hace que me refiera a una lista de cadenas: la lista solo contendrá cadenas: el compilador la trata (casi) como si en todos los lugares en que la API menciona "T" en realidad dice "cadena". Por lo tanto, solo puede agregar cadenas, y si utiliza el indexador no necesita convertirlo en cadena, etc.

Para ser honesto, dar cobertura detallada de genéricos en un foro en línea es prácticamente imposible. (En C# en profundidad, tomo casi 50 páginas hablando de genéricos). Sin embargo, armado con el nombre de la función, debería estar en una posición mucho mejor para obtener más información. El MSDN "Introduction to C# Generics" es probablemente un buen punto de partida.

Hacer preguntas específicas sobre los genéricos en SO es probable que arroje buenos resultados; simplemente no creo que realmente se pueda cubrir adecuadamente en una pregunta/respuesta.

+0

Gracias, una buena respuesta. –

1

Esto es genérico en acción. Una lista normal almacena elementos del tipo Objeto. Esto requiere lanzar entre tipos. Esto también le permitirá almacenar cualquier tipo de artículo en una instancia de una lista. Cuando está iterando a través de elementos en esa lista, no puede estar seguro de que todos sean de cierto tipo (al menos no sin enviar cada elemento). Por ejemplo digamos que se crea una lista como esta:

List listOfStrings = new List(); 

Nada impide a alguien de hacer algo como esto:

listOfStrings.add(6); //Not a string 

Una lista genérica le permitirá especificar una lista inflexible de tipos.

List<string> listOfStrings = new List<string>(); 
listOfStrings.add("my name"); //OK 
listofStrings.add(6); //Throws a compiler error 

hay un ejemplos más detallados aquí Generics

0

<> es para los genéricos. En su ejemplo específico, significa que la Lista es una Lista de cadenas, no una lista de entradas.

Los genéricos se utilizan para permitir que un tipo sea, bueno, genérico. Se usa ALOT en Colecciones para permitirles tomar diferentes tipos de modo que puedan funcionar de forma muy parecida a una matriz normal y seguir detectando tipos no válidos asignados en tiempo de compilación. Básicamente, permite que una clase diga "Necesito estar asociado con algún tipo específico T, pero no quiero codificar exactamente qué tipo es ese tipo, y dejar que el usuario lo seleccione".Una simple matriz, por ejemplo, podría ser algo como:

public class MyArray<T> { 
    private T[] _list; 

    public MyArray() : this.MyArray(10); 
    public MyArray(int capacity) 
    { _list = new T[capacity]; } 

    T this[int index] { 
     get { return _list[index]; } 
     set { _list[index] = value; } 
    } 
} 

Aquí, tenemos una lista privada de tipo T que se accede mediante el uso de nuestra clase como una matriz normal. No nos importa de qué tipo es, no importa nuestro código. Pero cualquiera que use la clase podría usarla como, digamos MyArray<string> para crear una lista de cadenas, mientras que otra persona podría usarla como MyArray<bool> y crear una lista de banderas.

Cuestiones relacionadas