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