2009-07-23 12 views
8

Ich versuche, den folgenden Code zu kompilieren, aber bekomme Fehler in VS2008. Kann mir jemand sagen, wo ich falsch liege?IEnumerable <T> in C#

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace dummy 
{ 
    public class NaturalNumbersSequence : IEnumerable<int> 
    { 
     public IEnumerator<int> GetEnumerator() 
     { 
      for (int i = 1; i <= 1000; i++) 
       yield return i; 
     } 

     IEnumerator IEnumerable.GetEnumerator() 
     { 
      for (int i = 1; i <= 1000; i++) 
       yield return i; 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      foreach (int i in new NaturalNumbersSequence()) 
       Console.WriteLine(i); 
     } 
    } 
} 
+12

Hinweis, es ist eine gute Idee, die Fehlermeldungen, die Sie erhalten, auch zu posten. –

Antwort

24

Nun, der erste Compiler-Fehler die ich erhalte, dass es, dass klagt:

den generischen Typ 'System.Collections.Generic.IEnumerator' Mit '1'

Argumente Typ erfordert

diese auf der Leitung 16 ist, diese:

IEnumerator IEnumerable.GetEnumerator() 

Fixing dass durch eine uns Hinzufügen Anweisung für den Namespace System.Collections (Tipp: Setzen Sie den Cursor direkt nach IEnumerator, am r am Ende des Wortes, und drücken Sie Strg +. (Strg + die Dot-Taste), sollte es vorschlagen, dass Sie ein "using System.Collections;" Richtlinie, tue das).

Dann kompiliert es und läuft. Passt das zu dem, was Sie erwarten?

Beachten Sie auch, dass Sie immer die Fehlermeldungen, die Sie erhalten, immer posten sollten. Auf diese Weise bellen wir nicht den falschen Baum, wenn auf Ihrem Code etwas nicht stimmt, das wir nicht auf den ersten Blick sehen.

Zusätzlich können Sie diese sehr häufige Implementierung von IEnumerable<T> vereinfachen, indem sie von der anderen der Methoden aufrufen, daher würde ich die Umsetzung der zweiten Verfahren wie folgt vereinfachen:

IEnumerator IEnumerable.GetEnumerator() 
{ 
    return GetEnumerator(); // this will return the one 
          // available through the object reference 
          // ie. "IEnumerator<int> GetEnumerator" 
} 

auf diese Weise nur implementieren der tatsächliche Enumeratorcode einmal.

Und schließlich siehe Earwicker 's answer auch, es zeigt eine bessere (meiner Meinung nach zumindest) Art und Weise, diesen ganzen Code zu schreiben.

+1

+1. Der letzte Teil über die Wiederverwendung einer Implementierung des Enumerators auf der anderen ist das i-Tüpfelchen. –

+0

Warum gibt es überhaupt 2 Implementierungen des Enumerators? – fcuk112

9

Nicht sicher, warum Sie Fehler bekommen, aber wäre das nicht einfacher?

public static class NumbersSequence 
{ 
    public static IEnumerable<int> Naturals 
    { 
     get 
     { 
      for (int i = 1; i <= 1000; i++) 
       yield return i; 
     } 
    } 
} 

class Program 
{ 
    public static void Main(string[] args) 
    { 
     foreach (int i in NumbersSequence.Naturals) 
      Console.WriteLine(i); 
    } 
} 
+5

Und warum bei tausend stoppen ?! –

+12

Jeder weiß, dass Zahlen über 1000 unnatürlich hoch sind. –

+2

Für mich ist die Unterscheidung zwischen "regulären" und "großen" Zahlen bei zwanzigtausend. Ich denke, das ist eine "Implementierungs" -Ding. –

4

Etwas vom Thema, aber vielleicht interessant zu sehen, ist dieser Ansatz:

public static class NumbersSequence 
{ 
    public static IEnumerable<int> Naturals 
    { 
     get 
     { 
      int i = 0; 
      while(true) 
       yield return i++; 
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     foreach (int i in NumbersSequence.Naturals.Take(1000)) 
      Console.WriteLine(i); 
    } 
} 

C# afaik 3.0. Achte auf die scheinbar endlose Schleife im Getter und den Aufruf zu Take (1000). Mit dieser Methode haben Sie nun eine "endlose" Folge von natürlichen Zahlen (endlos bis zum Maximalwert eines int). Es wird nicht hängen bleiben, solange Sie es sagen, um eine bestimmte Menge zu nehmen.

DISCLAIMER: Der Großteil des Codes von Earwickers Antwort entlehnt.

+1

Also, was ist 'ich' in' Naturs.get'? –

+1

Immer schön, "unendliche" Loops in Aktion zu sehen. –

+1

Wie Pavel bemerkt hat, fehlen Initialisierung und Inkrement von i. –

2

Lasse hat die richtige Antwort, und ich weiß, dieser Code ist zu lernen, aber im Interesse des Lernens der Förderung Ich mag zwei Dinge erwähnen:

  1. Enumerable.Range()
  2. Nehmen Sie sich Zeit, um darüber nachzudenken Implementierung:

.

public class NaturalNumbersSequence : IEnumerable<int> 
{ 
    public IEnumerator<int> GetEnumerator() 
    { 
     for (int i=0 i <= int.MaxValue;i++) 
      yield return i; 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     for (int i=0 i <= int.MaxValue;i++) 
      yield return i; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     foreach (int i in new NaturalNumbersSequence().TakeWhile(i => i<=1000)) 
      Console.WriteLine(i); 
    } 
} 
Verwandte Themen