为什么IList<T>没有接受IEnumerable<T>的Insert方法?

23
我现在的情况是,我想将字符串数组(类型为String[])中的值添加到一个包含IList<String>的对象中。在MSDN上快速查找后发现,IList<T>的Insert方法只有一种版本,它需要索引和对象T,而不是IEnumerable<T>的版本。这是否意味着我必须编写一个循环来将输入列表中的值放入目标列表中?如果是这样,那么这似乎非常受限制,而且API设计也不太友好。也许我漏掉了什么。在这种情况下,C#专家们会怎么做呢?
1个回答

38

因为接口通常是最少的功能,以使其可用,减轻实现者的负担。使用C# 3.0,您可以将此作为扩展方法添加:

public static void AddRange<T>(this IList<T> list, IEnumerable<T> items) {
    if(list == null) throw new ArgumentNullException("list");
    if(items == null) throw new ArgumentNullException("items");
    foreach(T item in items) list.Add(item);
}

看这里,IList<T>现在拥有了AddRange方法:

IList<string> list = ...
string[] arr = {"abc","def","ghi","jkl","mno"};
list.AddRange(arr);

7
你可以这样做,但是它有风险。当你调用AddRange时,你可能期望底层对象知道它正在操作一个范围。在数据绑定场景下,这可能会触发成千上万次事件,而实际上只需要一个事件就足够了。 - Sam Saffron
@Sam,确实如此,但这是您可以通过IList <T>做的最好的事情;当然有方法可以弥补... - Marc Gravell
1
谢谢您的答复,马克。我仍然觉得界面应该设计成可用性比易于实现性更加重要,考虑到将一个列表附加到另一个列表是如此常见的操作。无论如何,在这种情况下扩展方法非常好用,所以可能没有什么值得大惊小怪的。 - Kei
@Kei - 但它在很大程度上是冗余的(即已经可以实现相同的功能),所以我可以理解它不作为额外的接口方法存在。 - Marc Gravell
1
花括号放置的位置为什么这么“可怕”啊? ;) - Mitch Wheat
@Kei:这就是扩展方法有用的情况。 - rwong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接