Generische Klasse und Methoden

Generics führt das Konzept von Typparametern in .NET ein. Generics ermöglichen das Entwerfen von Klassen und Methoden, die die Spezifikation eines oder mehrerer Typparameter zurückstellen, bis Sie die Klasse oder Methode im Code verwenden. Indem Sie z. B. einen generischen Typparameter „T“ verwenden, können Sie eine einzelne Klasse schreiben, die von anderem Clientcode verwendet werden kann, ohne dass die Kosten und Risiken von Umwandlungen zur Laufzeit oder Boxingvorgängen anfallen, wie im Folgenden gezeigt:

// 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());
    }
}

Generische Klassen und Methoden vereinen Wiederverwendbarkeit, Typsicherheit und Effizienz auf eine Weise, wie es ihre nicht generischen Gegenstücke nicht können. Generische Typparameter werden während der Kompilierung durch die Typargumente ersetzt. Im vorherigen Beispiel ersetzt der Compiler T durch int. Generics werden am häufigsten für Auflistungen und deren Methoden verwendet. Der Namespace System.Collections.Generic enthält eine Reihe von auf Generics basierenden Auflistungsklassen. Die nicht generischen Auflistungen wie ArrayList werden nicht empfohlen und werden nur aus Kompatibilitätsgründen gepflegt. Weitere Informationen finden Sie unter Generics in .NET.

Sie können auch benutzerdefinierte generische Typen und Methoden erstellen, um Ihre eigenen typsicheren und effizienten Lösungen und Entwurfsmuster bereitzustellen. Das folgende Codebeispiel zeigt eine einfache generische linked-list-Klasse zur Veranschaulichung. (In den meisten Fällen sollten Sie die Klasse List<T> verwenden, die von .NET bereitgestellt wird, anstatt eine eigene Klasse zu erstellen.) Der Typparameter T wird an mehreren Stellen verwendet, wo für gewöhnlich ein konkreter Typ verwendet werden würde, um den Typ des Elements anzugeben, das in der Liste gespeichert wurde:

  • Als Typ eines Methodenparameters in der Methode AddHead.
  • Als Rückgabetyp der Eigenschaft Data in der geschachtelten Klasse Node.
  • Als Typ des privaten Members data in der geschachtelten Klasse.

T ist für die geschachtelte Node-Klasse verfügbar. Wenn GenericList<T> mit einem konkreten Typ instanziiert wird, beispielsweise als GenericList<int>, wird jedes T durch int ersetzt.

// 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;
        }
    }
}

Das folgende Codebeispiel zeigt, wie Clientcode die generische Klasse GenericList<T> verwendet, um eine Ganzzahlliste zu erstellen. Wenn Sie das Typargument ändern, erstellt der folgende Code Listen mit Zeichenfolgen oder einem anderen benutzerdefinierten Typ:

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");
    }
}

Hinweis

Generische Typen sind nicht auf Klassen beschränkt. In den vorangehenden Beispielen werden class-Typen verwendet. Sie können jedoch generische interface- und struct-Typen definieren, einschließlich record-Typen.

Übersicht über Generics

  • Verwenden Sie Generics, um die Wiederverwendung von Code, Typsicherheit und Leistung zu maximieren.
  • Generics werden am häufigsten zur Erstellung von Auflistungsklassen verwendet.
  • Die .NET Framework-Klassenbibliothek enthält eine Reihe generischer Sammlungsklassen im System.Collections.Generic-Namespace. Die generischen Sammlungen sollten nach Möglichkeit immer anstelle von Klassen wie ArrayList im System.Collections-Namespace verwendet werden.
  • Sie können Ihre eigenen generischen Schnittstellen, Klassen, Methoden, Ereignisse und Delegaten erstellen.
  • Generische Klassen können in der Aktivierung des Zugriffs auf Methoden für bestimmte Datentypen beschränkt sein.
  • Informationen zu den Typen, die in einem generischen Datentyp verwendet werden, können Sie zur Laufzeit unter Verwendung von Reflexion abrufen.

C#-Sprachspezifikation

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation.

Siehe auch