Vorteile von Generika (C#-Programmierhandbuch)Benefits of Generics (C# Programming Guide)

Generika bieten die Lösung für eine Einschränkung in früheren Versionen der Common Language Runtime und der C#-Sprache, bei der Generalisierung durch die Umwandlung von Typen in den und aus dem universellen Basistyp Object erfolgt.Generics provide the solution to a limitation in earlier versions of the common language runtime and the C# language in which generalization is accomplished by casting types to and from the universal base type Object. Durch Erstellen einer generischen Klasse können Sie eine Auflistung erstellen, die zur Kompilierzeit typsicher ist.By creating a generic class, you can create a collection that is type-safe at compile-time.

Die Einschränkungen bei der Verwendung nicht generischer Auflistungsklassen können durch das Schreiben eines kurzen Programms veranschaulicht werden, das die Auflistungsklasse ArrayList aus der .NET Framework-Klassenbibliothek verwendet.The limitations of using non-generic collection classes can be demonstrated by writing a short program that uses the ArrayList collection class from the .NET Framework class library. ArrayList ist eine äußerst praktische Auflistungsklasse, die unverändert verwendet werden kann, um einen beliebigen Verweis- oder Werttyp zu speichern.ArrayList is a highly convenient collection class that can be used without modification to store any reference or value type.

// The .NET Framework 1.1 way to create a list:
System.Collections.ArrayList list1 = new System.Collections.ArrayList();
list1.Add(3);
list1.Add(105);

System.Collections.ArrayList list2 = new System.Collections.ArrayList();
list2.Add("It is raining in Redmond.");
list2.Add("It is snowing in the mountains.");

Aber diese Vereinfachung ist mit Nachteilen verbunden.But this convenience comes at a cost. Jeder Verweis- oder Werttyp, der zu einem ArrayList-Objekt hinzugefügt wird, wird implizit nach oben in Object umgewandelt.Any reference or value type that is added to an ArrayList is implicitly upcast to Object. Wenn es sich bei den Elementen um Werttypen handelt, müssen Sie mittels Boxing geschachtelt werden, wenn sie zur Liste hinzugefügt werden, und mittels Unboxing wieder entpackt werden, wenn sie abgerufen werden.If the items are value types, they must be boxed when they are added to the list, and unboxed when they are retrieved. Sowohl die Umwandlung von Typen als auch das Boxing und Unboxing beeinträchtigen die Leistung; die Auswirkung von Boxing und Unboxing kann sehr groß sein, wenn Sie lange Auflistungen durchlaufen müssen.Both the casting and the boxing and unboxing operations decrease performance; the effect of boxing and unboxing can be very significant in scenarios where you must iterate over large collections.

Die andere Einschränkung ist die fehlende Typüberprüfung zur Kompilierzeit; da ein ArrayList-Objekt alles in Object umwandelt, kann zur Kompilierzeit nicht vermieden werden, dass der Clientcode etwas wie das Folgende macht:The other limitation is lack of compile-time type checking; because an ArrayList casts everything to Object, there is no way at compile-time to prevent client code from doing something such as this:

System.Collections.ArrayList list = new System.Collections.ArrayList();
// Add an integer to the list.
list.Add(3);
// Add a string to the list. This will compile, but may cause an error later.
list.Add("It is raining in Redmond.");

int t = 0;
// This causes an InvalidCastException to be returned.
foreach (int x in list)
{
    t += x;
}

Zwar ist das Erstellen einer heterogenen Auflistung durchaus akzeptabel und manchmal beabsichtigt, aber das Kombinieren von Zeichenfolgen und ints in einem einzigen ArrayList-Objekt ist meist eher ein Programmierfehler, der bis zur Laufzeit nicht erkannt wird.Although perfectly acceptable and sometimes intentional if you are creating a heterogeneous collection, combining strings and ints in a single ArrayList is more likely to be a programming error, and this error will not be detected until runtime.

In den Versionen 1.0 und 1.1 der C#-Sprache können Sie generalisierten Code in der Auflistung der .NET Framework-Basisklassenbibliothek nur vermeiden, wenn Sie Ihre eigenen typspezifischen Auflistungen schreiben.In versions 1.0 and 1.1 of the C# language, you could avoid the dangers of generalized code in the .NET Framework base class library collection classes only by writing your own type specific collections. Da eine solche Klasse nur für einen Datentyp verwendet werden kann, verlieren Sie so aber die Vorteile der Generalisierung und müssen die Klasse für jeden Typ, der gespeichert wird, umschreiben.Of course, because such a class is not reusable for more than one data type, you lose the benefits of generalization, and you have to rewrite the class for each type that will be stored.

Was ArrayList und ähnliche Klassen eigentlich benötigen, ist eine Möglichkeit für den Clientcode, instanzweise den zu verwendenden Datentyp anzugeben.What ArrayList and other similar classes really need is a way for client code to specify, on a per-instance basis, the particular data type that they intend to use. Dann wäre keine Typumwandlung nach oben zu T:System.Object mehr nötig, und der Compiler könnte eine Typüberprüfung durchführen.That would eliminate the need for the upcast to T:System.Object and would also make it possible for the compiler to do type checking. Das heißt, dass ArrayList einen Typparameter benötigt.In other words, ArrayList needs a type parameter. Genau das bieten Generika.That is exactly what generics provide. In der generischen List<T>-Auflistung im N:System.Collections.Generic-Namespace sieht der gleiche Vorgang des Hinzufügens von Elementen zur Auflistung ungefähr so aus:In the generic List<T> collection, in the N:System.Collections.Generic namespace, the same operation of adding items to the collection resembles this:

// The .NET Framework 2.0 way to create a list
List<int> list1 = new List<int>();

// No boxing, no casting:
list1.Add(3);

// Compile-time error:
// list1.Add("It is raining in Redmond.");

Bei Clientcode ist im Vergleich von List<T> mit ArrayList als Syntax lediglich das Typargument in der Deklaration und Instanziierung hinzugekommen.For client code, the only added syntax with List<T> compared to ArrayList is the type argument in the declaration and instantiation. Zwar ist die Codierung etwas komplexer, aber dafür können Sie eine Liste erstellen, die nicht nur sicherer als ArrayList ist, sondern auch bedeutend schneller, vor allem wenn es sich bei den Listenelementen um Werttypen handelt.In return for this slightly more coding complexity, you can create a list that is not only safer than ArrayList, but also significantly faster, especially when the list items are value types.

Siehe auchSee Also

System.Collections.Generic
C#-ProgrammierhandbuchC# Programming Guide
Einführung in GenerikaIntroduction to Generics
Boxing und UnboxingBoxing and Unboxing
Best Practices für AuflistungenCollections Best Practices