Maneira favorita de criar uma nova seqüência IEnumerable <T> de um único valor?

97

Eu geralmente crio uma sequência de um único valor usando a sintaxe de array, assim:

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

Ou usando uma nova lista. Gostaria de saber se alguém tem uma forma mais expressiva de fazer a mesma coisa.

Marcel Lamothe
fonte
3
Como isso é uma sequência vazia?
CoderDennis
É muito constrangedor que o dotnet ainda não tenha algo parecido Enumerable.From<T>(params T[] items).
Good Night Nerd Pride

Respostas:

144

Seu exemplo não é uma sequência vazia, é uma sequência com um elemento. Para criar uma sequência vazia de strings, você pode fazer

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

EDIT OP esclareceu que eles estavam procurando criar um único valor. Nesse caso

var sequence = Enumerable.Repeat("abc",1);
JaredPar
fonte
D'oh, eu me distraí, desculpe. Eu quis dizer criar a partir de um único valor, não criar uma instância vazia!
Marcel Lamothe
Esta é a 'resposta' sinalizar?
n8wrl
Este método é mais puramente funcional do que criar uma nova matriz.
Roy Tinker,
69

Eu gosto do que você sugere, mas com o tipo de matriz omitido:

var sequence = new[] { "abc" };
Bryan Watts
fonte
4
Nunca percebi que você poderia fazer isso. Acho que isso é mais claro do que usar Repeat.
Marcel Lamothe de
1
Mas este não é um IEnumerable, é um array!
Zodman
4
@Bryan Watts Eu sei disso, mas é uma implementação concreta de um IEnumerable. A questão é pedir um IEnumerable <> (mesmo que o exemplo não seja). Existe uma diferença.
Zodman
Talvez a pergunta deva ser mudada.
Zodman
1
@Jonesopolis: Essa é uma situação diferente e não relacionada. Você pode usar Task.FromResultpara conseguir isso.
Bryan Watts
21

Ou ainda mais curto,

string[] single = { "abc" };

Eu faria um método de extensão:

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

Ou ainda melhor e mais curto, apenas

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

Talvez seja exatamente isso o que Enumerable.Repeatestá acontecendo nos bastidores.

Nawfal
fonte
1
O último é brilhante. Exceto pelo nome ... ele entrará em conflito com tipos que já implementam IEnumerable, como a string em seu exemplo. Tente .AsSingleItemEnumerable () ou simplesmente .Yield () -> "abc" .Yield ()
DanO
7
Acho que ToEnumerable é mais apropriado.
Zodman
2
+1 Yieldé bom. Eu fiz IEnumerable<T> Yield<T>(this T source, params T[] others)também.
Jodrell
Eu tentei acabar totalmente com o rendimento em favor de um lambda, mas de alguma forma ele nunca compilou ... cf. stackoverflow.com/questions/1217729/… ;-).
Peter - Reintegrar Monica em
@PeterSchneider como e por que você fez isso? Sem ver o código, não posso comentar. Eu não acho que estou te seguindo.
nawfal
5

ou apenas crie um método

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

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

ou

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

uso:

IEnumerable<string> items = CreateEnumerable("single");
Andrew
fonte