2009-07-23 34 views
8

Sto cercando di ottenere il seguente codice da compilare ma sto ottenendo errori in VS2008. Qualcuno può dirmi dove sto andando male?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

Nota, è una buona idea pubblicare anche i messaggi di errore. –

risposta

24

Bene, il primo errore del compilatore ottengo è che si lamenta del fatto che:

Utilizzando il tipo generico 'System.Collections.Generic.IEnumerator' richiede '1' argomenti di tipo

questo è sulla linea 16, questa:

IEnumerator IEnumerable.GetEnumerator() 

fissaggio che con l'aggiunta di un noi direttiva per lo spazio dei nomi (suggerimento: posizionare il cursore subito dopo IEnumerator, sul numero alla fine della parola, e premere Ctrl +. (ctrl + tasto-punto), dovrebbe suggerire di aggiungere un "using System.Collections;" direttiva, fallo).

Quindi viene compilato e viene eseguito. Corrisponde a ciò che ti aspetti?

Inoltre, nota che dovresti sempre postare i messaggi di errore che stai ricevendo, in questo modo non stiamo abbaiando dall'albero sbagliato se c'è qualcosa d'altro che non va nel tuo codice che non vediamo a prima vista.

Inoltre, è possibile semplificare questa implementazione molto comune di IEnumerable<T> chiamando uno dei metodi dall'altro, quindi avrei semplificare l'attuazione del secondo metodi simili a questo:

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

questo modo si implementa solo il codice effettivo dell'enumeratore una volta.

E infine vedere Earwicker 's answer pure, mostra un modo migliore (almeno secondo me) per scrivere questo intero codice.

+1

+1. L'ultima parte sul riutilizzo di un'implementazione dell'enumeratore sull'altro è la ciliegina sulla torta. –

+0

perché ci sono 2 implementazioni dell'enumeratore in primo luogo? – fcuk112

9

Non sai perché stai ricevendo errori, ma non sarebbe più semplice?

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

E perché fermarsi a mille ?! –

+12

Tutti sanno che i numeri sopra i 1000 sono innaturalmente alti. –

+2

Per me, la distinzione tra numeri "normali" e "grandi" è di ventimila. Immagino che sia una cosa di "implementazione". –

4

Leggermente off-topic, ma forse interessante da vedere è questo approccio:

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# 3.0 afaik. Presta attenzione al loop apparentemente infinito nel getter e alla chiamata a Take (1000). Con questo metodo ora hai una sequenza 'infinita' di numeri naturali (infinita fino al valore massimo di un int). Non si bloccherà, a patto che tu dica di prendere una quantità specifica.

DISCLAIMER: Gran parte del codice preso in prestito dalla risposta di Earwicker.

+1

Quindi cosa significa "i" in "Naturals.get"? –

+1

Sempre bello vedere i loop "infiniti" in azione. –

+1

Come notato da Pavel, mancano l'inizializzazione e l'incremento di i. –

2

Lasse ha la risposta giusta, e so che questo è l'apprendimento del codice, ma nell'interesse di promuovere l'apprendimento voglio citare due cose:

  1. Enumerable.Range()
  2. Prendetevi del tempo per pensare a questo implementazione:

.

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); 
    } 
} 
Problemi correlati