次のような質問への回答:List <T>またはIList <T>は、コレクションの具体的な実装を返すよりも、インターフェイスを返す方が優れていることに常に同意しているようです。しかし、私はこれに苦労しています。インターフェイスをインスタンス化することは不可能であるため、メソッドがインターフェイスを返している場合でも、実際には特定の実装を返しています。私は2つの小さなメソッドを書くことによってこれを少し実験していました:
public static IList<int> ExposeArrayIList()
{
return new[] { 1, 2, 3 };
}
public static IList<int> ExposeListIList()
{
return new List<int> { 1, 2, 3 };
}
そして、私のテストプログラムでそれらを使用してください:
static void Main(string[] args)
{
IList<int> arrayIList = ExposeArrayIList();
IList<int> listIList = ExposeListIList();
//Will give a runtime error
arrayIList.Add(10);
//Runs perfectly
listIList.Add(10);
}
どちらの場合も、新しい値を追加しようとすると、コンパイラでエラーは発生しませんが、配列をとして公開するメソッドでは、IList<T>
何かを追加しようとするとランタイムエラーが発生します。したがって、私のメソッドで何が起こっているのかわからず、それに値を追加する必要がある人は、エラーのリスクを冒さずに値を追加できるようにIList
、最初に私のをにコピーList
する必要があります。もちろん、タイプチェックを実行して、List
またはを処理しているかどうかを確認できますArray
が、それを実行せず、コレクションにIList
List
List
アイテムを追加したい場合は、をコピーする他の選択肢はありません。すでにです。アレイは決して公開されるべきではありませんIList
か?
私のもう1つの懸念は、リンクされた質問の受け入れられた回答に基づいています(私の強調):
他の人が使用するライブラリを介してクラスを公開する場合は、通常、具体的な実装ではなく、インターフェイスを介してクラスを公開する必要があります。これは、後でクラスの実装を変更して別の具象クラスを使用することにした場合に役立ちます。その場合、インターフェースは変更されないため、ライブラリのユーザーはコードを更新する必要はありません。
内部で使用しているだけの場合は、それほど気にしないかもしれませんし、リストを使用しても問題ないかもしれません。
誰かが実際にIList<T>
私のExposeListIlist()
メソッドから取得した値を追加/削除するために使用したと想像してみてください。すべてが正常に動作します。しかし、答えが示唆しているように、インターフェイスを返す方が柔軟性が高いので、リストではなく配列を返します(私の側では問題ありません!)。
TLDR:
1)インターフェースを公開すると、不要なキャストが発生しますか?それは問題ではありませんか?
2)ライブラリのユーザーがキャストを使用しない場合、メソッドが完全に正常であっても、メソッドを変更するとコードが破損することがあります。
私はおそらくこれを考えすぎていますが、実装を返すよりもインターフェイスを返す方が優先されるという一般的なコンセンサスは得られません。
IEnumerable<T>
てコンパイル時の安全性を確保します。通常は特定の型にキャストすることでパフォーマンスを最適化しようとするすべてのLINQ拡張メソッドを引き続き使用できます(プロパティを列挙する代わりICollection<T>
に使用するようにCount
)。