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
ICollection
和IList
接口兼容,这意味着C5
的集合可以很容易地替代为底层的实现。
您可以将IEnumerable范围添加到列表,然后将ICollection =设置为列表。
IEnumerable<T> source; List<item> list = new List<item>(); list.AddRange(source); ICollection<item> destination = list;