AddRange в коллекцию
коллега спросил меня сегодня, как добавить серии в коллекцию. У него есть класс, который наследуется от Collection<T>
. Существует свойство get-only этого типа, которое уже содержит некоторые элементы. Он хочет добавить элементы из другой коллекции в коллекцию свойств. Как он может сделать это в C#3-дружественных мода? (обратите внимание на ограничение о свойстве get-only, которое предотвращает такие решения, как объединение и переназначение.)
конечно, 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.
плохой дизайн? Просто Позвонить Add? Упускаешь очевидное?
6 ответов
нет, это кажется вполне разумным. Есть List<T>.
AddRange() метод, который в основном делает именно это, но требует, чтобы ваша коллекция была конкретной List<T>
.
попробуйте выполнить приведение к списку в методе расширения перед запуском цикла. Таким образом, вы можете воспользоваться преимуществами производительности 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
Если вы хотите один-лайнер вы можно использовать System.Collections.Generic
по каждому элементу.
source.ForEach(o => destination.Add(o));
или даже короче, чем
source.ForEach(destination.Add);
производительность-это то же самое, что и для каждого цикла (синтаксический сахар).
и не попробуйте назначить его как
var x = source.ForEach(destination.Add)
причина ForEach
является недействительным.
на Библиотека Общих Коллекций C5 классы все поддерживают AddRange
метод. C5 имеет гораздо более надежный интерфейс, который фактически предоставляет все функции его базовых реализаций и совместим с интерфейсом System.Collections.Generic
ICollection
и IList
интерфейсы, что означает, что C5
коллекции могут быть легко заменены в качестве базовой реализации.
вы можете добавить свой диапазон IEnumerable в список, а затем установить ICollection = в список.
IEnumerable<T> source;
List<item> list = new List<item>();
list.AddRange(source);
ICollection<item> destination = list;