なぜ.NET4.5にList<T>
実装IReadOnlyList<T>
するのですか?
List<T>
読み取り専用ではありません...
なぜ.NET4.5にList<T>
実装IReadOnlyList<T>
するのですか?
List<T>
読み取り専用ではありません...
List<T>
必要なメソッド/プロパティなどをすべて実装しているためです。(そしていくつか)のIReadOnlyList<T>
。インターフェースは、「少なくともこれらのことはできる」という契約です。
のドキュメントに
IReadOnlyList<T>
は、要素の読み取り専用コレクションを表すと記載されています。
それは正しい。そのインターフェースにはミューテイターメソッドはありません。それが読み取り専用の意味ですよね?マーカーIReadOnlyList<T>
としてではなく、「典型的な」(契約)方法で使用されます。
インターフェイスは、実装される機能のみを記述します。実装されない機能については説明していません。したがって、IReadOnlyListは、書き込み機能が書き込まれないことを指示できないため、誤ったインターフェイス名になります。
のメソッド/関数は、リストの内容を読み取ることができることを示しています。インターフェイスは、IReadOnlyListではなくIReadableListである必要があります。
インターフェイスの実装は、それを「マーク」することと同じではありません。List<T>
も実装IEnumerable<T>
しますが、それは単にそれを列挙することに限定されているという意味ではありません。
彼らはAPI作成用の読み取り専用インターフェースを追加しましたが、読み取り専用タイプをインターフェースでマークできるようにするためではありません。IReadOnlyCollection<T>
コレクション内の要素の数を列挙せずに知りたい場合やIReadOnlyList<T>
、コレクション内の要素をインデックスで参照する必要がある場合に、引数に使用できます。これはすべての人にとって良いことです。引数タイプで設定した最小基準を満たしている限り、呼び出し元が必要なコレクションタイプを使用できるようにしながら、呼び出し元から必要なものを具体的に指定できます。
ですから、もっと難しい質問は、なぜ実装しないのかということだと思います。List<T>
IReadOnlyList<T>
インターフェイスを実装しているからといって、読み取り専用であるとは限りません。ただし、インターフェイスを実装しているため、を期待するメソッドに渡すことができますIReadOnlyList<T>
。したがって、それを見る方法は、読み取り専用リストインターフェイスを実装することです...いくつかの書き込みメソッドとともに。
これらのインターフェイスはIReadOnlyList
、IReadOnlyCollection
コレクションが読み取り専用であることを意味するのではなく、読み取り専用アクセスがサポートされていることを意味するため、多少混乱します。MSDNドキュメントから(備考までスクロールダウン)
リスト要素の内容は、読み取り専用であることが保証されていません。
より適切な名前はIReadable
、を参照してください。.NET4.5で汎用が実装されないのはなぜですか。ICollection
IReadOnlyCollection
。さらに、これは、下位互換性が原因ではありませんが、IList
継承する必要があることを意味します。「なぜ継承しないのですか? 」を参照してください。。IReadOnlyList
IList<T>
IReadOnlyList<T>
IReadOnlyListは、C ++にはあるが、C#にはない「参照不変性」の概念に代わるものです。C++に相当するものは次のとおりです。
void func(T const * t){...}
または、一部の人が好むように、まったく同等です。
void func(const T * t){...}
関数funcは、その引数tが参照するオブジェクト(tの「指示対象」と呼ばれる)を変更しないことを示しています。他のコードがtの指示対象を変更するかどうか、あるいは変更できるかどうかについては何も述べていません。
したがって、C#インターフェイスはコンパイラ構造の代わりになります。C#に参照の不変性の概念がない理由は、歴史的な質問です。これは間違いだったと思いますが、今すぐ修正するには遅すぎます。代わりのインターフェースを提供するのは良いことだと思います。私は何年もの間、IReadOnlyList <>とまったく同じインターフェイスを使用してきましたが、幸い、別の名前であるIConstList<>を使用しています。IConstList<>の使用をIReadOnlyList<>に置き換えることができます。
IReadOnlyList(Of T)を実行しているコードが、そのインターフェイスを実装するオブジェクトを呼び出すのは、通常、同じ実行スレッドを実行しているというのは本当ではありません。これにより、別の実行スレッドで実行されていない限り、オブジェクトがそれ自体で変更されるのを防ぐことができますが、そのような状況では、それを解決するための同期呼び出しがあります。