Reputation: 457
I am trying to get the following code to compile but am getting errors in VS2008. Anyone can tell me where I am going wrong?
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);
}
}
}
Upvotes: 8
Views: 19016
Reputation: 116744
Not sure why you're getting errors, but wouldn't this be simpler?
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);
}
}
Upvotes: 9
Reputation: 23840
Slightly off-topic, but perhaps interesting to see is this approach:
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. Pay attention to the seemingly endless loop in the getter, and the call to Take(1000). With this method you now have an 'endless' sequence of natural numbers (endless up until the maxvalue of an int). It won't get stuck, as long as you tell it to take a specific amount.
DISCLAIMER: Most of the code borrowed from Earwicker's answer.
Upvotes: 4
Reputation: 416131
Lasse has the right answer, and I know this is learning code, but in the interest of furthering your learning I want to mention two things:
Enumerable.Range()
.
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);
}
}
Upvotes: 2
Reputation: 391664
Well, the first compiler error I get is that it complains that:
Using the generic type 'System.Collections.Generic.IEnumerator' requires '1' type arguments
This is on line 16, this one:
IEnumerator IEnumerable.GetEnumerator()
Fixing that by adding a using directive for the System.Collections
namespace (tip: place the cursor just after IEnumerator, on the r at the end of the word, and hit Ctrl+. (ctrl + the dot-key), it should suggest you add a "using System.Collections;" directive, do that).
Then it compiles, and runs. Does that match what you expect?
Also, note that you should always post the actual error messages you're getting, this way we're not barking up the wrong tree if there's something else wrong with your code that we're not seeing at first glance.
Additionally, you can simplify this very common implementation of IEnumerable<T>
by calling one of the methods from the other, hence I would simplify the implementation of the second methods like this:
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator(); // this will return the one
// available through the object reference
// ie. "IEnumerator<int> GetEnumerator"
}
this way you only implement the actual enumerator code once.
And finally see Earwicker's answer as well, it shows a better (in my opinion at least) way to write this whole code.
Upvotes: 25