Любимый способ создать новую последовательность 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");
Андрей
источник