IListがAddRangeをサポートしないのはなぜですか


89

List.AddRange()存在しますが、存在IList.AddRange()しません。
これは奇妙なことに私を襲う。これの背後にある理由は何ですか?

回答:


68

インターフェースは実装が簡単で、「キッチン以外のすべて」が含まれていない必要があるためです。追加するAddRange場合は、InsertRangeandを追加する必要がありますRemoveRange(対称性のため)。より良い質問は、IList<T>インターフェイスに似たインターフェイスの拡張メソッドがない理由IEnumerable<T>です。(インプレースのための拡張メソッドをSortBinarySearch、...有用であろう)


35
@ShdNxパフォーマンス面で実装するのはそれほど簡単ではありません。「内部」AddRange/RemoveRange/InsertRangeは「内部」コレクションに直接作用し、Capacity管理を最適化し、Array.Copyデータのブロックを移動するような方法を使用できます。拡張方法RemoveRangeは、おそらく、より遅いマグニチュードのオーダーになりますList.RemoveRange
xanatos

2
クラスIFoo(eg MyAssembly)が「ヘルパー」名前空間(eg )を指定する方法がなかった(そしてまだそうではない)のは残念です。クラスが実装を主張しているIFooがメソッドがない場合int Bar(String)、コンパイラは自動的に生成メソッドint IFoo.Bar(String p1) {return MyAssembly.ClassHelpers.IFoo.Bar(this, p1);} このような機能が存在する場合、インターフェイスにAddRangeは、基本動作の観点から実装できるが、一部の実装では最適化できるような、より多くのメソッドが含まれている可能性があります。
スーパーキャット2012年

1
それらは拡張メソッドとして実装でき、そうすればインターフェース実装はそれらを実装する必要がなくなります。なぜそうではないのですか?
トムPažourek

15
これは意味がありません。インターフェイスは実装を抽象化するため、同じ基本機能の複数の実装が存在する可能性があります。「実装が難しい」ため、インターフェイスから機能を省略しなければならない理由はありません。インターフェイスに「AddRange」のようなメソッドがないと、基になるオブジェクトがそれらをサポートする保証はありません。その時点で、次善の拡張を実装するか、危険な仮定をしてインターフェイスを使用する目的を無効にする必要があります。特定の実装クラスにキャストします。唖然としたインターフェースは使いすぎです。
Triynko 2015

3
一括操作をサポートするIRangeListインターフェイスが必要です。これは、内部的に最適な実装を持つ一部のコレクションにのみ実装されます。
あまりにも

8

IListで「AddRange」、「Sort」、...の拡張メソッドが必要な場合は、

以下はAddRange拡張方法です:

 public static void AddRange<T>(this IList<T> source, IEnumerable<T> newList)
 {
     if (source == null)
     {
        throw new ArgumentNullException(nameof(source));
     }

     if (newList == null)
     {
        throw new ArgumentNullException(nameof(newList));
     }

     if (source is List<T> concreteList)
     {
        concreteList.AddRange(newList);
        return;
     }

     foreach (var element in newList)
     {
        source.Add(element);
     }
}

これを行う小さなライブラリを作成しました。プロジェクトごとに拡張メソッドをやり直すよりも実用的だと思います。

一部のメソッドはListよりも低速ですが、機能します。

これが彼らに興味を持ってもらうためのGitHubです:

IListExtensionリポジトリ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.