コレクション初期化子と ICollection
おもしろい記事を見つけて読みふけってしまったので、おもしろいとこだけぎゅぎゅっと抜粋。
via http://blogs.msdn.com/madst/archive/2006/10/10/What-is-a-collection_3F00_.aspx
コレクション初期化子の設計話。なんで「IEnumerable + Add メソッド」なんて変な設計なのさ?って疑問への答え。
駄訳
コレクションとは何か?
ICollection は役にたたない、失敗だった。そして ICollection
誰もは言いすぎた。でも、コレクション初期化子を設計する際、LINQ + リフレクションで .NET フレームワークを調べてみたら、たった14クラスしか使っていなかった(・・;
コレクションって何よ?もっと調べてみた。
- IEnumerable & public Add メソッド : 189
- 非 IEnumerable & public Add メソッド : 42
つまり、コレクションとは「IEnumerable を実装して、public Add メソッドを持ってる型」だ!
もっと調べてみた。
- Add メソッドを複数持ってる : 28
- Add メソッドの引数が1つじゃない : 30
もっとよくするために、{} で囲って引数が複数でも呼べるようにした、初期化リストはそれぞれオーバーロードを解決するようにした。
これは正しい?
この結果の言語設計はパターンに基づいた取り組み方だ。Add がなくなってもコンパイラは文句を言わない(注:誤訳かも)。そのうち、みんなが ICollection
おまけ
おもしろいので原文もぜひどうぞ。コメント欄もなかなかです。
Queue のような Add を持ってないクラスのために、拡張メソッドの Add も呼ぶようにしたら?って意見が出てますが、もう遅いと却下。次版?Queue はコンストラクタが豪華なので Queue にはいらないけど。
Chris Sells さんも書き込んでます。ちなみに c.GetInterface( "ICollection`1" ) != null で拾えました。
オーバーロード解決を試してみました。
using System; using System.Net.Mail; class P { static void Main() { var col = new MailAddressCollection { "example@example.com", new MailAddress( "example2@example.com", "ex2" ), }; foreach ( var item in col ) Console.WriteLine( item.Address ); Console.ReadKey(); } }
できた!
まーでも、2.0以降、コレクションは滅多に書く必要なくなったよね(^^;
ICollection