Yield -> IEnumerator
Allgemein C#
Wenn man bei einer eigenen Klasse einen Enumerator zur Verfügung stellen möchte, muß man normalerweise das IEnumerator Interface implementieren....
Also MoveNext, Current und (ich glaube mich zu erinnern) Reset.
Ist viel Schreibarbeit (finde ich) -> Man kann aber auch yield benutzen
public IEnumerator GetEnumerator() {
for(int i = 0; i < 10; i++) {
yield return container[i];
}
}
Wäre nur die Frage zu klären, warum funktioniert dies ....
Kategorie Wenn man bei einer eigenen Klasse einen Enumerator zur Verfügung stellen möchte, muß man normalerweise das IEnumerator Interface implementieren....
Also MoveNext, Current und (ich glaube mich zu erinnern) Reset.
Ist viel Schreibarbeit (finde ich) -> Man kann aber auch yield benutzen
public IEnumerator GetEnumerator() {
for(int i = 0; i < 10; i++) {
yield return container[i];
}
}
Wäre nur die Frage zu klären, warum funktioniert dies ....
Hier noch einmal die vollständige Klasse
->
class Yield {
private int[] container = null;
public Yield() {
Random r = new Random();
container = new int[10];
for(int i = 0; i < 10; i++) {
container[i] = r.Next(100);
}
}
public IEnumerator GetEnumerator() {
for(int i = 0; i < 10; i++) {
yield return container[i];
}
}
}
Wie man leicht feststellt, wird das IEnumerator-Interface nicht implementiert
Wenn man sich das Compilat im Reflector anschaut, wird man sehen, dass die GetEnumerator-Methode wie folgt aussieht:
D.h. yield weist den Compiler an eine Nested Type zu generieren, welche die Aufgaben erledigt, hier der vollständige Code ->
Jupp's, dann gehen wir einmal davon aus, dass der Compiler Generated Code nie und nimmer Fehlerchen enthält
Gruß JJR
class Yield {
private int[] container = null;
public Yield() {
Random r = new Random();
container = new int[10];
for(int i = 0; i < 10; i++) {
container[i] = r.Next(100);
}
}
public IEnumerator GetEnumerator() {
for(int i = 0; i < 10; i++) {
yield return container[i];
}
}
}
Wie man leicht feststellt, wird das IEnumerator-Interface nicht implementiert
Wenn man sich das Compilat im Reflector anschaut, wird man sehen, dass die GetEnumerator-Methode wie folgt aussieht:
public
IEnumerator
GetEnumerator() { return new <GetEnumerator>d__0(0) { <>4__this = this }; } |
D.h. yield weist den Compiler an eine Nested Type zu generieren, welche die Aufgaben erledigt, hier der vollständige Code ->
CompilerGenerated private sealed class <GetEnumerator>d__0 : IEnumerator<object>, IEnumerator, IDisposable { // Fields private int <>1__state; private object <>2__current; public Yield <>4__this; public int <i>5__1; // Methods DebuggerHidden public <GetEnumerator>d__0(int <>1__state){ this.<>1__state = <>1__state; } private bool MoveNext(){ switch (this.<>1__state){ case 0: this.<>1__state = -1; this.<i>5__1 = 0; while (this.<i>5__1 < 10){ this.<>2__current = this.<>4__this.containerthis.<i>5__1; this.<>1__state = 1; return true; Label_0057: this.<>1__state = -1; this.<i>5__1++; } break; case 1: goto Label_0057; } return false; } DebuggerHidden void IEnumerator.Reset(){ throw new NotSupportedException(); } void IDisposable.Dispose(){} // Properties object IEnumerator<object>.Current{ DebuggerHidden get{ return this.<>2__current; } } object IEnumerator.Current{ DebuggerHidden get { return this.<>2__current; } } } |
Jupp's, dann gehen wir einmal davon aus, dass der Compiler Generated Code nie und nimmer Fehlerchen enthält
Gruß JJR
Kommentare
Hier noch zwei Links aus der MSDN dazu:
{ Link }
{ Link }
Grüße,
Sebastian
P.S.: und dabei steht das sogar in der MSDN drinnen, was das genau macht - wie peinlich...
Erstellt von Sebastian Stricker um 10:10:12 PM am 09/16/2011 | - Website - |