AddRange添加到集合

一位同事今天问我如何添加范围到一个集合。 他有一个inheritance自Collection<T> 。 这种types的只读属性已经包含了一些项目。 他希望将另一个集合中的项目添加到属性集合中。 他如何以一种C#3友好的方式来做到这一点? (请注意关于只读属性的约束,这会阻止像联合和重新分配这样的解决scheme。)

当然,与财产的foreach。 添加将工作。 但是一个List<T>风格的AddRange会更加优雅。

写一个扩展方法很简单:

 public static class CollectionHelpers { public static void AddRange<T>(this ICollection<T> destination, IEnumerable<T> source) { foreach (T item in source) { destination.Add(item); } } } 

但是我有一种感觉,我正在重新发明轮子。 我在System.Linq或morelinq中找不到类似的东西。

糟糕的devise? 只是打电话添加? 缺less显而易见的?

不,这似乎是完全合理的。 有一个List<T>. 基本上这样做的AddRange()方法,但要求您的集合是一个具体的List<T>

在运行循环之前,尝试在扩展方法中转换为List。 这样你可以利用List.AddRange的性能。

 public static void AddRange<T>(this ICollection<T> destination, IEnumerable<T> source) { List<T> list = destination as List<T>; if (list != null) { list.AddRange(source); } else { foreach (T item in source) { destination.Add(item); } } } 

请记住,每个Add将检查集合的容量,并在必要时调整它的大小(较慢)。 使用AddRange ,集合将被设置容量,然后添加项目(更快)。 这种扩展方法将非常缓慢,但会起作用。

.NET4.5如果你想.NET4.5 ,你可以使用System.Collections.Generic ForEach。

 source.ForEach(o => destination.Add(o)); 

甚至更短

 source.ForEach(destination.Add); 

性能方面与每个循环(语法糖)相同。

不要试图分配它

 var x = source.ForEach(destination.Add) 

因为ForEach是无效的。

C5通用集合库类都支持AddRange方法。 C5有一个更强大的接口,实际上暴露了底层实现的所有function,并且与System.Collections.Generic ICollectionIList接口兼容,这意味着C5的集合可以很容易地替代为底层的实现。

您可以将IEnumerable范围添加到列表,然后将ICollection =设置为列表。

  IEnumerable<T> source; List<item> list = new List<item>(); list.AddRange(source); ICollection<item> destination = list;