Classes et méthodes génériques

Les génériques introduisent le concept de paramètres de type dans .NET. Les génériques permettent de concevoir des classes et des méthodes qui reportent la spécification d’un ou plusieurs paramètres de type jusqu’à ce que vous utilisiez la classe ou la méthode dans votre code. Par exemple, à l’aide d’un paramètre de type générique T, vous pouvez écrire une seule classe qui peut être utilisée par un autre code client sans impliquer le coût ou le risque des casts de runtime ou des opérations de boxing à l’exécution, comme illustré ici :

// Declare the generic class.
public class GenericList<T>
{
    public void Add(T input) { }
}
class TestGenericList
{
    private class ExampleClass { }
    static void Main()
    {
        // Declare a list of type int.
        GenericList<int> list1 = new GenericList<int>();
        list1.Add(1);

        // Declare a list of type string.
        GenericList<string> list2 = new GenericList<string>();
        list2.Add("");

        // Declare a list of type ExampleClass.
        GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
        list3.Add(new ExampleClass());
    }
}

Les classes et méthodes génériques combinent la réutilisation, la sécurité des types et l’efficacité d’une manière que leurs équivalents non génériques ne peuvent pas. Les paramètres de type générique sont remplacés par les arguments de type pendant la compilation. Dans l’exemple précédent, le compilateur remplace T par int. Les génériques sont plus fréquemment utilisés dans des collections et des méthodes qui agissent sur eux. L’espace de noms System.Collections.Generic contient plusieurs classes de collection génériques. Les collections non génériques, telles que ArrayList ne sont pas recommandées et sont conservées uniquement à des fins de compatibilité. Pour plus d’informations, consultez Génériques en .NET.

Bien sûr, vous pouvez également créer des types et des méthodes génériques personnalisés pour fournir vos propres solutions et modèles de conception généralisés qui soient efficaces et de type sécurisé. L’exemple de code suivant montre une classe de liste liée générique simple, à des fins de démonstration. (Dans la plupart des cas, il est préférable d’utiliser la classe List<T> fournie par .NET plutôt que de créer sa propre classe). Le paramètre de type T est utilisé dans plusieurs emplacements où un type concret serait généralement utilisé pour indiquer le type de l’élément stocké dans la liste :

  • Comme le type d’un paramètre de méthode dans la méthodeAddHead.
  • Comme le type de retour de la propriété Data de la classe imbriquée Node.
  • Comme le type de membre privé data de la classe imbriquée.

T est disponible pour la classe imbriquée Node. Lorsque GenericList<T> est instanciée avec un type concret, par exemple en tant que GenericList<int>, chaque occurrence de T est remplacée par int.

// type parameter T in angle brackets
public class GenericList<T>
{
    // The nested class is also generic on T.
    private class Node
    {
        // T used in non-generic constructor.
        public Node(T t)
        {
            next = null;
            data = t;
        }

        private Node? next;
        public Node? Next
        {
            get { return next; }
            set { next = value; }
        }

        // T as private member data type.
        private T data;

        // T as return type of property.
        public T Data
        {
            get { return data; }
            set { data = value; }
        }
    }

    private Node? head;

    // constructor
    public GenericList()
    {
        head = null;
    }

    // T as method parameter type:
    public void AddHead(T t)
    {
        Node n = new Node(t);
        n.Next = head;
        head = n;
    }

    public IEnumerator<T> GetEnumerator()
    {
        Node? current = head;

        while (current != null)
        {
            yield return current.Data;
            current = current.Next;
        }
    }
}

L’exemple de code suivant montre comment le code client utilise la classe générique GenericList<T> pour créer une liste d’entiers. Si vous modifiez l’argument de type, le code suivant crée des listes de chaînes ou tout autre type personnalisé :

class TestGenericList
{
    static void Main()
    {
        // int is the type argument
        GenericList<int> list = new GenericList<int>();

        for (int x = 0; x < 10; x++)
        {
            list.AddHead(x);
        }

        foreach (int i in list)
        {
            System.Console.Write(i + " ");
        }
        System.Console.WriteLine("\nDone");
    }
}

Remarque

Les types génériques ne sont pas limités aux classes. Les exemples précédents utilisent des types class , mais vous pouvez définir des types génériques interface et struct, y compris les types record.

Vue d’ensemble des génériques

  • Utilisez des types génériques pour optimiser la réutilisation de code, la sécurité des types et les performances.
  • L’utilisation la plus courante des génériques est de créer des classes de collection.
  • La bibliothèque de classes de .NET contient plusieurs nouvelles classes de collection génériques dans l’espace de noms System.Collections.Generic. Les collections génériques doivent être utilisées chaque fois que c’est possible, à la place de classes comme ArrayList dans l’espace de noms System.Collections.
  • Vous pouvez créer vos propres interfaces, classes, méthodes, événements et délégués génériques.
  • Les classes génériques peuvent être contraintes pour permettre l’accès aux méthodes sur des types de données particuliers.
  • Vous pouvez obtenir des informations au moment de l’exécution sur les types utilisés dans un type de données générique à l’aide de la réflexion.

spécification du langage C#

Pour plus d'informations, voir la spécification du langage C#.

Voir aussi