C'est la syntaxe générique pour C#.
Le concept de base est qu'il vous permet d'utiliser un espace réservé de type et de remplacer le type réel réel au moment de la compilation.
Par exemple, l'ancienne:
ArrayList foos = new Arraylist();
foos.Add("Test");
travaillé en faisant magasin ArrayList une liste de System.Objects (Le type de base pour toutes les choses .NET).
Ainsi, lors de l'ajout ou la récupération d'un objet à partir de la liste, le CLR devrait jeter à l'objet, au fond ce qui se passe vraiment est la suivante:
foos.Add("Test" as System.Object);
string s = foos[1] as String.
Cela provoque une pénalité de performance de la coulée, et Il est aussi dangereux parce que je peux le faire:
ArrayList listOfStrings = new ArrayList();
listOfStrings.Add(1);
listOfStrings.Add("Test");
cela va compiler très bien, même si je mets un entier listOfStrings.
Generics a changé tout cela, maintenant je peux en utilisant Generics déclarer quel type ma collection attend:
List<int> listOfIntegers = new List<int>();
List<String> listOfStrings = new List<String>();
listOfIntegers.add(1);
// Compile time error.
listOfIntegers.add("test");
Cela fournit le type de compilation sécurité, ainsi que des opérations coûteuses évite de coulée.
La façon dont vous en tirer parti est assez simple, bien qu'il existe des cas de bords avancés. Le concept de base est de rendre votre type de classe agnostique en utilisant un espace réservé de type, par exemple, si je voulais créer une classe générique "Ajouter deux choses".
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));
Pour une explication beaucoup plus détaillée des génériques, je ne peux pas recommander suffisamment le livre CLR via C#.
fyi la pénalité de performance lors de l'utilisation de ArrayLists est lorsque les types de valeur boxe et unboxing se produit (structs, ints, flotteurs, etc). Il n'y a pas de pénalité de performance appréciable pour renvoyer la référence d'objet à une référence de chaîne. –
De plus, c'est un point mineur, mais les génériques (ou les types construits) dans .net ne sont pas réalisés (construits) avant l'exécution. Le compilateur vérifie seulement votre code au moment de la compilation et s'assure que pour IList .Add (T) que var dans 'Add (var)' est implicitement convertible en T. –
L'exemple AddTwoThings a été couvert plusieurs fois sur SO, et n'est pas valide. – erikkallen