Dela via


Allmänna klasser och metoder

Generics introducerar begreppet typparametrar för .NET. Generiska objekt gör det möjligt att utforma klasser och metoder som skjuter upp specifikationen för en eller flera typparametrar tills du använder klassen eller metoden i koden. Genom att till exempel använda en generisk typparameter Tkan du skriva en enda klass som annan klientkod kan använda utan att medföra kostnaden eller risken för körningsgjutningar eller boxningsåtgärder, som du ser här:

// Declare the generic class.
public class GenericList<T>
{
    public void Add(T item) { }
}

public class ExampleClass { }

class TestGenericList
{
    static void Main()
    {
        // Create a list of type int.
        GenericList<int> list1 = new();
        list1.Add(1);

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

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

Generiska klasser och metoder kombinerar återanvändbarhet, typsäkerhet och effektivitet på ett sätt som deras icke-generiska motsvarigheter inte kan. Generiska typparametrar ersätts med typargumenten under kompilering. I föregående exempel ersätter T kompilatorn med int. Generiska program används oftast med samlingar och de metoder som fungerar på dem. Namnområdet System.Collections.Generic innehåller flera generiska samlingsklasser. Icke-generiska samlingar, till exempel ArrayList rekommenderas inte och underhålls endast i kompatibilitetssyfte. Mer information finns i Generiska objekt i .NET.

Du kan också skapa anpassade generiska typer och metoder för att tillhandahålla egna generaliserade lösningar och designmönster som är typsäkra och effektiva. I följande kodexempel visas en enkel allmän länkad listklass i demonstrationssyfte. (I de flesta fall bör du använda klassen List<T> som tillhandahålls av .NET i stället för att skapa din egen.) Typparametern T används på flera platser där en betongtyp vanligtvis används för att ange vilken typ av objekt som lagras i listan:

  • Som typ av en metodparameter i AddHead metoden.
  • Som returtyp för Data egenskapen i den kapslade Node klassen.
  • Som typen av privat medlem data i den kapslade klassen.

T är tillgänglig för den kapslade Node klassen. När GenericList<T> instansieras med en betongtyp, till exempel som en GenericList<int>, ersätts varje förekomst av T med int.

// Type parameter T in angle brackets.
public class GenericList<T>
{
    // The nested class is also generic, and
    // holds a data item of type T.
    private class Node(T t)
    {
        // T as property type.
        public T Data { get; set; } = t;

        public Node? Next { get; set; }
    }

    // First item in the linked list
    private Node? head;

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

    // T in method return type.
    public IEnumerator<T> GetEnumerator()
    {
        Node? current = head;

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

I följande kodexempel visas hur klientkoden använder den generiska GenericList<T> klassen för att skapa en lista med heltal. Om du ändrar typargumentet skapar följande kod listor med strängar eller någon annan anpassad typ:

// A generic list of int.
GenericList<int> list = new();

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

// Write them to the console.
foreach (int i in list)
{
    Console.WriteLine(i);
}

Console.WriteLine("Done");

Kommentar

Generiska typer är inte begränsade till klasser. I föregående exempel används class typer, men du kan definiera generiska interface typer och struct typer, inklusive record typer.

Översikt över generiska data

  • Använd allmänna typer för att maximera återanvändning av kod, typsäkerhet och prestanda.
  • Den vanligaste användningen av generiska läkemedel är att skapa samlingsklasser.
  • .NET-klassbiblioteket innehåller flera generiska samlingsklasser i System.Collections.Generic namnområdet. De generiska samlingarna ska användas när det är möjligt i stället för klasser som ArrayList i System.Collections namnområdet.
  • Du kan skapa egna allmänna gränssnitt, klasser, metoder, händelser och ombud.
  • Allmänna klasser kan begränsas för att ge åtkomst till metoder för vissa datatyper.
  • Du kan hämta information vid körning om de typer som används i en allmän datatyp med hjälp av reflektion.

Språkspecifikation för C#

Mer information finns i C#-språkspecifikationen.

Se även