Pratik Deoghare
Pratik Deoghare

Reputation: 37172

Enumerable giving unexpected output

class Foo
{
    public static IEnumerable<int> Range(int start, int end)
    {
        return Enumerable.Range(start, end);
    }

    public static void PrintRange(IEnumerable<int> r)
    {
        foreach (var item in r)
        {
            Console.Write(" {0} ", item);
        }
        Console.WriteLine();
    }
}

class Program
{
    static void TestFoo()
    {
        Foo.PrintRange(Foo.Range(10, 20));
    }

    static void Main()
    {
        TestFoo();
    }
}

Expected Output:

10  11  12  13  14  15  16  17  18  19  20

Actual Output:

10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29

What is the problem with this code? Whats happening?

Upvotes: 4

Views: 229

Answers (3)

Eric Lippert
Eric Lippert

Reputation: 660024

Why is it not end but count?

How do you enumerate an empty range if you have start and end points? For example, suppose you have a text buffer on the screen and a selection, and the selection is of a single character starting at character 12 and ending at character 12. How do you enumerate that range? You enumerate one character starting at character 12.

Now suppose the selection is ZERO characters. How do you enumerate it? If you have start, size, you just pass zero for size. If you have start, end, what do you do? You can't pass 12 and 12.

Now you might say "well, just don't enumerate it if its an empty range". So you end up taking code that ought to look like this:

var results = from index in Range(selectionStart, selectionSize)
              where blah blah blah
              select blah;

and instead writing

IEnumerable<Chicken> results = null;
if (selectionSize == 0)
{
    results = Enumerable.Empty<Chicken>();
}
else
{
    results = from index in Range(selectionStart, selectionEnd)
              where blah blah blah
              select blah;
}

which hurts my eyes.

Upvotes: 3

LukeH
LukeH

Reputation: 269358

The second parameter of Enumerable.Range specifies the number of integers to generate, not the last integer in the range.

If necessary, it's easy enough to build your own method, or update your existing Foo.Range method, to generate a range from start and end parameters.

Upvotes: 10

Anton Gogolev
Anton Gogolev

Reputation: 115731

Second parameter of Range is the numbers of items to produce.

Upvotes: 4

Related Questions