Façon préférée de créer une nouvelle séquence IEnumerable <T> à partir d'une seule valeur?

97

Je crée généralement une séquence à partir d'une seule valeur en utilisant la syntaxe de tableau, comme ceci:

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

Ou en utilisant une nouvelle liste. J'aimerais savoir si quelqu'un a une façon plus expressive de faire la même chose.

Marcel Lamothe
la source
3
En quoi est-ce une séquence vide?
CoderDennis
C'est juste embarrassant que dotnet n'ait toujours pas quelque chose comme Enumerable.From<T>(params T[] items).
Good Night Nerd Pride

Réponses:

144

Votre exemple n'est pas une séquence vide, c'est une séquence avec un élément. Pour créer une séquence vide de chaînes, vous pouvez faire

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

EDIT OP a précisé qu'ils cherchaient à créer une valeur unique. Dans ce cas

var sequence = Enumerable.Repeat("abc",1);
JaredPar
la source
D'oh, j'ai été distrait, désolé. Je voulais dire créer à partir d'une valeur unique, pas créer une instance vide!
Marcel Lamothe
C'est «la réponse» le signaler?
n8wrl
Cette méthode est plus purement fonctionnelle que la création d'un nouveau tableau.
Roy Tinker
69

J'aime ce que vous suggérez, mais avec le type de tableau omis:

var sequence = new[] { "abc" };
Bryan Watts
la source
4
Je n'ai jamais réalisé que tu pouvais faire ça. Je pense que c'est plus clair que d'utiliser Repeat.
Marcel Lamothe
1
Mais ce n'est pas un IEnumerable, c'est un tableau!
Zodman le
4
@Bryan Watts Je le sais, mais c'est une implémentation concrète d'un IEnumerable. La question demande un IEnumerable <> (même si l'exemple ne l'est pas). Il y a une différence.
Zodman le
Peut-être que la question devrait être modifiée.
Zodman le
1
@Jonesopolis: C'est une situation différente et sans rapport. Vous pouvez utiliser Task.FromResultpour y parvenir.
Bryan Watts
21

Ou encore plus court,

string[] single = { "abc" };

Je ferais une méthode d'extension:

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

Ou encore mieux et plus court, juste

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

C'est peut-être exactement ce que l' Enumerable.Repeaton fait sous le capot.

nawfal
la source
1
Le dernier est génial. Sauf pour le nom ... il entrera en conflit avec les types qui implémentent déjà IEnumerable tels que la chaîne de votre exemple. Essayez .AsSingleItemEnumerable (), ou simplement .Yield () -> "abc" .Yield ()
DanO
8
Je pense que ToEnumerable est plus approprié.
Zodman le
2
+1 Yieldest bon. J'ai fait IEnumerable<T> Yield<T>(this T source, params T[] others)aussi.
Jodrell
J'ai essayé de supprimer complètement Yield au profit d'un lambda mais il n'a jamais été compilé ... cf. stackoverflow.com/questions/1217729/… ;-).
Peter - Réintègre Monica
@PeterSchneider comment et pourquoi avez-vous fait ça? Sans voir le code, je ne peux pas commenter. Je ne pense pas que je te suis.
nawfal
5

ou créez simplement une méthode

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>();
}

utilisation:

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