[解決済み] Collection<T> vs List<T> インターフェースで使うべきものは?
質問
コードは以下のようになります。
namespace Test
{
public interface IMyClass
{
List<IMyClass> GetList();
}
public class MyClass : IMyClass
{
public List<IMyClass> GetList()
{
return new List<IMyClass>();
}
}
}
コード解析を実行すると、以下のような勧告が表示されます。
警告 3 CA1002 : マイクロソフト.デザイン: IMyClass.GetList()' の 'List' を Collection、ReadOnlyCollection または KeyedCollection を使用するように変更する。
どのように修正すればよいのでしょうか。また、ここでいうグッドプラクティスとは何でしょうか。
どのように解決するのですか?
なぜダメなのか、という"why"の部分に答えるために
List<T>
理由は、将来性、APIの簡素化です。
将来性
List<T>
は、サブクラス化することで簡単に拡張できるように設計されているわけではなく、内部実装のために高速に設計されています。このメソッドは virtual ではないのでオーバーライドできません。
Add
Insert
/
Remove
の操作を行うことができます。
つまり、将来的にコレクションの動作を変更する必要がある場合(例えば、人々が追加しようとするNULLオブジェクトを拒否したり、クラスの状態を更新するなど、NULLが発生したときに追加の作業を行うなど)、返すコレクションのタイプをサブクラス化できるものに変更する必要があり、これは破格のインターフェース変更となります(もちろん、NULLを許可しないなどの意味論の変更もインターフェース変更となるかもしれませんが、内部のクラス状態の更新などは、そうではないでしょう)。
というように、簡単にサブクラス化できるクラスを返すことで、そのようなクラスは不要になります。
Collection<T>
のようなインターフェースか
IList<T>
,
ICollection<T>
または
IEnumerable<T>
を使用すると、内部実装を変更して別のコレクション・タイプにすることができ、消費者が期待するタイプとして返すことができるので、消費者のコードを壊すことはありません。
APIの簡素化
List<T>
のような便利な操作がたくさん含まれています。
BinarySearch
,
Sort
といった具合です。しかし、もしこれがコレクションを公開しているのであれば、リストのセマンティクスは消費者ではなく、あなたがコントロールすることになるでしょう。ですから、あなたのクラスが内部的にこれらの操作を必要とすることはあっても、あなたのクラスの消費者がそれらを呼び出したいと思うことはほとんどないでしょう(あるいは、呼び出すべきです)。
このように、よりシンプルなコレクションクラスやインターフェースを提供することで、APIの利用者が目にするメンバーの数を減らし、利用しやすくすることができます。
関連
-
[解決済み] DBNullから他の型にオブジェクトをキャストすることができない
-
[解決済み】エラー「必要なフォーマルパラメータに対応する引数が与えられていない」を解決する?
-
[解決済み] 関数を終了するには?
-
[解決済み] C#では、文字列の初期化にはstring.EmptyとString.Emptyと""のどちらを使えばいいのでしょうか?
-
[解決済み] C#のインターフェイス。暗黙の実装と明示の実装
-
[解決済み] await/asyncを使用しているときにHttpClient.GetAsync(...)が返らない
-
[解決済み】なぜFunc<T>ではなくExpression<Func<T>を使うのですか?
-
[解決済み】Javaの「ダブルブレース初期化」の効率化?
-
[解決済み】IEnumerable vs List - What to Use? どのように動作するのでしょうか?
-
[解決済み】ArrayとList<T>の比較。いつどちらを使うか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】指定されたキャストが有効でない?
-
[解決済み】"出力タイプがクラスライブラリのプロジェクトは直接起動できない"
-
[解決済み】ここで「要求URIに一致するHTTPリソースが見つかりませんでした」となるのはなぜですか?
-
[解決済み】パディングが無効で、削除できない?
-
[解決済み】プロジェクトビルド時のエラー。エディタでスクリプトにコンパイルエラーがあるため、Playerのビルドにエラーが発生する
-
[解決済み】「namespace x already contains a definition for x」エラーの修正方法は?VS2010にコンバートした後に発生しました。
-
[解決済み】ORA-01008: すべての変数がバインドされていません。これらはバインドされています。
-
[解決済み] UnityでOnCollisionEnterが呼ばれない
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である
-
[解決済み] IEnumerableとICollectionとIListを使用したカスタムコレクション