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.


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

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

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


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");
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.