2009-06-05 16 views
6

Mam IEnumerable listę obiektów w C#. Mogę użyć każdego z nich do przechodzenia i sprawdzenia każdego obiektu w porządku, jednak w tym przypadku wszystko, co chcę zrobić, to sprawdzenie pierwszego obiektu czy istnieje sposób na wykonanie tego bez użycia pętli foreach?C# IEnumerable Odzyskaj pierwszy rekord

Próbowałem mylist [0], ale to nie działało.

Dzięki

Odpowiedz

22

(Dla wygody, ta odpowiedź zakłada myList narzędzi IEnumerable<string>;. Zastąpić string z odpowiedniego typu, gdzie jest to konieczne)

Jeśli używasz .NET 3.5, należy użyć rozszerzenia First() metoda:

string first = myList.First(); 

Jeśli nie jesteś pewien, czy istnieją jakieś wartości lub nie, można użyć metody FirstOrDefault() który powróci null (lub bardziej ogólnie, domyślna wartość typu elementu) dla pustej sekwencji.

Nadal można zrobić to „długa droga” bez foreach pętli:

using (IEnumerator<string> iterator = myList.GetEnumerator()) 
{ 
    if (!iterator.MoveNext()) 
    { 
     throw new WhateverException("Empty list!"); 
    } 
    string first = iterator.Current; 
} 

to całkiem brzydki choć :)

W odpowiedzi na Twój komentarz, nie, zwrócony iterator nie umieszczony początkowo na pierwszym elemencie; jest pozycjonowany przed przed pierwszym elementem. Musisz zadzwonić pod numer MoveNext(), aby przenieść go do pierwszego elementu, i tak można odróżnić pustą sekwencję od jednej z jednym elementem.

EDYCJA: Zastanawiam się nad tym, zastanawiam się, czy jest to użyteczna metoda rozszerzenia:

public static bool TryFirst(this IEnumerable<T> source, out T value) 
{ 
    using (IEnumerator<T> iterator = source.GetEnumerator()) 
    { 
     if (!iterator.MoveNext()) 
     { 
      value = default(T); 
      return false; 
     } 
     value = iterator.Current; 
     return true; 
    } 
} 
+0

Czy mylist.GetEnumerator() Aktualny równa do tego.? Chciałbym wiedzieć tylko ze względu na wiedzę. –

+0

Nie jestem pewien, czy podoba mi się metoda rozszerzenia, ponieważ jej parametr wyjściowy sprawia, że ​​jest ona mniej kompozycyjna. Wiem, że to jest punkt metody w tym przypadku, ale posiadanie czegoś niepodzielnego na sekwencji wydaje się błędne. –

+0

Wynikiem tego nie jest jednak sekwencja - będzie to tylko jeden element i element logiczny, więc i tak musi być na końcu łańcucha kompozycji. Myślę, że gdybyś spojrzał na miejsca, w których naprawdę tego chcesz, nie byłby to problem. Jak mówisz, jest to punkt metody. –

3

Pamiętaj, że nie może być "pierwszego elementu", jeśli sekwencja jest pusta.

 IEnumerable<int> z = new List<int>(); 
     int y = z.FirstOrDefault(); 
+0

Aby użyć FirstOrDefault(), musisz zadeklarować "using System.Linq;" – Tony

2

Jeśli nie jesteś na 3,5:

using (IEnumerator<Type> ie = ((IEnumerable<Type>)myList).GetEnumerator()) { 
    if (ie.MoveNext()) 
     value = ie.Current; 
    else 
     // doesn't exist... 
} 

lub

Type value = null; 
foreach(Type t in myList) { 
    value = t; 
    break; 
}