Любимый способ создать новую последовательность IEnumerable <T> из одного значения?


97

Обычно я создаю последовательность из одного значения, используя синтаксис массива, например:

IEnumerable<string> sequence = new string[] { "abc" };

Или используя новый список. Я хотел бы услышать, есть ли у кого-нибудь более выразительный способ сделать то же самое.


3
Как это пустая последовательность?
CoderDennis

Просто смущает, что в dotnet все еще нет чего-то подобного Enumerable.From<T>(params T[] items).
Good Night Nerd Pride

Ответы:


144

Ваш пример - это не пустая последовательность, это последовательность с одним элементом. Чтобы создать пустую последовательность строк, вы можете сделать

var sequence = Enumerable.Empty<string>();

EDIT OP пояснил, что они хотели создать единственное значение. В таком случае

var sequence = Enumerable.Repeat("abc",1);

Ох, я отвлекся, извини. Я имел в виду создание из одного значения, а не создание пустого экземпляра!
Marcel Lamothe

Это флаг «ответ»?
n8wrl

Этот метод более функциональный, чем создание нового массива.
Рой Тинкер,

69

Мне нравится то, что вы предлагаете, но с опущенным типом массива:

var sequence = new[] { "abc" };

4
Я никогда не понимал, что ты можешь это сделать. Я думаю, это понятнее, чем использовать Repeat.
Марсель Ламот,

1
Но это не IEnumerable, это массив!
Zodman

4
@Bryan Watts: Я знаю это, но это конкретная реализация IEnumerable. Вопрос требует IEnumerable <> (даже если в примере нет). Есть разница.
Zodman

Может вопрос стоит поменять.
Zodman

1
@Jonesopolis: Это другая, не связанная с этим ситуация. Вы можете использовать Task.FromResultдля этого.
Брайан Уоттс

21

Или даже короче,

string[] single = { "abc" };

Я бы сделал способ расширения:

public static T[] Yield<T>(this T item)
{
    T[] single = { item };
    return single;
}

Или даже лучше и короче, просто

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

Возможно, именно Enumerable.Repeatэто и делается под капотом.


1
Последний великолепен. За исключением имени ... он будет конфликтовать с типами, которые уже реализуют IEnumerable, такими как строка в вашем примере. Попробуйте .AsSingleItemEnumerable () или просто .Yield () -> "abc" .Yield ()
DanO

8
Я думаю, что ToEnumerable более подходит.
Zodman

2
+1 Yieldхорошо. Я IEnumerable<T> Yield<T>(this T source, params T[] others)тоже сделал .
Джодрелл

Я попытался полностью отказаться от Yield в пользу лямбды, но почему-то он так и не компилировался ... ср. stackoverflow.com/questions/1217729/… ;-).
Питер - Восстановить Монику

@PeterSchneider, как и зачем ты это сделал? Не видя кода, я не могу комментировать. Не думаю, что пойду за тобой.
nawfal

5

или просто создайте метод

public static IEnumerable<T> CreateEnumerable<T>(params T[] items)
{
    if(items == null)
        yield break;

    foreach (T mitem in items)
        yield return mitem;
}

или

public static IEnumerable<T> CreateEnumerable<T>(params T[] items)
{
   return items ?? Enumerable.Empty<T>();
}

использование :

IEnumerable<string> items = CreateEnumerable("single");
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.