Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Isn';从循环外部跳入循环内部的标签不是非法的C代码吗?_C#_.net - Fatal编程技术网

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

C# Isn';从循环外部跳入循环内部的标签不是非法的C代码吗?,c#,.net,C#,.net,大约在9频道09:19,Jeffrey Richter向Charlie Calvert演示了他的AsyncEnumerator,他展示了一段代码,其中控制流跳到内的标签,而循环遵循循环外的goto指令。这让我大吃一惊。我一时不相信 因此,我尝试了类似的方法,正如我所料,C#不允许我这样做,因为标签不在我要跳转的goto语句的块范围内 using System; namespace JumpToInsideALoopWithGoToTest { class Program {

大约在9频道09:19,Jeffrey Richter向Charlie Calvert演示了他的
AsyncEnumerator
,他展示了一段代码,其中控制流跳到
内的标签,而
循环遵循循环外的
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;
        }
    }
}
使用系统;
命名空间跳转到InSideAloopWithGoToTest
{
班级计划
{
静态int i=0;
静态整数=0;
静态void Main(字符串[]参数)
{
Console.WriteLine(“\n按任意键继续…”);
Console.ReadKey();
}
静态bool GoToInsideLoopTest(int多少)
{
如果(i==0)
{
i=1;返回true;
}
如果(i==1)
{
while(someRandomNumber<多少)
{
i=2;
返回true;
增量:i++;
}
}
如果(i==2)
{
后藤增量;
}
返回false;
}
}
}
然后呢?我甚至不知道我的问题是什么。比如,我当时看到的是什么


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

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

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

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


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

谢谢。是的,多年来,我已经为迭代器多次阅读了编译器生成的状态机代码,并且对它相当熟悉。这让我有点困惑。谢谢你整理。嘿嘿!谢谢。:-)但如果看看他在视频中提到的迭代器real MoveNext的IL代码,似乎没有gotos,甚至没有循环,只有一个switch语句。所以它似乎同样可能只是一种简化复杂逻辑的伪代码,不是吗?我承认我从未检查过IL。我来看看。也许这是一个“duffs设备”,它们根据迭代器的状态
切换
。@Evk:我注意到,在许多有趣的情况下,真正的codegen要复杂得多。例如,当需要将
goto
放入语句中间时,当需要将
goto
放入finally块时,等等。在很多情况下,编译器需要生成代码,如果反编译回C#,这些代码看起来会非常奇怪。将对异步方法的实际控制流的任何描述都视为伪代码,以便于理解;现实往往更为复杂,但并不有趣。