#.net #linq #generics #collections
#.net #linq #обобщения #Коллекции
Вопрос:
Учитывая, что у меня есть IEnumerable (e) и единственное значение T (t). Какой самый простой способ сделать:
IEnumerable<T> newCollection = t e
На данный момент я делаю:
ItemArray = Enumerable.Repeat<object>(t, 1).Concat(e);
что довольно нечитаемо, поскольку я здесь не повторяю.
Я также пытался:
IEnumerable<T> newCollection = new List<object> { t}.Concat(e);
Но это создает ненужный объект List, который также не является оптимальным.
У кого-нибудь есть идея получше?
Ответ №1:
В MoreLINQ у нас есть Prepend
метод, который может вас заинтересовать. Таким образом, ваш код будет:
ItemArray = e.Prepend(t);
РЕДАКТИРОВАТЬ: Под капотом Prepend
выполняет только то, что делает ваш текущий код — на самом деле я просто предлагаю преобразовать его в метод, который скрывает часть Repeat
/ Concat
и оставляет вам более читаемый вызывающий код.
Комментарии:
1. По-видимому, метод prepend — это просто оболочка для того же, что он делает во втором codestub.
2. @Yet Another Geek: Да, но обратите внимание, что возражение заключается в удобочитаемости , а не в чем-либо семантическом. Все же отредактирую…
Ответ №2:
Ответ Джона Скита является наиболее семантически ценным. Однако, если вам все еще нужен способ сделать это встроенным, вы можете использовать неявно типизированный массив:
newCollection = new[] { t }.Concat(e);
Ответ №3:
Вместо списка, который является более сложным объектом, попробуйте создать простой массив. Это может быть быстрее:
IEnumerable<T> newCollection = new [] { t}.Concat(e);
Я скажу вам сейчас, что для использования Linq для добавления этого элемента вы должны создать новую коллекцию определенного типа. Это потому, что Linq разработан для работы с перечислимыми, и потому, что он не имеет побочных эффектов; независимо от того, что вы делаете в инструкции Linq, исходные перечислимые остаются такими, какими они были до того, как вы начали (если вы не имеете дело с пользовательской коллекцией, которая имеет побочные эффекты, присущие ее перечислению). Результатом является то, что на некотором уровне Linq должен обрабатывать ваш отдельный элемент как коллекцию, содержащую этот один элемент, чтобы он мог перечислять через эту коллекцию для получения любого желаемого результата. Это верно независимо от того, скрываете ли вы реализацию за методом расширения, подобным методам в MoreLINQ, или нет.