Подтвердить что ты не робот

Почему компилятор С# разбивается на этот код?

Почему код ниже разбивает компилятор .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));
4b9b3361

Ответ 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>>{}