Die Frage, die ich stellen möchte, ist folgende:
Ist Casting nach unten den Vererbungsbaum (dh. in Richtung eines more specialiased Klasse) von innerhalb einer abstrakten Klasse entschuldbar, oder sogar eine gute Sache, oder ist es immer eine schlechte Wahl mit besseren Optionen zur Verfügung?
Nun ein Beispiel dafür, warum ich glaube, dass sie zum Guten eingesetzt werden kann.
Ich habe vor kurzem Bencoding des BitTorrent-Protokolls in C#. Ein einfaches Problem, wie man die Daten darstellen kann. Ich habe mich für diesen Weg entschieden,
Wir haben eine abstract BItem
Klasse, die einige grundlegende Funktionen bietet, darunter die static BItem Decode(string)
die zur Dekodierung einer bencodierten Zeichenfolge in die erforderliche Struktur verwendet wird.
Außerdem gibt es vier abgeleitete Klassen, BString
, BInteger
, BList
y BDictionary
, die die vier verschiedenen zu kodierenden Datentypen darstellen. Jetzt kommt der schwierige Teil. BList
y BDictionary
haben this[int]
y this[string]
um den Zugriff auf die array-ähnlichen Eigenschaften dieser Datentypen zu ermöglichen.
Der potenziell schreckliche Teil kommt jetzt:
BDictionary torrent = (BDictionary) BItem.DecodeFile("my.torrent");
int filelength = (BInteger)((BDictionary)((BList)((BDictionary)
torrent["info"])["files"])[0])["length"];
Nun, Sie verstehen, was ich meine... Autsch, das ist anstrengend für die Augen, ganz zu schweigen vom Gehirn. Also habe ich etwas Zusätzliches in die abstrakte Klasse eingeführt:
public BItem this[int index]
{
get { return ((BList)this)[index]; }
}
public BItem this[string index]
{
get { return ((BDictionary)this)[index]; }
}
Jetzt könnten wir den alten Code wie folgt umschreiben:
BDictionary torrent = (BDictionary)BItem.DecodeFile("my.torrent");
int filelength = (BInteger)torrent["info"]["files"][0]["length"];
Wow, hey presto, VIEL besser lesbarer Code. Aber habe ich gerade einen Teil meiner Seele verkauft, weil ich der abstrakten Klasse Kenntnisse über Unterklassen unterstellt habe?
EDIT: Als Antwort auf einige der eingegangenen Antworten sind Sie bei dieser speziellen Frage völlig auf dem Holzweg, da die Struktur variabel ist, zum Beispiel mein Beispiel torrent["info"]["files"][0]["length"]
ist gültig, aber das gilt auch für torrent["announce-list"][0][0]
und beides ist in 90 % der Torrent-Dateien vorhanden. Generics ist nicht der Weg zu gehen, mit diesem Problem zumindest :(. Klicken Sie sich durch die Spezifikation, die ich verlinkt, es ist nur 4 kleine Punkt-Punkte groß.