したがって、私が尋ねたい質問は次のとおりです。
抽象クラス内から継承ツリーを (つまり、より特殊化されたクラスに向かって) キャストすることは許されますか、それとも良いことでしょうか?
さて、それが良いことに使えると私が思う理由の例。
最近、C# でBitTorrent プロトコルから Bencoding を実装しました。データをどのように表現するかという単純な問題です。こうすることにしたのですが、
Bencoded 文字列を必要な構造にデコードするために使用されるなど、いくつかの基本的な機能を提供するabstract BItem
クラスがあります。static BItem Decode(string)
、、、およびの4 つの派生クラスもありBString
、エンコードされる 4 つの異なるデータ型を表します。さて、ここがトリッキーな部分です。また、これらのデータ型の配列のような性質にアクセスできるように、それぞれとアクセサーを持っています。BInteger
BList
BDictionary
BList
BDictionary
this[int]
this[string]
潜在的に恐ろしい部分が今来ています:
BDictionary torrent = (BDictionary) BItem.DecodeFile("my.torrent");
int filelength = (BInteger)((BDictionary)((BList)((BDictionary)
torrent["info"])["files"])[0])["length"];
さて、あなたは写真を手に入れます... 痛い、それは脳は言うまでもなく、目にも難しいです. そこで、抽象クラスに何か特別なものを導入しました。
public BItem this[int index]
{
get { return ((BList)this)[index]; }
}
public BItem this[string index]
{
get { return ((BDictionary)this)[index]; }
}
これで、古いコードを次のように書き直すことができます。
BDictionary torrent = (BDictionary)BItem.DecodeFile("my.torrent");
int filelength = (BInteger)torrent["info"]["files"][0]["length"];
うわー、さてさて、はるかに読みやすいコードです。しかし、サブクラスの知識を抽象クラスに暗示するために魂の一部を売っただけですか?
編集:いくつかの回答が寄せられたことに応じて、構造が可変であるため、この特定の質問については完全に軌道に乗っていませんtorrent["info"]["files"][0]["length"]
。torrent["announce-list"][0][0]
そこに。ジェネリックは、少なくともこの問題では進むべき道ではありません:(。私がリンクした仕様をクリックしてください。それは4つの小さなドットポイントだけです。