为什么C#编译器在这个嵌套的LINQ查询上生气?

尝试编译下面的代码,你会发现编译器需要> 3 GB的RAM(我的机器上的所有可用内存)和很长的时间来编译(实际上10分钟后我得到IOexception)。

using System; using System.Linq; public class Test { public static void Main() { Enumerable.Range(0, 1).Sum(a => Enumerable.Range(0, 1).Sum(b => Enumerable.Range(0, 1).Sum(c => Enumerable.Range(0, 1).Sum(d => Enumerable.Range(0, 1).Sum(e => Enumerable.Range(0, 1).Sum(f => Enumerable.Range(0, 1).Count(g => true))))))); } } 

有人可以解释这个好奇的行为吗?

  CS版本:Microsoft(R)Visual C#编译器版本4.0.30319.17929
操作系统名称:Microsoft Windows 7 Ultimate
 OS版本:6.1.7601 Service Pack 1 Build 7601 

内存使用情况

我认为它与types推断和/或lambda生成有关(当types推断必须与正常情况相反时),并结合重载parsing。 不幸的是,仅仅提供types参数并不能帮助这种情况(大概仍然需要执行types检查)。

下面的代码在逻辑上应该与你的代码相同,在lambdas被分析之后,编译没有问题:

 static void Main() { var x = Enumerable.Range(0, 1).Sum(a); } private static int a(int a) { return Enumerable.Range(0, 1).Sum(b); } private static int b(int b) { return Enumerable.Range(0, 1).Sum(c); } private static int c(int c) { return Enumerable.Range(0, 1).Sum(d); } private static int d(int d) { return Enumerable.Range(0, 1).Sum(e); } private static int e(int e) { return Enumerable.Range(0, 1).Sum(f); } private static int f(int f) { return Enumerable.Range(0, 1).Count(g); } private static bool g(int g) { return true; } 

我相信Eric Lippert之前已经发布过types推理,它是C#编译器中的某个地方(某些问题)可能会迫使编译器试图解决一个NP-Complete问题,而它唯一的真正的策略(就像这里)是powershell的。 如果我能find相关的参考资料,我会在这里添加它们。


我能find的最好的参考是Eric在讨论这个事实,即重载parsing工作导致了真正的成本 – 记住, Enumerable.Sum有10个接受lambda / method的重载。