Entwickler-Ecke

C# - Die Sprache - Generische Klassen "allgemein" verwenden


wulfskin - Do 04.12.08 16:08
Titel: Generische Klassen "allgemein" verwenden
Hallo,

sorry erstmal für den unverständlichen Titel. Mir ist nichts besseres eingefallen.

Zum Problem: Ich möchte eine Baumstruktur mit mehreren unterschiedlichen Datentypen füllen. Dafür habe ich eine generische Klasse erstellt, welche Funktionen zur Bearbeitung der einzelnen Datentypen bereitstellt.
Der Baum selber soll nun die generischen Klassen als Kinder haben, aber ohne vorher festzulegen, welchen Typ diese haben müssen.

Wie löse ich das Problem?

Beispiel:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
public class Daten<T>
{
  // verschiedene Eigenschaften vom Typ T
}

public class Knoten
{
  public Knoten Parent;
  public Daten<????> FirstChild;     //wie implementiere ich jetzt Kinder und Geschwister von der generischen Klasse
  public Daten<????> FirstSibling;   //ohne vorher zu wissen von welchem Typ diese sind?
}


P.S.: Kann man where auch auf Klassen anwenden? Hätte gern sowas wie

C#-Quelltext
1:
public class Daten<T> where T: String, Int32.....                    

Gruß Hape!


Th69 - Do 04.12.08 16:34

Na, dann antworte ich mal, um zu helfen -)

Du solltest deine beiden Eigenschaften FirstChild und FirstSibling auf jeden Fall vom Typ Knoten machen (die Knoten sind untereinander verbunden, nicht die Daten).
Dann bekommt deine Knotenklasse nur noch EINE zusätzliche Eigenschaft mit den Daten.
Am einfachsten ist es, wenn du einfach ein Interface IDaten definierst und dieses dann als Typ für den Knoten verwendest. So braucht der Knoten nichts direkt von T zu wissen.

Wenn du jedoch deinen gesamten Baum, so anlegen willst, daß immer nur der selbe Datentyp für T benutzt wird, dann mach auch einfach den Baum sowie die Knoten generisch: Tree<T> und Knoten<T>.

Ich hoffe, dies reicht aus, um dir Hilfe zur Selbsthilfe zu geben...

P.S: 'where' kann man auch auf Klassen anwenden, jedoch sollten als Datentypen immer Schnittstellen (Interfaces) angegeben werden, sonst kann man ja keine Methoden auf die Objekte vom Typ T anwenden (außer die von Object). Es gibt auch noch 'class' und 'struct' als Möglichkeit, um nur Referenz- bzw. Werttypen zuzulassen.


JüTho - Do 04.12.08 18:07

Ergänzung zum PS von Th69: Ich meine, dass in der where-Klausel ohne Weiteres auch Klassen angegeben werden können. Aber das sind immer AND-Bedingungen. Deine (Hape) Idee mit "where: string, int" klappt also nicht. In einer vergleichbaren Situation hatte ich "where T: struct, IComparable" benutzt.

Zum Hauptproblem will ich lieber nichts sagen, weil ich mich mit Bäumen noch nicht befasst habe.

Jürgen


wulfskin - Do 04.12.08 22:18

Hallo,

danke für die Antworten. Was ich immer noch nicht verstehe: Wie kann ich den unterschiedliche Daten in einem Knoten speichern (am besten mit generischen Typen)?

Der Typ ist aber jeweils erst zur Laufzeit bekannt und muss dynamisch angelegt werden.

Gruß Hape!


Kha - Do 04.12.08 22:52

user profile iconwulfskin hat folgendes geschrieben Zum zitierten Posting springen:
Wie kann ich den unterschiedliche Daten in einem Knoten speichern (am besten mit generischen Typen)?
Dabei bringen dir Generics wenig, da der Compiler schlecht zur Kompilierzeit überprüfen kann, welchen Typ die Objekte zur Laufzeit haben. In den allermeisten Fällen interessiert einen aber der genaue Typ gar nicht, nämlich dann, wenn alle Objekte ein Interface implementieren und man sich nur für dessen Member interessiert. Dann kannst du das Interface als Typparameter benutzen und hast wieder eine typsichere Collection.