¿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.


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

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" };

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ó.


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");
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.