Mit generischen Klassen kann man Datentyp unabhängigen Aufbau einer Klasse erreichen. Das bedeutet, man kann dann ein Objekt der Klasse erzeugen und sagen, dass die Methoden dort eben mit diesen Datentyp arbeiten soll, dem wir dem Objekt übergeben. Auch eine dort deklarierte Variable ist eben der Typ, der übergeben wurde.
Dabei arbeitet man mit einem sogenannten Typ-Parameter, welcher ähnlich einem Platzhalter für einen Datentyp stehen soll. Deutlicher wird das vielleicht durch das folgende Beispiel:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class meineKlasse<T> { T _value; public meineKlasse(T t) { _value = t; } public void Write() { Console.WriteLine(_value); } } |
Die Klasse erhält einen Typenparameter T. Man könnte auch einen anderen Buchstaben nehmen (i.d.R. ist der erste immer ein T), oder durch Komma getrennt weitere Datentypen anfügen.
Etwas ungewöhnlicher sieht da die Klassen-Eigenschaft in der 2. Zeile aus. Denkt man sich das T weg, könnte dort ein int, string[], double oder sonstwas stehen.
Dann folgt ein Konstruktor, der dieser Eigenschaft nun einen Wert zuweist
und zum Schluss noch eine Methode, die diese Eigenschaft ausgibt.
Contraints
im oberen Beispiel hätte man rein theoretisch die Möglichkeit alle möglichen Datentypen zu setzen. Möchte man dies aber auf eine bestimmte Art von Datentypen beschränken, so gibt es eine where Klausel. Das Muster erinnert dann ein wenig an SQL.
Dann nimmt die Klasse folgende Bezeichnung ein:
1 |
class meineKlasse<T> where T : IComparable |
Dabei kann man daraus den Satz machen: „Filtere alle, die von der Elternklasse IComparable erben“. Dabei macht man sich am besten im Objektexplorer schlau, welche Einschränkungen man treffen möchte.
Möchte man ein Objekt erstellen und dieser Datentyp passt nicht unter das Gefilterte, wird bereits zur Entwicklungszeit ein Fehler angezeigt.
Login