Note that there are some explanatory texts on larger screens.

plurals
  1. PO'Looser' typing in C# by casting down the inheritance tree
    text
    copied!<p>The question I want to ask is thus:</p> <p>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?</p> <p>Now, the example of why I think it can be used for good.</p> <p>I recently implemented <a href="http://www.bittorrent.org/beps/bep_0003.html#the-connectivity-is-as-follows" rel="nofollow noreferrer">Bencoding from the BitTorrent protocol</a> in C#. A simple enough problem, how to represent the data. I chose to do it this way,</p> <p>We have an <code>abstract BItem</code> class, which provides some basic functionality, including the <code>static BItem Decode(string)</code> that is used to decode a Bencoded string into the necessary structure.</p> <p>There are also four derived classes, <code>BString</code>, <code>BInteger</code>, <code>BList</code> and <code>BDictionary</code>, representing the four different data types that be encoded. Now, here is the tricky part. <code>BList</code> and <code>BDictionary</code> have <code>this[int]</code> and <code>this[string]</code> accessors respectively to allow access to the array-like qualities of these data types.</p> <p>The potentially horrific part is coming now:</p> <pre><code>BDictionary torrent = (BDictionary) BItem.DecodeFile("my.torrent"); int filelength = (BInteger)((BDictionary)((BList)((BDictionary) torrent["info"])["files"])[0])["length"]; </code></pre> <p>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:</p> <pre><code>public BItem this[int index] { get { return ((BList)this)[index]; } } public BItem this[string index] { get { return ((BDictionary)this)[index]; } } </code></pre> <p>Now we could rewrite that old code as:</p> <pre><code>BDictionary torrent = (BDictionary)BItem.DecodeFile("my.torrent"); int filelength = (BInteger)torrent["info"]["files"][0]["length"]; </code></pre> <p>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?</p> <p>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 <code>torrent["info"]["files"][0]["length"]</code> is valid, but so is <code>torrent["announce-list"][0][0]</code>, 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.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload