从循环外部跳入循环内的标签是不是非法的C#代码?

时间:2016-06-03 20:40:30

标签: c# .net

在第9频道的this video大约09:19,杰弗里·里希特向查理·卡尔弗特展示他的AsyncEnumerator,他展示了一段代码,其中控制流跳转到一个标签内while循环遵循循环外的goto指令。那让我感到震惊。我有点难以置信。

所以,我尝试了类似的东西,并且正如我所料,C#不允许我这样做,因为标签不在goto语句的块范围内,我想要跳转。

using System;

namespace JumpToInsideALoopWithGoToTest
{
    class Program
    {
        static int i = 0;
        static int someRandomNumber = 0;

        static void Main(string[] args)
        {


            Console.WriteLine("\nPress any key to continue...");
            Console.ReadKey();
        }

        static bool GoToInsideLoopTest(int howMany)
        {
            if (i == 0)
            {
                i = 1; return true;
            }

            if (i == 1)
            {
                while (someRandomNumber < howMany)
                {
                    i = 2;
                    return true;

                    Increment: i++;
                }
            }

            if (i == 2)
            {
                goto Increment;
            }

            return false;
        }
    }
}

然后呢?我甚至不知道我的问题是什么。就像,那时我看到了什么?

我怀疑他展示的代码是伪代码吗?或者IL可能是这样的事情吗?无论如何,那是什么?

1 个答案:

答案 0 :(得分:1)

也许他正在演示C#编译器为异步和迭代器方法生成的状态机。编译器不需要遵守C#语法要求。它需要做的就是让CLR满意。

在CLR级别,所有局部变量都在函数的顶部声明。它们随处可见。没有声明问题,也没有未初始化变量的问题。

CLR强加了自己的要求,主要是关于正确形成执行堆栈。跳转到堆栈为空的位置(例如语句之间)时,这不是问题。由于await可以出现在表达式中,因此重写会重写所有内容,以便状态机跳转到具有空堆栈的位置。

对于C#编译器来说,跳转到几乎任何地方都不是问题。