Ulubiony sposób tworzenia nowej sekwencji IEnumerable <T> na podstawie pojedynczej wartości?

97

Zwykle tworzę sekwencję z pojedynczej wartości przy użyciu składni tablicy, na przykład:

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

Lub używając nowej listy. Chciałbym usłyszeć, czy ktoś ma bardziej wyrazisty sposób, aby zrobić to samo.

Marcel Lamothe
źródło
3
Jak to jest pusta sekwencja?
CoderDennis
To po prostu żenujące, że dotnet nadal nie ma czegoś takiego Enumerable.From<T>(params T[] items).
Good Night Nerd Pride

Odpowiedzi:

144

Twój przykład nie jest pustą sekwencją, to sekwencja z jednym elementem. Aby utworzyć pustą sekwencję ciągów, możesz to zrobić

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

EDIT OP wyjaśnił, że chcą stworzyć jedną wartość. W tym wypadku

var sequence = Enumerable.Repeat("abc",1);
JaredPar
źródło
D'oh, rozproszyłem się, przepraszam. Miałem na myśli tworzenie z pojedynczej wartości, a nie tworzenie pustej instancji!
Marcel Lamothe
Czy to oznacza „odpowiedź”?
n8wrl
Ta metoda jest bardziej czysto funkcjonalna niż tworzenie nowej tablicy.
Roy Tinker
69

Podoba mi się to, co sugerujesz, ale z pominiętym typem tablicy:

var sequence = new[] { "abc" };
Bryan Watts
źródło
4
Nigdy nie zdawałem sobie sprawy, że możesz to zrobić. Myślę, że jest to wyraźniejsze niż użycie opcji Powtórz.
Marcel Lamothe
1
Ale to nie jest IEnumerable, to tablica!
Zodman
4
@Bryan Watts Wiem, ale jest to konkretna implementacja IEnumerable. Pytanie dotyczy IEnumerable <> (nawet jeśli przykład nie jest). Jest różnica.
Zodman
Może należy zmienić pytanie.
Zodman
1
@Jonesopolis: To inna, niepowiązana sytuacja. Możesz użyć, Task.FromResultaby to osiągnąć.
Bryan Watts
21

Albo jeszcze krócej,

string[] single = { "abc" };

Zrobiłbym metodę rozszerzenia:

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

Albo jeszcze lepiej i krócej

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

Być może dokładnie to Enumerable.Repeatrobi się pod maską.

nawfal
źródło
1
Ten ostatni jest genialny. Z wyjątkiem nazwy ... spowoduje to konflikt z typami, które już implementują IEnumerable, takimi jak ciąg w Twoim przykładzie. Spróbuj .AsSingleItemEnumerable () lub po prostu .Yield () -> "abc" .Yield ()
DanO
8
Myślę, że ToEnumerable jest bardziej odpowiednie.
Zodman
2
+1 Yieldjest dobre. Ja IEnumerable<T> Yield<T>(this T source, params T[] others)też zrobiłem .
Jodrell,
Próbowałem całkowicie pozbyć się Yielda na rzecz lambdy, ale jakoś nigdy się to nie skompilowało ... por. stackoverflow.com/questions/1217729/… ;-).
Peter - Przywróć Monikę
@PeterSchneider jak i dlaczego to zrobiłeś? Nie widząc kodu, nie mogę komentować. Chyba nie podążam za tobą.
nawfal
5

lub po prostu utwórz metodę

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

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

lub

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

stosowanie :

IEnumerable<string> items = CreateEnumerable("single");
Andrzej
źródło