为什么IList不支持AddRange

Bor*_*ens 83 .net c# ilist

List.AddRange()存在,但IList.AddRange()没有.
这让我很奇怪.这背后的原因是什么?

xan*_*tos 64

因为界面应该易于实现,并且不包含"除了厨房之外的所有东西".如果添加AddRange,则应添加InsertRangeRemoveRange(对称).一个更好的问题是为什么没有IList<T>类似于IEnumerable<T>接口的接口的扩展方法.(就地扩展方法Sort,BinarySearch...将是有益的)

  • @ShdNx实现性能方面并不是很容易."内部"`AddRange/RemoveRange/InsertRange`可以直接在"内部"集合上工作,并优化`容量`管理,并使用像`Array.Copy`这样的方法来移动数据块.扩展方法`RemoveRange`可能比`List.RemoveRange`慢一些 (32认同)
  • 这毫无意义.接口抽象实现,因此可以存在相同基本特征的多个实现; 没有理由为什么要从界面中省略功能,因为"实现很难".如果接口上没有像"AddRange"这样的方法,则无法保证底层对象支持它们,并且此时您不得不通过做出危险的假设来实现次优扩展或者破坏使用接口的目的.强制转换为特定的实现类.Dumbed-down接口被过度使用. (13认同)
  • 你是对的,我没有考虑性能角度. (3认同)
  • 应该有支持批量操作的 IRangeList 接口,只在一些内部实现最佳的集合上实现。 (3认同)
  • 对于一个接口(例如`IFoo`)声明没有(并且仍然没有)任何方式来指定一个"辅助"命名空间(例如`MyAssembly`),如果一个类声称实现`IFoo`,那就太糟糕了.但缺少方法`int Bar(String)`,编译器会自动生成方法`int IFoo.Bar(String p1){return MyAssembly.ClassHelpers.IFoo.Bar(this,p1);}`如果存在这样的特征,接口可能包含更多的方法,如`AddRange`,可以根据基本行为实现,但某些实现可以优化. (2认同)

小智 13

对于那些想要在 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);
     }
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个小型图书馆来做到这一点。我发现它比必须在每个项目上重做其扩展方法更实用。

有些方法比 List 慢,但它们可以完成工作。

这是他们感兴趣的 GitHub:

IListExtension 存储库