CollectionやReadOnlyCollectionで、リストのプロパティを公開する
Collection
変更可能なリストとして、よく知られているのはList<T>クラスだろう。なので、変更可能なリストのプロパティを公開したい場合、その型をList
しかし、これはデザイン面で非推奨とされており、その代わりにCollection
- List
は速度と内部的な実装の詳細のために設計されているが、Collection は拡張性のために設計されている - List
が公開しているメンバが多すぎ、それらの多くは多くのシチュエーションに関係がない。対照的に、Collection が公開しているのは少数である。さらに、Collection の派生クラスでList のメンバの一部を公開するのも簡単である
これらの理由を見る限り、特にセキュリティ上の問題が生じるわけではなさそうだが、ガイドラインが示されているのだからそれに従うのが良いだろう。
なお、上記の「Why does DoNotExposeGenericLists recommend that I expose Collection
ReadOnlyCollection
では、変更不可能なリストを公開するにはどうするか。「配列フィールドを返すメソッド - 星一の日記」で述べられているとおり、以下の2パターンがある。
- 配列
- ReadOnlyCollection
このうち配列を公開するパターンでは、注意が必要だ。なぜなら、配列の要素の書き換えを防ぐ方法がないからだ。上記の「配列フィールドを返すメソッド - 星一の日記」にもあるが、型の内部フィールドである配列を型の外に出す際には、Cloneしなければならない。しかしこれは、配列の要素数に応じたコストがかかる操作だ。手元の環境で試したところ、以下のとおりだった。
要素の型 | 要素数 | Clone回数 | かかった時間(単位:秒) |
---|---|---|---|
DateTime | 1000 | 1000 | 0.008〜0.022 |
String | 1000 | 1000 | 0.008〜0.013 |
DateTime | 10000 | 10000 | 2.744〜2.842 |
String | 10000 | 10000 | 2.724〜3.379 |
念のため、Microsoftのガイドラインへのリンクを記しておく。
- プロパティで配列を返さないでください
- 配列の使用方法のガイドライン
- プロパティとメソッドの選択(配列を返す場合はプロパティでなくメソッドとするように推奨されている)
そこで、読み取り専用のリストであるReadOnlyCollection
ReadOnlyCollection
変更不可能なリストを公開するには、ReadOnlyCollection
まとめ
自前の型でリストのプロパティを公開する場合、System.Collections.ObjectModel名前空間の各クラスを利用すべきだろう。少なくとも私はそうする。
ちなみに本エントリを書きながら気づいたが、この名前空間には.NET 3.0から以下のクラスが追加されたようだ。
リストを変更する各操作が行われると、イベントを発生させる機能を持つクラスのようだ。有用だと思う。