为什么下面的代码会使 .NET 编译器崩溃?它在 csc.exe 版本 4.0 上进行了测试。
参见例如此处用于不同版本的在线演示 - 它以相同的方式崩溃,同时表示不支持动态 https://dotnetfiddle.net/FMn59S :
Compilation error (line 0, col 0): Internal Compiler Error (0xc0000005 at address xy): likely culprit is 'TRANSFORM'.
扩展方法在 List<dynamic>
上运行良好虽然。
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>{}
}
更新:这不会使编译器崩溃
static void U(Dictionary<string, dynamic> d)
{
d.M(kvp => Console.WriteLine(kvp));
}
更新 2:http://connect.microsoft.com/VisualStudio/feedback/details/892372/compiler-error-with-dynamic-dictinoaries 中报告了相同的错误.该错误是针对 FirstOrDefault 报告的,但似乎编译器在应用于从 Dictionarydynamic
。 .请参阅下面 Erik Funkenbusch 对问题的更一般性描述。
更新 3:另一个非标准行为。当我尝试将扩展方法作为静态方法调用时,即 F.M(d, kvp => Console.WriteLine(kvp));
,编译器不会崩溃,但找不到重载:
Argument 1: cannot convert from 'C.K' to 'System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string,dynamic>>'
更新 4 - 解决方案(某种):Hans 草拟了第二个解决方法,它在语义上等同于原始代码,但仅适用于扩展方法调用而不适用于标准调用。由于该错误很可能是由于编译器无法将从具有多个参数(其中一个是动态的)的泛型类派生的类转换为其父类(super class)型这一事实引起的,因此解决方案是提供显式转换。参见 https://dotnetfiddle.net/oNvlcL :
((Dictionary<string, dynamic>)d).M(kvp => Console.WriteLine(kvp));
M((Dictionary<string, dynamic>)d, kvp => Console.WriteLine(kvp));
最佳答案
触发不稳定的是动态,当您用object替换它时崩溃消失。
这是一种解决方法,另一种是帮助它推断正确的 T:
static void U(C.K d) {
d.M(new Action<KeyValuePair<string, dynamic>>(kvp => Console.WriteLine(kvp)));
}
feedback report您找到的匹配度很高,我会说无需提交您自己的文件。
关于c# - 为什么 C# 编译器会在此代码上崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24345220/