2011年2月27日日曜日

いつも思うけどC#のジェネリックスが不完全

さて、ここにShapeクラスがあるとします。これはシェイプ(形)の情報を持つクラスです。

それを継承したCircleクラスというのもあるとします。円ですね。

では、円のリストを作ってみましょう
var clist = new List<circle>();

Listジェネリッククラスを使えば簡単ですね。

さて、ここまでは良いのですが、この円のリストをシェイプのリストにキャストしようとすると失敗します。コンパイルエラーです。

var slist = clist as List<shape>;

仮にasではなくキャスト演算子を使ったとしても失敗です。
ジェネリッククラスで指定された型はアップキャストできないわけです。

おかしくない? ねえ、おかしくない?

円のリストというのは、当然形のリストでもあるわけですから型変換できてしかるべきですよね。

実は昔、似たような問題に出くわして設計できねー!ってなって1年近くプログラムから離れた時期がありました。
……今昔の再現をしてたら同じ問題でした。



<すぐさま追記>

Listジェネリッククラスについては解決法がありました。
ConvertAllメソッドを使います。


var slist = clist.ConvertAll<ishape>(c => c as IShape);

うーむ。なるべくシンプルにしたのですがややこしいですね。
しかもConvertAllメソッドか、同様の仕組みを持つクラスにしか利用できないという。言語レベルでできるようにしてほしいものです。

0 件のコメント:

コメントを投稿