C# 为什么';IList支持范围
C# 为什么';IList支持范围,c#,.net,ilist,C#,.net,Ilist,List.AddRange()存在,但IList.AddRange()不存在。 我觉得这很奇怪。这背后的原因是什么?因为接口应该易于实现,并且不包含“除了厨房以外的所有东西”。如果添加AddRange,则应添加InsertRange和RemoveRange(用于对称)。更好的问题是为什么没有类似于IEnumerable接口的IList接口的扩展方法。(用于就地排序的扩展方法,二进制搜索,…将非常有用)对于那些希望使用“AddRange”、“Sort”和。。。关于IList 下面是AddRange
List.AddRange()
存在,但IList.AddRange()
不存在。我觉得这很奇怪。这背后的原因是什么?因为接口应该易于实现,并且不包含“除了厨房以外的所有东西”。如果添加
AddRange
,则应添加InsertRange
和RemoveRange
(用于对称)。更好的问题是为什么没有类似于IEnumerable
接口的IList
接口的扩展方法。(用于就地排序的扩展方法,二进制搜索
,…将非常有用)对于那些希望使用“AddRange”、“Sort”和。。。关于IList
下面是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);
}
}
publicstaticvoidaddrange(此IList源代码,IEnumerable newList)
{
if(source==null)
{
抛出新ArgumentNullException(nameof(source));
}
if(newList==null)
{
抛出新ArgumentNullException(nameof(newList));
}
if(来源为列表具体列表)
{
concreteList.AddRange(newList);
返回;
}
foreach(newList中的var元素)
{
来源.添加(元素);
}
}
我创建了一个小型库来实现这一点。我发现这比在每个项目上重做扩展方法更实际
有些方法比列表慢,但它们可以完成任务
以下是让他们感兴趣的GitHub:
@ShdNx在实现性能方面,它们并非微不足道。“内部”AddRange/RemoveRange/InsertRange
可以直接作用于“内部”集合,优化容量
管理,并使用数组等方法。复制
来移动数据块。扩展方法RemoveRange
可能比List慢一个数量级。RemoveRange
很遗憾,接口(例如IFoo
)声明没有(现在仍然没有)任何方法来指定“helper”命名空间(例如MyAssembly
)这样,如果一个类声明实现IFoo
,但缺少方法int-Bar(String)
,编译器将自动生成方法int-IFoo.Bar(String p1){return MyAssembly.ClassHelpers.IFoo.Bar(this,p1);}
如果存在这样的特性,接口可以包含更多的方法,如AddRange
,这些方法可以根据基本行为来实现,但某些实现可以优化。它们可以作为扩展方法来实现,这样接口实现就不必实现它们了。为什么不呢?这毫无意义。接口抽象了一个实现,因此可以有多个相同基本特性的实现;没有理由从接口中省略特性,因为“实现很难”。如果接口上没有像“AddRange”这样的方法,就无法保证底层对象支持它们,此时,您要么被迫实现次优扩展,要么通过对特定的实现类进行危险的假设来破坏使用接口的目的。简化接口过度使用。应该有支持批量操作的IRangeList接口,仅在某些集合上实现,这些集合内部的实现将是最优的。您是BeautifulHanks:)。没什么特别的