Warum unterstützt IList AddRange nicht?


88

List.AddRange()existiert, aber IList.AddRange()nicht.
Das kommt mir seltsam vor. Was ist der Grund dafür?

Antworten:


66

Denn eine Schnittstelle sollte einfach zu implementieren sein und nicht "alles außer der Küche" enthalten. Wenn Sie hinzufügen AddRange, sollten Sie InsertRangeund RemoveRange(aus Symmetriegründen) hinzufügen . Eine bessere Frage wäre, warum es keine Erweiterungsmethoden für die IList<T>Schnittstelle gibt, die der Schnittstelle ähnlich sind IEnumerable<T>. (Erweiterungsmethoden für in-place Sort, BinarySearch... wäre nützlich)


34
@ShdNx Die Implementierung in Bezug auf die Leistung ist nicht sehr trivial. Ein "interner" AddRange/RemoveRange/InsertRangekann direkt an der "internen" Sammlung arbeiten und die CapacityVerwaltung optimieren und Methoden verwenden Array.Copy, um Datenblöcke zu verschieben. Eine Erweiterungsmethode RemoveRangewäre wahrscheinlich eine Größenordnung langsamer alsList.RemoveRange
xanatos

2
Es ist schade , es war nicht (und ist immer noch nicht) eine Möglichkeit für eine Schnittstelle (zB IFoo) Deklaration eines „Helfer“ Namespace angeben (zB MyAssembly) , so dass , wenn eine Klasse Ansprüche zu implementieren , IFooaber es fehlt Verfahren int Bar(String)würde die Compiler auto- Methode generieren int IFoo.Bar(String p1) {return MyAssembly.ClassHelpers.IFoo.Bar(this, p1);} Wäre eine solche Funktion vorhanden, hätten die Schnittstellen möglicherweise mehr Methoden enthalten AddRange, die im Hinblick auf ein Basisverhalten implementiert werden könnten, die jedoch von einigen Implementierungen optimiert werden könnten.
Supercat

1
Sie könnten als Erweiterungsmethoden implementiert werden, so dass die Schnittstellenimplementierung sie nicht implementieren müsste. Warum sind sie nicht?
Tom Pažourek

14
Das macht keinen Sinn. Eine Schnittstelle abstrahiert eine Implementierung, sodass mehrere Implementierungen derselben Grundfunktionen vorhanden sein können. Es gibt keinen Grund, warum Funktionen in einer Schnittstelle weggelassen werden sollten, da die "Implementierung schwierig ist". Ohne Methoden wie "AddRange" auf der Schnittstelle gibt es keine Garantie dafür, dass das zugrunde liegende Objekt sie unterstützt, und zu diesem Zeitpunkt sind Sie gezwungen, entweder eine suboptimale Erweiterung zu implementieren oder den Zweck der Verwendung einer Schnittstelle zu umgehen, indem Sie gefährliche Annahmen treffen Besetzung einer bestimmten implementierenden Klasse. Dumbed-Down-Schnittstellen werden überbeansprucht.
Triynko

3
Es sollte die IRangeList-Schnittstelle geben, die Massenoperationen unterstützt und nur für einige Sammlungen implementiert ist, bei denen die Implementierung intern optimal ist.
Auch

7

Für diejenigen, die Erweiterungsmethoden für "AddRange", "Sort", ... auf IList haben möchten,

Unten ist die AddRangeErweiterungsmethode:

 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);
     }
}

Ich habe eine kleine Bibliothek erstellt, die dies tut. Ich finde es praktischer, als die Erweiterungsmethoden für jedes Projekt wiederholen zu müssen.

Einige Methoden sind langsamer als List, aber sie erledigen den Job.

Hier ist der GitHub, der sie interessiert:

IListExtension-Repository

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.