C# 4.0编译器崩溃

50

这段代码示例无法编译。是否有任何解决方法?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    using church = Func<dynamic, dynamic, dynamic>;

    class Program
    {
        static void Main(string[] args)
        {
            church True = (a, b) => a;
            church False = (a, b) => b;

            Func<church, church, church> And = (x, y) => x(y(True, False), False);
        }
    }
}

错误 6 内部编译器错误(地址为 5476A4CC 的 0xc0000005):可能的罪魁祸首是“EMITIL”。编译器发生了内部错误。要解决此问题,请尝试在下面列出的位置附近简化或更改程序。列表顶部的位置离内部错误发生点更近。可以使用 /errorreport 选项向 Microsoft 报告此类错误。TestApplication


1
似乎是在使用语句中带有“dynamic”的任何通用类型来创建类型别名。 - Michael J. Gray
4个回答

49

很明显这是一个编译器错误。

我向我们的一个测试人员提到了这个问题,他说:

很高兴地告诉您,这个问题已经得到了修复,您将在下一个版本的VS中看到这个修复。您也将在Visual Studio的BUILD Developer Preview版本中看到它已被修复!

对于这个错误,我们很抱歉,并感谢您将其带给我们的注意。


2
请注意我的评论,Jon Skeet的回答中委托是无关紧要的;using crash = List<dynamic>;同样会崩溃。 - configurator
@EricLippert 这个错误在VS 2012 v11.0.61030.00 Update 4中仍然存在。 - mozgow

27

我在使用VS2010 (WinXP 64)时,复现了崩溃问题。

有两种解决方案:

1. 不要使用 using 别名

下面的代码可以在VS2010上编译通过:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<dynamic, dynamic, dynamic> True = (a, b) => a;
            Func<dynamic, dynamic, dynamic> False = (a, b) => b;

            Func<Func<dynamic, dynamic, dynamic>, 
                 Func<dynamic, dynamic, dynamic>,
                 Func<dynamic, dynamic, dynamic> > And 
                = (x, y) => x(y(True, False), False);
        }
    }
}

2. 使用Mono编译器

Mono 2.10编译器(dmcs)没有问题。

[mono] /tmp @ dmcs test.cs
test.cs(18,42): warning CS0219: The variable `And' is assigned but its value is never used
Compilation succeeded - 1 warning(s)
[mono] /tmp @ ./test.exe 
[mono] /tmp @ 

这是在Linux上测试过的。

  1. 您可以在Windows .NET上运行使用mono创建的二进制文件。
  2. Mono编译器附带安装程序MSI,并且也可以在Windows上运行。

21

编辑:我现在已经成功地重现了它,而且我有一个潜在的解决方法。

这个有效:

csc Test.cs

这样做不行:

csc /debug+ Test.cs

看起来这是一个调试信息的问题。如果在您的特定情况下可以不使用它,那么您可以继续进行...

编辑:我刚刚进行了测试,并且使用 /debug:pdbonly 也会出现此问题...

编辑:以防有人想知道,我将联系Eric Lippert询问此事。

编辑:这是我找到的最小复现:

using church = System.Func<dynamic>;

class Program
{
    static void Main() {}
}

不错的发现。你也可以不使用类型别名(using)来实现。 - sehe
1
我怀疑问题在于 lambda 中的隐含属性无处可去,因为 lambda 实际上并未被使用;因此,下一个方法(在本例中是 Main())突然出现了失衡的堆栈或诸如此类的情况。当然,实际上并不知道编译器的内部结构,这只是一次无凭无据的猜测。 - configurator
3
我们通常使用委托,但这与问题无关。using crash = List<dynamic>; 也会导致崩溃。 - configurator

14

这里有另一个解决方法:不要使用 Func,而是使用一个好的老委托类型。

public delegate dynamic Church(dynamic x, dynamic y);

class Program {
    static void Main(string[] args) {
        Church True = (a, b) => a;
        Church False = (a, b) => b;

        Func<Church, Church, Church> And = (x, y) => x(y(True, False), False);
    }
}

这也有好处,那就是 Church 被定义在任何地方,而不仅仅是通过别名在每个文件中定义。


不要使用Func,而是使用一个好的老委托类型。 <-- 我上次检查时,Func(包括Func<T>系列的其余部分)都是委托... - larsw
1
@larsw:我的意思是使用非泛型委托类型,就像我在示例中展示的那样。 - configurator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接