PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C#] Rekursive Generics?


Xmas
2006-05-16, 15:05:56
Ich habe einige Klassen A0, A1, ..., An, die jeweils voneinander Erben und etwa folgendermaßen aussehen sollen:
public abstract class A0
{
protected static Object StaticGet(String key) { return null; }
public virtual Object Get(String key);
}

public class A<n>: A<n-1>
{
protected static Object StaticGet(String key)
{
if(classDict.ContainsKey(key))
return classDict[key];
else
return base.StaticGet(key);
}

public override Object Get(String key)
{
if(instanceDict.ContainsKey(key))
return instanceDict[key];
else
return StaticGet(key);
}

protected Dictionary<String, Object> instanceDict;
protected static Dictionary<String, Object> classDict;
}
Der Code dient nur zur Illustration und compiliert so natürlich nicht.

Zweck: Ich will Objekte, die per String benannte "Eigenschaften" besitzen. Hat eine Instanz eine bestimmte Eigenschaft nicht, fragt sie bei der Klasse nach, diese wiederum bei ihrer Basisklasse, usw.

Beispiel:
Die Klasse Säugetier hat die Eigenschaft "Beine" = 4.
Die Klasse Mensch hat die Eigenschaft "Beine" = 2.
Die Klassen Hund und Mensch erben von Säugetier.
Eine bestimmte Instanz von Hund hat die Eigenschaft "Beine" = 3. ;(

DreibeinigerHund.Get("Beine") soll 3 zurückliefern. EinAndererHund.Get("Beine") soll 4 zurückliefern, nämlich jene die im statischen Dictionary der Klasse Säugetier gespeichert ist.

Nur, wie realisiere ich sowas in C# ohne dass ich für jede Klasse den oben aufgeführten Code nochmal schreiben muss? Rekursive Generics gehen ja leider nicht, also sowas:
public class A <T> : T {}
"base" geht in static-Methoden nicht, also darf StaticGet nicht static sein (was aber kein Problem sein sollte).

Und ich will auch nicht in jeder neuen Klasse classDict deklarieren, nur offensichtlich ist das nötig weil sonst das classDict der Basisklasse verwendet würde.


Oder wäre es sinnvoll, zu jeder Klasse ein Singleton EigenschaftenContainer zu erzeugen, und jeder Klasse ein statisches Feld "baseEigenschaftenContainer" hinzuzufügen? So dass die Klassen durch Referenzen miteinander verbunden sind, nicht mehr nur durch Vererbung.

Obligaron
2006-05-16, 19:05:42
Hallo,

man muss ja nicht alles mit Generics machen. Ein Lösungswerk wäre über ein static Dict in der Basis Klasse und dann weiter verebend. Siehe Beispiel:


public class A0
{
public object Get(string key)
{
if (instanceDict.ContainsKey(key))
return instanceDict[key];
else
return StaticGet(key);
}
public void Set(string key, object obj)
{
instanceDict[key] = obj;
}
public object StaticGet(string key)
{
return StaticGet(this.GetType(),key);
}
public object StaticGet(Type type, string key)
{
if (classDict.ContainsKey(type))
{
Dictionary<string, object> myDict = classDict[type];
if (myDict.ContainsKey(key))
return myDict[key];
}
if (type.BaseType == null)
return null;
else
return StaticGet(type.BaseType, key);
}
protected static Dictionary<Type, Dictionary<string, object>> classDict = new Dictionary<Type, Dictionary<string, object>>();
protected Dictionary<string, object> instanceDict = new Dictionary<string, object>();
}

public class A1 : A0
{
static A1()
{
Dictionary<string, object> myDict = new Dictionary<string, object>();
classDict[typeof(A1)] = myDict;
myDict["Beine"] = 4;
}
}
public class A2 : A1
{
static A2()
{
Dictionary<string, object> myDict = new Dictionary<string, object>();
classDict[typeof(A2)] = myDict;
myDict["Beine"] = 2;
}
}



Und hier das Beispiel (mal kurz durchgetest)

A2 myMensch = new A2();
A1 myTier = new A1();
A1 myTierMit3Beinen = new A1();
myTierMit3Beinen.Set("Beine", 3);
object objMenschBeine = myMensch.Get("Beine");
object objTier = myTier.Get("Beine");
object objTierMit3Beinen = myTierMit3Beinen.Get("Beine");


Ich hoffe das passt ca. von den Anforderungen.

Gruß,
obli

Demirug
2006-05-16, 19:46:40
Xmas, schon mal an Attribute gedacht?

Xmas
2006-05-16, 21:02:25
Obligaron[/POST]']Hallo,

man muss ja nicht alles mit Generics machen. Ein Lösungswerk wäre über ein static Dict in der Basis Klasse und dann weiter verebend. Siehe Beispiel:
Das scheint mir recht brauchbar zu sein, danke!

Demirug[/POST]']Xmas, schon mal an Attribute gedacht?
Inwiefern? Ich habe bisher noch recht wenig mit Attributen gemacht, ich weiß jetzt allerdings nicht genau was dir da vorschwebt.