読者です 読者をやめる 読者になる 読者になる

mikan_daisuki’s blog

IT系サラリーマンの日記。前職ではスマホゲームを、現在はアプリを作ってます。



c#のジェネリック(Dictionary, List etc)は安易にキャストする前に必ず注意すること

この前ハマったコード

gist.github.com

例えばobjectクラスからDictionary<string, object>へはキャストできるけど、

Dictionary<string, Dictionary<string, object>>へはキャストできなかったりする。

直感的に、これでいけそうに見えませんか?

そもそもジェネリックとは

qiita.com

これが簡単でわかりやすい。テンプレートと呼ばれるものらしい。

プログラミングにおけるテンプレートは、静的型付けのC++データ型にとらわれずにコードを書くことを可能にする機能であり、

引用元: テンプレート (プログラミング) - Wikipedia

ひとつのソースコードを使って、型をパラメータ指定にすることで複数の型で同じロジックを流用できる、という機能のようだ。

挙動が中途半端

とかなら挙動としてわかりやすいが

ジェネリックのキャストについては、いけるケースといけないケース

があってよくわからない・・・

  • Dictionary<string, object>は、いける
  • Dictionary<string, Dictionary<string, object>>は、いけない
  • List<object>は、いける
  • List<uint>は、いけない

悲しみを感じながら今後は・・

確実に非ジェネリック(System.Collectionsの方のIList, IDictionary)にキャストしていくのが

間違いない。c#のキャスト機能(()演算子、as演算子)は、ジェネリックを考慮しきれてない

ということだろう。

gist.github.com

まとめ

  • ジェネリクス、つまりDictionary<T1, T2>とかの型パラメータ(T1やT2)は簡単にキャストできません!
  • キャストするときは、まずは非ジェネリック(IList, IDictionary)の利用を考える