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