2009-06-05 20 views
6

Tengo una lista IEnumerable de objetos en C#. Puedo usar un para cada uno para recorrer y examinar bien cada objeto, sin embargo, en este caso, todo lo que quiero hacer es examinar el primer objeto ¿hay alguna forma de hacerlo sin usar un bucle foreach?C# IEnumerable Recuperar El Primer Registro

He intentado mylist [0] pero eso no funcionó.

Gracias

Respuesta

22

(Por razones de conveniencia, esta respuesta supone myList implementos IEnumerable<string>;. string sustituir con el tipo apropiado cuando sea necesario)

Si está utilizando .NET 3.5, utilice la extensión First() método:

string first = myList.First(); 

Si no está seguro de si hay algún valor o no, puede utilizar el método FirstOrDefault() que devolverá null (o más generalmente, el valor predeterminado del tipo de elemento) para una secuencia vacía.

Todavía se puede hacer "el camino más largo" sin foreach bucle:

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

Es bastante feo aunque :)

En respuesta a su comentario, no, el iterador devuelto no es colocado inicialmente en el primer elemento; está posicionado antes de el primer elemento. Necesita llamar al MoveNext() para moverlo al primer elemento, y así es como se puede ver la diferencia entre una secuencia vacía y una con un solo elemento.

EDIT: Solo de pensarlo, me pregunto si esto es método de extensión útil:

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

Es mylist.GetEnumerator() igual a esta.? Me gustaría saber solo por el simple hecho de saberlo. –

+0

No estoy seguro si me gusta el método de extensión ya que su parámetro lo hace menos composable. Sé que ese es el objetivo del método en este caso, pero tener algo no compostable en una secuencia parece equivocado. –

+0

Sin embargo, el resultado de esto no es una secuencia; solo será un único elemento y un booleano, por lo que tendría que estar al final de la cadena de composición de todos modos. Creo que si miraras lugares donde realmente quisieras esto, no sería un problema. Como dices, es el punto del método. –

3

Recuerde, puede que no haya "primer elemento" si la secuencia está vacía.

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

Para utilizar FirstOrDefault(), debe declarar "using System.Linq;" – Tony

2

Si no estás en 3.5:

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

o

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