¿Forma favorita de crear una nueva secuencia IEnumerable <T> a partir de un solo valor?

97

Por lo general, creo una secuencia a partir de un valor único usando la sintaxis de matriz, como esta:

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

O usando una nueva lista. Me gustaría saber si alguien tiene una forma más expresiva de hacer lo mismo.

Marcel Lamothe
fuente
3
¿Cómo es eso una secuencia vacía?
CoderDennis
Es sólo embarazoso que dotnet todavía no tiene algo así Enumerable.From<T>(params T[] items).
Good Night Nerd Pride

Respuestas:

144

Tu ejemplo no es una secuencia vacía, es una secuencia con un elemento. Para crear una secuencia vacía de cadenas, puede hacer

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

EDIT OP aclaró que estaban buscando crear un valor único. En ese caso

var sequence = Enumerable.Repeat("abc",1);
JaredPar
fuente
Oh, me distraje, lo siento. Me refiero a crear a partir de un valor único, ¡no crear una instancia vacía!
Marcel Lamothe
Esta es la "respuesta".
n8wrl
Este método es más puramente funcional que crear una nueva matriz.
Roy Tinker
69

Me gusta lo que sugieres, pero con el tipo de matriz omitido:

var sequence = new[] { "abc" };
Bryan Watts
fuente
4
Nunca me di cuenta de que podías hacer eso. Creo que esto es más claro que usar Repeat.
Marcel Lamothe
1
Pero esto no es un IEnumerable, ¡es una matriz!
Zodman
4
@Bryan Watts Lo sé, pero es una implementación concreta de un IEnumerable. La pregunta solicita un IEnumerable <> (incluso si el ejemplo no lo es). Hay una diferencia.
Zodman
Quizás la pregunta debería cambiarse.
Zodman
1
@Jonesopolis: Esa es una situación diferente y no relacionada. Puede usar Task.FromResultpara lograr eso.
Bryan Watts
21

O incluso más corto,

string[] single = { "abc" };

Haría un método de extensión:

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

O incluso mejor y más corto, solo

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

Quizás esto es exactamente lo que Enumerable.Repeatestá haciendo bajo el capó.

nawfal
fuente
1
El último es brillante. Excepto por el nombre ... entrará en conflicto con los tipos que ya implementan IEnumerable, como la cadena en su ejemplo. Pruebe .AsSingleItemEnumerable (), o simplemente .Yield () -> "abc" .Yield ()
DanO
7
Creo que ToEnumerable es más apropiado.
Zodman
2
+1 Yieldes bueno. Yo IEnumerable<T> Yield<T>(this T source, params T[] others)también hice .
Jodrell
Traté de eliminar Yield por completo a favor de una lambda pero de alguna manera nunca se compiló ... cf. stackoverflow.com/questions/1217729/… ;-).
Peter - Reincorpora a Monica
@PeterSchneider ¿cómo y por qué hiciste eso? Sin ver el código no puedo comentar. No creo que te siga.
Nawfal
5

o simplemente crea un método

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

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

o

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

uso:

IEnumerable<string> items = CreateEnumerable("single");
Andrés
fuente