2009-07-23 3 views
8

Я пытаюсь получить следующий код для компиляции, но я получаю ошибки в VS2008. Кто-нибудь может сказать мне, где я ошибаюсь?IEnumerable <T> в 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

Примечание. Рекомендуется размещать сообщения об ошибках, которые вы получаете. –

ответ

24

Ну, первая ошибка компилятора я получаю то, что он жалуется, что:

Использование универсального типа 'System.Collections.Generic.IEnumerator' требует '1' аргументы типа

Это в строке 16, это один:

IEnumerator IEnumerable.GetEnumerator() 

Крепление, что при добавлении к нам директива для пространства имен System.Collections (подсказка: поместите курсор сразу после IEnumerator, на r в конце слова и нажмите Ctrl +. (ctrl + dot-key), он должен предложить вам добавить «using System.Collections;» директива, сделайте это).

Затем он компилируется и запускается. Соответствует ли это тому, что вы ожидаете?

Также обратите внимание, что вы всегда должны публиковать сообщения об ошибках, которые вы получаете, таким образом, мы не лаем неправильное дерево, если что-то не так с вашим кодом, что мы не видим на первый взгляд.

Кроме того, вы можете упростить очень общую реализацию IEnumerable<T>, вызвав один из методов с другой стороны, поэтому я бы упростить реализацию второго способов, как это:

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

таким образом, вы только реализовать фактический код перечислителя один раз.

И наконец, см. Earwicker's answer, а также показывает лучший (по моему мнению, минимум) способ написать весь этот код.

+1

+1. Последняя часть о повторном использовании одной реализации перечислителя - с другой стороны - обледенение на торте. –

+0

Почему есть 2 реализации перечислителя в первую очередь? – fcuk112

9

Не знаете, почему вы получаете ошибки, но разве это не будет проще?

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

И зачем останавливаться на тысячу ?! –

+12

Все знают, что цифры выше 1000 неестественно высоки. –

+2

Для меня разница между «регулярными» и «большими» числами составляет двадцать тысяч. Я предполагаю, что это «реализация». –

4

Немного не по теме, но, возможно, интересно посмотреть этот подход:

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. Обратите внимание на бесконечный цикл в геттере и вызов Take (1000). С помощью этого метода у вас теперь есть «бесконечная» последовательность натуральных чисел (бесконечная до максимального значения int). Он не застрянет, если вы скажете, чтобы он взял определенную сумму.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Большая часть кода, заимствованного из ответа Earwicker.

+1

Итак, что такое 'i' в' Naturals.get'? –

+1

Всегда приятно видеть «бесконечные» петли в действии. –

+1

Как заметил Павел, вам не хватает инициализации и приращения i. –

2

Лассе имеет правильный ответ, и я знаю, что это изучение кода, но в интересах дальнейшего вашего обучения я хочу отметить две вещи:

  1. Enumerable.Range()
  2. занять некоторое время, чтобы думать об этом осуществление:

.

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); 
    } 
} 
Смежные вопросы