« SQL Server -> ETW - Tracing :-( | Main| Android - Flex T9 »

Yield -> IEnumerator

10
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:

 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

Gravatar Image1 - Und ich dachte immer das yield ist nur dazu da um eine lokale Variable in einer Methode zu sparen, wenn man daraus eine Collection als Ergebnis zurückliefern möchte... wer hätte gedacht, dass man damit sogar im IL-Code so eine Art kleiner State-Machine erstellt ohne eine Zeile davon selbst schreiben zu müssen. Wieder was gelernt Emoticon

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... Emoticon

Mach einen Kommentar

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::lips::rolleyes:;-)

Amazon


Impressum

Firmenname: Peanuts-Soft
Straße Nummer: Biinger Strasse 8
PLZ Ort: 55263 Wackernheim
Telefon: +491772134526
E-Mail: joerg.reck @ peanuts-soft.de
Disclaimer: Peanuts-Soft übernimmt keine Garantie dafür, dass die auf dieser Website bereitgestellten Informationen vollständig, richtig und stets aktuell sind. Dies gilt auch für alle Links, auf die verwiesen wird. Peanuts-Soft ist für die Inhalte, auf die per Link verwiesen wird, nicht verantwortlich. Peanuts-Soft haftet nicht für konkrete, mittelbare und unmittelbare Schäden oder Schäden, die durch fehlende Nutzungsmöglichkeiten, Datenverluste oder entgangene Gewinne – sei es aufgrund der Nichteinhaltung vertraglicher Verpflichtungen, durch Fahrlässigkeit oder eine andere unerlaubte Handlung – im Zusammenhang mit der Nutzung von Dokumenten oder Informationen bzw. der Erbringung von Dienstleistungen entstehen, die auf dieser Web Site zugänglich sind.
Datenschutz: Inhalt und Gestaltung der Internetseiten sind urheberrechtlich geschützt. Eine Vervielfältigung der Seiten oder deren Inhalte bedarf der vorherigen schriftlichen Zustimmung von Peanuts-Soft.


Locations of visitors to this page

Powered By

Domino BlogSphere
Version 3.0.2