c# - IEnumerable for vs foreach -
i have method yield returns values. e.g.:
public static ienumerable<int> getvalues() { (int = 0; < 10; i++) { yield return i; } }
when call method foreach, yield return i;
being called 10 times
foreach (int in getvalues()) { console.writeline(i); }
when call for-loop, yield return i;
being called factorial 10 times
for (int = 0;i< 10;i++) { console.writeline(getvalues().elementat(i)); }
question: there way keep for-loop , avoid multiple calls, caused elementat(i)
? or... can call element ienumerable index without causing iteration thourgt previous elements? thing found this,
for (int = 0; < 10; i++) { console.writeline(getvalues().skip(i).first()); }
doesn't work either.
you can't move backward or refer random index in ienumerable<> object - collection can created in various ways including randomness , there's no magic way of getting n-th element without iterating on previous elements.
the common usage of ienumerable<>
is:
foreach (var value in getvalues()) { console.writeline(value); }
which translates like:
using (var enumerator = getvalues().getenumerator()) { while(enumerator.movenext()) { var value = enumerator.current; console.writeline(value); } }
if want refer specific index, need have ilist<> object - can create 1 calling
.tolist()
the .toarray()
mentioned in response little bit slower , calls .tolist()
internally before making array (because array need have fixed size , don't know number of elements in ienumerable until enumerate end)
you can create own proxy, lazy class enumerate enumerator when needed
public static ienumerable<int> getvalues() { (int = 0; < 10; i++) { console.writeline("yielding " + i); yield return i; } } class lazylist<t> { ienumerator<t> enumerator; ilist<t> list; public lazylist(ienumerable<t> enumerable) { enumerator = enumerable.getenumerator(); list = new list<t>(); } public t this[int index] { { while (list.count <= index && enumerator.movenext()) { list.add(enumerator.current); } return list[index]; } } } static void main(string[] args) { var lazy = new lazylist<int>(getvalues()); console.writeline(lazy[0]); console.writeline(lazy[4]); console.writeline(lazy[2]); console.writeline(lazy[1]); console.writeline(lazy[7]); console.writeline(lazy[9]); console.writeline(lazy[6]); console.read(); }
will produce:
yielding 0 0 yielding 1 yielding 2 yielding 3 yielding 4 4 2 1 yielding 5 yielding 6 yielding 7 7 yielding 8 yielding 9 9 6
Comments
Post a Comment