2011-04-29 15 views
8

Estoy devolviendo un elemento IEnumerable<object[]> desde una función que usa yield return en un bucle.Obtención del primer elemento de un elemento de IEnumerable

public static IEnumerable<object[]> GetData() 
{ 
     ... 

     connection.Open(); 

     using (OleDbDataReader dr = command.ExecuteReader()) 
     { 
      while (dr.Read()) 
      { 
      object[] array = new object[dr.FieldCount]; 
       dr.GetValues(array); 
      yield return array; 
      } 
     } 

     connection.Close(); 
} 

¿Cuál es la mejor manera de recuperar el primer elemento sin utilizar un bucle de preferencia?

var result = Adapter.GetData(); 

Respuesta

14

En resumen:

enumerator=result.GetEnumerator(); 
enumerator.MoveNext(); 
enumerator.Current; 

Esto es lo que hace un foreach en un bucle para iterar a través de todos los elementos.

Forma correcta:

using (IEnumerator<object[]> enumerator = result.GetEnumerator()) { 
    if (enumerator.MoveNext()) e = enumerator.Current; 

}

Con LINQ:

var e = result.First(); 

o

var e = result.FirstOrDefault(default); 

también:

var e = result.ElementAt(0); 
+0

Esto es bueno, gracias. Pero me hace atacar otro problema y es que cierro la conexión de DB después de 'yield return', por lo que si llamo a la función dos veces, se genera una excepción diciendo que la conexión anterior no estaba cerrada. ¿Cómo es que esto funciona bien con 'foreach'? ¿Debo deshacerme de algo de alguna manera? –

+0

¿Puedes decir lo que usaste para obtener el primer elemento? – manojlds

+0

Genial, lo arreglé pasando el comportamiento 'CloseConnection' a la función' ExecuteReader'. Todo está funcionando bien ahora. Montones de gracias. –

0

¿No puedes usar result.First()?

+0

No, no hay primer método. –

+0

@DavidWeng: espere, ¿no tengo IEnumerable un método 'First()'? ¿O he malentendido completamente tu pregunta (podría ser)? – alex

+0

¿Me falta una referencia? 'System.Collections.Generic.IEnumerable ' no contiene una definición para 'Primero' y no se puede encontrar ningún método de extensión 'Primero' aceptando un primer argumento de tipo 'System.Collections.Generic.IEnumerable ' (¿falta una directiva de uso o una referencia de ensamblado?) –

1

Si su .Net 3.5 o superior

Adapter.GetData().First() 
0
enumerator=result.GetEnumerator(); 
enumerator.MoveNext(); 
enumerator.Current; 
+8

La respuesta más votada en realidad tiene exactamente la misma respuesta. Es difícil pasar por alto. – alex

0
public static T FirstOrDefault<T>(this IEnumerable items) where T : class { 
     var list = items.OfType<T>(); 
     if (list!= null) { 
      return list.FirstOrDefault(); 
     } 

     return default(T); 
    } 
Cuestiones relacionadas