Подтвердить что ты не робот

Каков наилучший способ добавить один элемент в коллекцию IEnumerable?

Я удивлен, увидев, что не существует способа добавить один элемент в коллекцию IEnumerable.

Как добавить один элемент в коллекцию IEnumerable?

4b9b3361

Ответ 1

Вы не можете добавлять элементы в IEnumerable, поскольку он должен быть только для чтения. Ваш лучший выбор - это что-то вроде:

return new List<Foo>(enumerable){ new Foo() };

или

return enumerable.Concat(new [] { new Foo() });

Ответ 2

Точка IEnumerable заключается в том, что она представляет собой коллекцию стилей, собранных только для чтения. Если вы хотите, вы можете имитировать добавление, выполнив что-то вроде этого:

public static IEnumerable<T> Add<T>(this IEnumerable<T> source, T additionalItem)
{
   foreach(var item in source)
   {
      yield return item;
   }

   yield return additionalItem;
}

Ответ 3

Вы можете объединить его с помощью одноэлементного массива:

IEnumerable xs;
xs.Concat(new[]{x});

Ответ 4

Я хотел бы указать на некоторые из других ответов здесь, что IEnumerable - это не только сбор для чтения, но и не сборник. Это интерфейс, который определяет, как можно перебирать коллекцию.

Если вы хотите добавлять объекты, вы должны добавлять объекты в свой конкретный класс коллекции или, по крайней мере, с помощью другого интерфейса.

Ответ 5

Помня, что другие говорили о том, что они не могут "добавить" к перечислимому, вы все равно можете имитировать добавление. На самом деле, я бы сказал, что вы можете "добавить" элемент в последовательность путем преобразования последовательности в новую последовательность, которая фактически "содержит" элемент (просто перебирайте новую последовательность, если вы мне не верите!).

Вы также можете выразить один элемент как перечислимое что-то вроде этого:

//ToEnumerable might not be the best name here
public static IEnumerable<T> ToEnumerable<T>(this T item)
{
    return Enumerable.Repeat(item,1);
}

или

public static IEnumerable<T> ToEnumerable<T>(this T item)
{
    yield return item;
}

Затем вы можете "добавить" элемент к перечисляемому, например:

var items = GetSomeItems();

var itemsWithNewItemOnEnd = items.Concat(somenewitem.ToEnumerable());

var itemsWithNewItemAtStart = somenewitem.ToEnumerable().Concat(items);

Вы даже можете вставить элемент в другое место в последовательности, подобной этой (если вы знаете позицию, после которой вы хотите вставить ее):

var itemsWithNewItemInserted = items.Take(5).Concat(somenewitem.ToEnumerable()).Concat(items.Skip(5));

После завершения операции (т.е. вы управляете своей последовательностью, чтобы она "содержала" то, что вы хотите содержать), вы, вероятно, захотите сделать массив или список из последовательности с помощью методов ToArray или ToList:

var itemsWithNewItemInserted = items.Take(5).Concat(somenewitem.ToEnumerable()).Concat(items.Skip(5)).ToList();

Теперь itemsWithNewItemInserted - это список, содержащий все нужные элементы из исходного списка, с новыми элементами, вставленными посередине.

Обманывание с чересчур многопоточными (удаление, пропуски, вставка и т.д.) может стоить вам со временем, потому что каждый добавленный метод расширения (Take, Skip и т.д.) может привести к повторному повторению последовательности, но список синтаксис понимания облегчает экспресс-операции, которые, по-видимому, будут более запутанными, используя обычную итерацию.

Кроме того, здесь приведены некоторые ссылки, в которых обсуждаются выражения отдельных элементов как IEnumerable:

Передача одного элемента в виде IEnumerable <T>

Есть ли более простой способ linux для "Объединения" одного элемента?

Ответ 6

IEnumerable - это только чтение, ICollection предоставляет изменчивую коллекцию с добавлением и удалением.

Однако вы можете создать новый IEnumerable, содержащий все элементы исходного IEnumerable и новый элемент, объединив 2 списка:

var newCollection = original.Concat(new[]{element});

Ответ 7

IEnumerable предназначен для перебора элементов. У него не всегда есть коллекция в качестве основы. Кроме того, пока вы просматриваете коллекцию, вы не можете изменять коллекцию.

Если вам нужно обновить свою коллекцию во время итерации по ней, вам нужно сделать копию перед запуском цикла foreach. Метод LINQ ToList() - хороший способ сделать это.

Ответ 8

Может быть, не тот ответ, который вы ищете, но использование общих классов коллекций всегда, кажется, решает эти проблемы для меня. Большинство из них имеют метод .Add(T).