Jochens Weblog

ESCde Developer Blog

  Home :: Kontakt :: RSS Feed
  12 Posts :: 0 Artikel :: 4 Kommentare :: 0 Trackbacks

Archiv

Post Kategorien

ESCde

ESCde Blogger

Generics sind eine sehr hübsche und unglaublich nützliche Angelegenheit. Allerdings gibt es hierbei auch manche Dinge, die nicht wirklich Intuitiv gelöst sind. Ein kleines Beispiel:

Sie haben eine Klasse A, von der zwei Klassen B und C erben. Da Sie sowohl viele B als auch viele C Objekte benötigen, benutzen Sie 2 Listen:

List<B> list_b = new List<B>(); List<C> list_c = new List<C>();

Angenommen, Sie möchten nun eine Methode schreiben, die auf Mengen von A Objekten operiert. Was liegt näher als eine Funktion wie folgt zu deklarieren:

public void MyMethod(List<A> list_a) { foreach (A a in list_a) { Do_Something_Important(a); } }

Nun sollten die beiden folgenden Aufrufe doch eigentlich ordnungsgemäß ihren Dienst verrichten:

MyMethod(list_b); MyMethod(list_c);

Leider bekommen Sie hier bereits beim Kompilieren eine Fehlermeldung. Die Typen List<A> und List<B> sind nicht kompatibel. Obwohl sich eine Vererbungshierarchie zwischen beiden Mengen logisch geradezu aufdrängt, gibt es keine. Die beiden Typen haben rein gar nichts gemeinsam. Sollte man deshalb also genötigt sein, Code doppelt zu schreiben? Je eine Methode MyMethod für List<B> und List<C>? Wenn Ihre Vererbungshierarchie etwas komplexer ist, wird das Problem gar noch schlimmer. Aber es gibt eine Lösung, auch ohne exzessives Quellcode-Copy-And-Paste: Bekämpfen Sie Generics mit Generics:

 

public static void MyMethod<type>(List<type> list_t) where type : A { foreach (A a in list_t) { Do_Something_Important(a); } }

Diese Methode ist nun selbst generisch. Sie übernimmt einen Typ-Parameter (type) und erwartet als Argument eine Liste mit Elementen vom Typ type. Allerdings schränken wir den Typparameter insoweit ein, dass er von der Klasse A erben muss. Somit können wir in der Funktion ohne hässliche Casts oder Ähnliches auf die Elemente der Liste zugreifen und unsere beiden Methodenaufrufe von oben (mit list_b und list_c als Parameter) werden erfolgreich durchgeführt. Der Trick hierbei ist, dass für jeden Parametertyp (List<B> und List<C>) vom Compiler eine eigene Version von MyMethod<type> angelegt wird. Man hat zwar weiterhin keine "echte" Vererbung zwischen den verschiedenen Listen, allerdings hat man zumindest die mehrfache Implementierung von MyMethod an den Compiler delegiert.

veröffentlicht am 21.02.2007 10:34

Kommentare

Bisher kein Feedback.

Kommentar abgeben

Titel:
Name:
Email:
(wird nicht angezeigt!)
Homepage:
Feedback:
Please add 1 and 4 and type the answer here: