为什么C#编译器会在这段代码上崩溃?

为什么C#编译器会在这段代码上崩溃?,c#,csc,C#,Csc,为什么下面的代码会使.NET编译器崩溃?它是在csc.exe 4.0版上测试的 例如,请参见此处,了解不同版本的在线演示-它以相同的方式崩溃,同时表示不支持动态: 编译错误(第0行,第0列):内部编译器错误(地址xy处的0xc0000005):可能的罪魁祸首是“转换” 但是扩展方法在列表上运行良好 using System; using System.Collections.Generic; static class F { public static void M<T>

为什么下面的代码会使.NET编译器崩溃?它是在csc.exe 4.0版上测试的

例如,请参见此处,了解不同版本的在线演示-它以相同的方式崩溃,同时表示不支持动态:

编译错误(第0行,第0列):内部编译器错误(地址xy处的0xc0000005):可能的罪魁祸首是“转换”

但是扩展方法在
列表上运行良好

using System;
using System.Collections.Generic;

static class F  {
    public static void M<T>(this IEnumerable<T> enumeration, Action<T> action){}

    static void U(C.K d) {
        d.M(kvp => Console.WriteLine(kvp));
    }
}

class C  {
    public class K : Dictionary<string, dynamic>{}
}

好吧,你的问题的答案是为什么它会使编译器崩溃,这是因为你遇到了一个。。。。使编译器崩溃

VS2013编译器说“内部编译器错误(地址012DC5B5处的0xc0000005):可能的罪魁祸首是‘转换’”,所以很明显这是一个bug

C0000005通常是空指针,或引用未分配或已删除的内存。这是一般保护故障

编辑:

这个问题也存在于几乎任何类型的多参数泛型类型中,其中任何参数都是动态的。例如,它在以下情况下崩溃:

List<Tuple<string, dynamic>>{}
List{}
它也会崩溃

List<KeyValuePair<dynamic, string>>{}
List{}
但并没有崩溃

List<dynamic>{}
List<List<dynamic>>{}
List{}
但是,它会崩溃吗

List<dynamic>{}
List<List<dynamic>>{}
List{}
触发不稳定性的是动态的,当用对象替换它时,崩溃消失

这是一个解决方法,另一个是帮助它推断正确的T:

static void U(C.K d) {
    d.M(new Action<KeyValuePair<string, dynamic>>(kvp => Console.WriteLine(kvp)));
}
静态空隙U(C.K d){
d、 M(新操作(kvp=>Console.WriteLine(kvp));
}

你发现的是一个很强的匹配,我认为不需要提交你自己的。

类名的选择很好。FWIW,Roslyn编译了这个。@Henk Holterman似乎这个错误是一样的-FirstOrDefault也是扩展方法我很难弄清楚什么答案才能真正回答这个问题“为什么我没有源代码的程序会崩溃?“你打算从这个问题的任何答案中学到什么?@Eric-我希望了解一些关于编译器内部工作的知识,并找出这个bug的实际程度,因为它在比我原先想象的更多的情况下表现出来。所以。。。这是问题的重复?答案在哪里?@HenkHolterman-首先,当我回答这个问题时,这个问题没有包含相同的信息。他后来补充说。第二,答案是第一句话,清楚地说“你的问题的答案”。我知道这听起来很愚蠢,但这就是答案。问一个愚蠢的问题,你会得到一个愚蠢的答案。我们没有编译器的源代码,因此我们无法了解更多其他信息。您可能想将这些信息添加到问题中,但它并不能真正回答问题。@ErikFunkenbusch-我只是想澄清一下,我对中断0n13/14和SEH/VEH有一般的了解,但这只是一些问题的表现。Hans的第二个解决方案更详细地介绍了这个bug的本质,更不用说它已经在内部版本中得到了修复,并且似乎在Roslyn中得到了修复。嗯,如果您正在编写解释器,那么如果不使用
dynamic
,就很难实现解释器。目前,我所知道的最好的解决方法是定义一个需要
字典
的方法,但这也是一个非常糟糕的解决方案。当需要将一个具有多个参数的泛型类强制转换为另一个接口,并且至少有一个参数是动态的时,就会出现此错误。在一种情况下,它使编译器(扩展方法)崩溃,在另一种情况下,它找不到重载。呃,我的解决方法是完全合理的,只要帮助它推断类型即可。在动态环境下工作良好,无需选择“T2”。你为什么不想用它呢?请原谅我的无知,你的第二个解决办法很好。与代表一起,它工作得很好。若在编译器中并没有实际的答案,那个么我将选择这个作为答案。因此,如果只存在lambda参数,编译器似乎将类转换为错误的接口,对吗?C编译器在这个代码中有一个很难解决的问题,因为字典实现协变接口的双类型推理与动态可替代性相结合,它可能会考虑可能匹配的数量。我不喜欢自己写这样的代码,不可能完全测试。潜在的崩溃只是一个null ReavyExchange异常,每天都在C语言程序中发生,它只是在C++中出现时看起来像是一个HekkoaloT丑角。需要微软的工程师才能完全诊断出来。简化它必须做的工作,崩溃就会消失。