The question I want to ask is thus:
Is casting down the inheritance tree (ie. towards a more specialiased class) from inside an abstract class excusable, or even a good thing, or is it always a poor choice with better options available?
Now, the example of why I think it can be used for good.
I recently implemented Bencoding from the BitTorrent protocol in C#. A simple enough problem, how to represent the data. I chose to do it this way,
We have an abstract BItem
class, which provides some basic functionality, including the static BItem Decode(string)
that is used to decode a Bencoded string into the necessary structure.
There are also four derived classes, BString
, BInteger
, BList
and BDictionary
, representing the four different data types that be encoded. Now, here is the tricky part. BList
and BDictionary
have this[int]
and this[string]
accessors respectively to allow access to the array-like qualities of these data types.
The potentially horrific part is coming now:
BDictionary torrent = (BDictionary) BItem.DecodeFile("my.torrent");
int filelength = (BInteger)((BDictionary)((BList)((BDictionary)
torrent["info"])["files"])[0])["length"];
Well, you get the picture... Ouch, that's hard on the eyes, not to mention the brain. So, I introduced something extra into the abstract class:
public BItem this[int index]
{
get { return ((BList)this)[index]; }
}
public BItem this[string index]
{
get { return ((BDictionary)this)[index]; }
}
Now we could rewrite that old code as:
BDictionary torrent = (BDictionary)BItem.DecodeFile("my.torrent");
int filelength = (BInteger)torrent["info"]["files"][0]["length"];
Wow, hey presto, MUCH more readable code. But did I just sell part of my soul for implying knowledge of subclasses into the abstract class?
EDIT: In response to some of the answers coming in, you're completely off track for this particular question since the structure is variable, for instance my example of torrent["info"]["files"][0]["length"]
is valid, but so is torrent["announce-list"][0][0]
, and both would be in 90% of torrent files out there. Generics isn't the way to go, with this problem atleast :(. Have a click through to the spec I linked, it's only 4 small dot-points large.