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.