Obecné třídy a metody
Obecné typy představují koncept parametrů typu do .NET. Obecné typy umožňují navrhovat třídy a metody, které odvozují specifikaci jednoho nebo více parametrů typu, dokud v kódu nepoužijete třídu nebo metodu. Například pomocí parametru T
obecného typu můžete napsat jednu třídu, kterou může použít jiný kód klienta, aniž by se zabízly náklady nebo riziko operací přetypování za běhu nebo boxování, jak je znázorněno zde:
// 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());
}
}
Obecné třídy a metody kombinují opakovaně použitelnost, bezpečnost typů a efektivitu způsobem, který jejich negenerické protějšky nemohou. Parametry obecného typu se během kompilace nahradí argumenty typu. V předchozím příkladu kompilátor nahradí T
znakem int
. Obecné typy se nejčastěji používají s kolekcemi a metodami, které s nimi pracují. Obor System.Collections.Generic názvů obsahuje několik obecných tříd kolekce. Negenerické kolekce, například ArrayList se nedoporučují a uchovávají se jenom pro účely kompatibility. Další informace naleznete v tématu Obecné typy v .NET.
Můžete také vytvořit vlastní obecné typy a metody, které poskytují vlastní generalizovaná řešení a vzory návrhu, které jsou typově bezpečné a efektivní. Následující příklad kódu ukazuje jednoduchou obecnou třídu propojeného seznamu pro demonstrační účely. (Ve většině případů byste měli místo vytváření vlastních prostředků použít List<T> třídu, kterou poskytuje .NET.) Parametr T
typu se používá v několika umístěních, kde by byl obvykle použit konkrétní typ k označení typu položky uložené v seznamu:
- Jako typ parametru metody v
AddHead
metodě. - Jako návratový
Data
typ vlastnosti ve vnořenéNode
třídě. - Jako typ soukromého člena
data
ve vnořené třídě.
T
je k dispozici pro vnořenou Node
třídu. Je-li GenericList<T>
vytvořena instance s konkrétním typem, například jako , GenericList<int>
každý výskyt T
je nahrazen 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;
}
}
}
Následující příklad kódu ukazuje, jak klientský kód používá obecnou GenericList<T>
třídu k vytvoření seznamu celých čísel. Pokud změníte argument typu, následující kód vytvoří seznamy řetězců nebo jiného vlastního typu:
// 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");
Poznámka:
Obecné typy nejsou omezeny na třídy. Předchozí příklady používají class
typy, ale můžete definovat obecné interface
typy a struct
typy včetně record
typů.
Přehled obecných typů
- Pomocí obecných typů můžete maximalizovat opakované použití kódu, bezpečnost typů a výkon.
- Nejběžnějším použitím obecných typů je vytvoření tříd kolekce.
- Knihovna tříd .NET obsahuje v oboru názvů několik obecných tříd System.Collections.Generic kolekce. Obecné kolekce by měly být použity, kdykoli je to možné, místo tříd, jako ArrayList je v System.Collections oboru názvů.
- Můžete vytvořit vlastní obecná rozhraní, třídy, metody, události a delegáty.
- Obecné třídy mohou být omezeny tak, aby umožňovaly přístup k metodám u konkrétních datových typů.
- Informace o typech, které se používají v obecném datovém typu, můžete získat za běhu pomocí reflexe.
specifikace jazyka C#
Další informace najdete v tématu Specifikace jazyka C#.