为什么IList不支持AddRange


89

List.AddRange()存在,但IList.AddRange()不存在。
这让我感到奇怪。这是什么原因呢?

Answers:


68

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


35
@ShdNx在实现性能方面,它们并不是很简单。“内部”AddRange/RemoveRange/InsertRange可以直接在“内部”集合上工作,并优化Capacity管理和使用诸如Array.Copy在数据块之间移动的方法。扩展方法RemoveRange很可能是magniture的顺序慢于List.RemoveRange
萨那托斯

2
太糟糕了,接口(例如IFoo)声明没有(而且仍然没有)以任何方式指定“帮助”命名空间(例如MyAssembly),使得如果类声明要实现IFoo但缺少方法int Bar(String),则编译器将自动生成方法int IFoo.Bar(String p1) {return MyAssembly.ClassHelpers.IFoo.Bar(this, p1);} 如果存在这样的功能,则接口可以包含更多的方法,例如AddRange可以根据基本行为来实现,但是可以对某些实现进行优化。
2012年

1
它们可以作为扩展方法来实现,这样,接口实现就不必实现它们。他们为什么不呢?
汤姆·帕索里克(TomPažourek),2013年

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存储库

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.