101

ここのプロジェクトでRunCodeAnalysisを実行しようとしましたが、次のような警告がいくつか表示されました。

CA1002:Microsoft.Design: ' SomeClass.SomeProtectedOrPublicProperty 'の'List < SomeType >'を、Collection、ReadOnlyCollection、またはKeyedCollectionを使用するように変更します

なぜCollection<T>代わりに使用する必要がありList<T>ますか?msdnのドキュメントを見ると、ほぼ同じように見えます。警告のエラーヘルプを読んだ後、私はそれを見つけました

System.Collections.Generic.List(T)_は、継承ではなくパフォーマンスを目的として設計された汎用コレクションであるため、仮想メンバーは含まれていません。

しかし、これは本当にどういう意味ですか?そして、私は代わりに何をすべきですか?

List<T>内部で使用し続ける必要がありますが、プロパティでnew Collection<T>(someList)代わりにを返しますか?または、Collection<T>代わりに使用を開始する必要がありList<T>ますか?

4

2 に答える 2

143

つまり、汎用リストには、拡張可能ではなく高速になるように設計されているため、追加、削除などの仮想メソッドがありません。これは、この具体的な実装を有用なサブクラスと交換できないことを意味します(封印されていないためサブクラス化できますが)。

したがって、リスト自体を公開することにより、クラスの公開コントラクトを破ることなく、コレクションを拡張して追加または削除操作を追跡することはできません(たとえば)。

コレクションをIListなどとして公開することで、リストを実際のバッキングストアとして使用できますが、クラスのパブリックコントラクトを変更せずに、後でconcerete実装を交換できるため、将来の拡張性を維持できます。

于 2009-08-05T09:30:20.187 に答える
26

Collectionコレクションが変更されたときにオーバーライドして追加機能(通知イベントなど)を提供できるいくつかの仮想メンバー(挿入、削除、設定、クリア)を公開します。

今は必要ないかもしれませんが、コレクションを含むクラスでは一般的な要件であるため、事前に計画することをお勧めします。Collection拡張性を念頭に置いて設計されているため、非常に柔軟性があります。将来、コレクションに追加機能が必要になった場合は、クラスのパブリックインターフェイスを変更せずに拡張できます。リストを使用した場合は、それをコレクションに変更する必要があります。つまり、リストを使用するには変更する必要があるため、クラスのすべての呼び出し元が壊れてしまいます。

List一方、パフォーマンスを念頭に置いて設計されているため、パフォーマンスが非常に重要な特定の場合にのみ使用してください。それは拡張可能ではないので、リストを使用するものへの将来の変更は、それに依存する他のすべてを壊します。通常List、非常に低レベルのクラス内でのみ内部的に使用する必要があり、将来の重大な変更の可能性を減らすために何にもさらされないようにする必要があります。

于 2009-08-05T09:28:11.547 に答える