代码之家  ›  专栏  ›  技术社区  ›  Pratik Deoghare

可枚举,给出意外的输出

  •  4
  • Pratik Deoghare  · 技术社区  · 14 年前
    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();
        }
    }
    

    预期输出:

    10  11  12  13  14  15  16  17  18  19  20
    

    实际产量:

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

    这个代码有什么问题?发生什么事了?

    3 回复  |  直到 14 年前
        1
  •  10
  •   LukeH    14 年前

    的第二个参数 Enumerable.Range 指定要生成的整数的数目, 范围中的最后一个整数。

    如果需要,很容易构建自己的方法,或者更新现有的方法 Foo.Range 方法,生成一个范围 start end 参数。

        2
  •  4
  •   Anton Gogolev    14 年前

    的第二个参数 Range 是要生产的项目数。

        3
  •  3
  •   Eric Lippert    14 年前

    为什么不是结束而是计数?

    如果有起点和终点,如何枚举空范围?例如,假设您在屏幕上有一个文本缓冲区和一个选择,并且选择是从字符12开始到字符12结束的单个字符。你如何枚举这个范围?从字符12开始枚举一个字符。

    现在假设所选内容为零个字符。你如何列举它?如果你有开始,大小,你只要通过零的大小。如果你有开始,结束,你会怎么做?你不能通过12和12。

    现在你可能会说,“好吧,如果它是空的,就不要枚举它”。所以你最终得到的代码应该是这样的:

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

    而不是写作

    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;
    }
    

    这伤了我的眼睛。