uso que loop for array c# ienumerable yield-return

c# - que - Uso de IEnumerable sin bucle foreach



return foreach c# (6)

Tengo que estar perdiendo algo simple aquí.

Toma el siguiente código:

public IEnumerable<int> getInt(){ for(int i = 0; i < 10; i++){ yield return i; } }

Puedo llamar esto con:

foreach (int j in obj.getInt()){ //do something with j }

¿Cómo puedo usar el método getInt sin el ciclo foreach?

IEnumerable<int> iter = obj.getInt(); // do something with iter ??

Gracias.

EDITS

Para aquellos que se preguntan por qué me gustaría esto. Estoy iterando dos cosas:

IEnumerator<int> iter = obj.getInt().GetEnumerator(); foreach(object x in xs){ if (x.someCondition) continue; iter.MoveNext(); int n = iter.current(); x.someProp = n; etc... }


¿Qué tal esto?

IEnumerator<int> iter = obj.getInt(); using(iter) { while(iter.MoveNext()) { DoSomethingWith(iter.Current) } }


Aunque las respuestas aceptadas son correctas, observe que IEnumerator.Current no está definido antes de la primera llamada a MoveNext ().

Si está iterando sobre una matriz secundaria, querrá algo como:

IEnumerable<Foo> Foo() { ... } int AssignValues(List<TakesFoo> data) { var count = 0; var foo = Foo().GetEnumerator(); // Step into the first element of the array; // doing this does not discard a value from the IEnumerator if (foo.MoveNext()) { foreach (var x in data) { x.SetFoo(foo.Current); count += 1; if (!foo.MoveNext()) { break; } } // Return count of assigned values return count; }


Es importante mencionar que el deber del bucle foreach es deshacerse del enumerador si la instancia implementa IDisposable . En otras palabras, foreach debería reemplazarse por algo como:

var enumerator = enumerable.GetEnumerator(); try { while (enumerator.MoveNext()) { var item = enumerator.Current; // do stuff } } finally { var disposable = enumerator as IDisposable; if (disposable != null) { disposable.Dispose(); } }


Mi consejo: no te metas con los enumeradores. Caracteriza tu problema como una serie de operaciones en secuencias. Escribir código para expresar esas operaciones. Deje que los operadores de secuencia se encarguen de administrar los enumeradores.

Así que vamos a ver si lo tengo claro. Tienes dos secuencias Digamos {2, 3, 5, 7, 12} y {"rana", "sapo"}. La operación lógica que desea realizar es, por ejemplo, "pasar por la primera secuencia. Cada vez que encuentre un número divisible entre tres, obtenga el siguiente elemento en la segunda secuencia. Haga algo con el par resultante (número, anfibio)".

Hecho facilmente Primero, filtra la primera secuencia:

var filtered = firstSequence.Where(x=>x%3 == 0);

A continuación, comprima la secuencia filtrada con la segunda secuencia:

var zipped = filtered.Zip( secondSequence, (y, z)=> new {Number = x, Amphibian = y});

Y ahora puedes iterar sobre la secuencia comprimida y hacer lo que quieras con los pares:

foreach(var pair in zipped) Console.WriteLine("{0} : {1}", pair.Number, pair.Amphibian);

Easy peasy, sin jugar con los enumeradores.


Puede obtener una referencia al Enumerator , utilizando el método GetEnumerator , luego puede usar el método MoveNext() para continuar y usar la propiedad Current para acceder a sus elementos:

var enumerator = getInt().GetEnumerator(); while(enumerator.MoveNext()) { int n = enumerator.Current; Console.WriteLine(n); }


usando for loop:

for (var enumerator = getInt().GetEnumerator(); enumerator.MoveNext(); ) { Console.WriteLine(enumerator.Current); }