Почему компилятор С# разбивается на этот код?
Почему код ниже разбивает компилятор .NET? Он был протестирован на csc.exe версии 4.0.
См. здесь для онлайн-демонстрации в другой версии - он падает таким же образом, пока он говорит, что динамический не поддерживается https://dotnetfiddle.net/FMn59S:
Ошибка компиляции (строка 0, col 0): Внутренняя ошибка компилятора (0xc0000005 по адресу xy): вероятным виновником является "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, но, похоже, компилятор сбой на любом методе расширения, применяемом к классу, полученному из словаря < T1, T2 > , где по крайней мере один из типов параметров имеет значение dynamic
. См. Еще более общее описание проблемы, приведенной ниже Эриком Функенбушем.
Обновление 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 - РЕШЕНИЕ (вид): Ганс набросал второе обходное решение, которое семантически эквивалентно исходному коду, но работает только для вызова метода расширения, а не для стандартного вызова. Поскольку ошибка, скорее всего, вызвана тем фактом, что компилятор не может использовать класс, полученный из универсального класса, с несколькими параметрами (с одним из которых является динамическим) до своего супертипа, решение заключается в предоставлении явного приведения. См. https://dotnetfiddle.net/oNvlcL:
((Dictionary<string, dynamic>)d).M(kvp => Console.WriteLine(kvp));
M((Dictionary<string, dynamic>)d, kvp => Console.WriteLine(kvp));
Ответы
Ответ 1
Это динамическое действие, вызывающее нестабильность, авария исчезает, когда вы заменяете ее объектом.
Это одно решение, другое - помочь ему вывести правильный T:
static void U(C.K d) {
d.M(new Action<KeyValuePair<string, dynamic>>(kvp => Console.WriteLine(kvp)));
}
отчет о обратной связи, который вы нашли, является сильным совпадением, не нужно записывать свои собственные, я бы сказал.
Ответ 2
Ну, ответ на ваш вопрос о том, почему он сбой компилятора, потому что вы столкнулись с ошибкой, которая... сбой компилятора.
Компилятор VS2013 говорит: "Внутренняя ошибка компилятора (0xc0000005 по адресу 012DC5B5): вероятно, виновником является" ТРАНСФОРМ ", так что это явно ошибка.
C0000005 обычно является нулевым указателем или ссылкой на нераспределенную или удаленную память. Это общая ошибка защиты.
EDIT:
Проблема также присутствует практически во всех типах с несколькими параметрами, где любой параметр является динамическим. Например, он разбивается на:
List<Tuple<string, dynamic>>{}
Он также падает на
List<KeyValuePair<dynamic, string>>{}
Но не падает на
List<dynamic>{}
но сбой на
List<List<dynamic>>{}