我要发布此内容,但我认为答案是:
550至575之间
在Visual Studio 2015中使用默认设置
我创建了一个生成嵌套for
循环的小程序...
for (int i0=0; i0<10; i0++)
{
for (int i1=0; i1<10; i1++)
{
...
...
for (int i573=0; i573<10; i573++)
{
for (int i574=0; i574<10; i574++)
{
Console.WriteLine(i574);
}
}
...
...
}
}
对于500个嵌套循环,仍可以编译该程序。有了575个循环,编译器可以解决以下问题:
警告AD0001分析器'Microsoft.CodeAnalysis.CSharp.Diagnostics.SimplifyTypeNames.CSharpSimplifyTypeNamesDiagnosticAnalyzer'引发了类型'System.InsufficientExecutionStackException'的异常,消息为'堆栈不足,无法继续安全地执行程序。这可能是由于调用堆栈上的函数过多或使用过多堆栈空间的堆栈上的函数造成的。
与底层的编译器消息
错误CS8078:表达式太长或太复杂而无法编译
当然,这纯粹是假设的结果。如果最里面的循环的作用大于a Console.WriteLine
,则在超出堆栈大小之前,可能会出现较少的嵌套循环。同样,在可能存在隐藏设置的情况下,这可能不是严格的技术限制,以增加错误消息中提及的“分析器”或(如果需要)生成的可执行文件的最大堆栈大小。但是,答案的这一部分留给了深入了解C#的人。
更新资料
针对评论中的问题:
我很想看到这个答案可以扩展为通过实验“证明”是否可以将575个局部变量(如果未在for循环中使用)放在堆栈上,和/或是否可以在其中放入575个非嵌套的for循环。单一功能
对于这两种情况,答案都是:是的,有可能。用575个自动生成的语句填充方法时
int i0=0;
Console.WriteLine(i0);
int i1=0;
Console.WriteLine(i1);
...
int i574=0;
Console.WriteLine(i574);
它仍然可以编译。其他一切都会令我惊讶。int
变量所需的堆栈大小仅为2.3 KB。但是我很好奇,为了测试更多的限制,我增加了这个数字。最终,它并不能编译,导致错误
错误CS0204:仅允许65534个本地人,包括由编译器生成的本地人
这是一个有趣的观点,但是已经在其他地方观察到:方法中的最大变量数
同样,有575个非嵌套 for
循环,例如
for (int i0=0; i0<10; i0++)
{
Console.WriteLine(i0);
}
for (int i1=0; i1<10; i1++)
{
Console.WriteLine(i1);
}
...
for (int i574=0; i574<10; i574++)
{
Console.WriteLine(i574);
}
也可以编译。在这里,我还试图找到极限,并创建了更多的循环。特别是,我不确定这种情况下的循环变量是否也计入als“ locals”,因为它们是独立存在的{ block }
。但是仍然不能超过65534。最后,我添加了一个由40000个循环的模式组成的测试
for (int i39999 = 0; i39999 < 10; i39999++)
{
int j = 0;
Console.WriteLine(j + i39999);
}
在循环中包含一个额外的变量,但这些变量似乎也算作“局部变量”,因此无法对其进行编译。
总结一下:〜550的限制确实是由循环的嵌套深度引起的。错误消息也表明了这一点
错误CS8078:表达式太长或太复杂而无法编译
很遗憾(但可以理解)错误CS1647的文档未指定复杂性的“度量”,而仅给出了实用的建议。
编译器在处理您的代码时发生堆栈溢出。要解决此错误,请简化您的代码。
再次强调这一点:对于深度嵌套for
循环的特殊情况,所有这些都是相当学术性和假设性的。但是,通过网络搜索CS1647的错误消息,发现了几种情况,其中该错误针对的代码似乎不是故意有意创建的,而是在现实情况下产生的。