Компилятор сгенерировал неверный код для анонимных методов [MS BUG FIXED]

Смотрите следующий код:

public abstract class Base
{
    public virtual void Foo() where T : class
    {
        Console.WriteLine("base");
    }
}

public class Derived : Base
{
    public override void Foo()
    {
        Console.WriteLine("derived");
    }

    public void Bang()
    {
        Action bang = new Action(delegate { base.Foo(); });
        bang();    //VerificationException is thrown
    }
}

new Derived().Bang(); бросает исключение. Внутри сгенерированного CIL методаBang Я получил:

call instance void ConsoleApp.Derived::'n__FabricatedMethod1'()

и подпись сгенерированного компилятором метода:

method private hidebysig 
    instance void 'n__FabricatedMethod1' () cil managed 
{
    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
        01 00 00 00
    )       
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: call instance void ConsoleApp.Base::Foo()
    IL_0006: ret
}

Я думаю, что правильный код должен быть'n__FabricatedMethod1', Это ошибка? Кстати, без использованияdelegate{ }(лямбда-выражение то же самое), код отлично работает с синтаксическими сахарами.

Action good = new Action(base.Foo());
good();  //fine

РЕДАКТИРОВАТЬ Я 'м с использованием VS2012 RTMRel в Windows8 RTM, .net Framework 4.5

РЕДАКТИРОВАТЬ Эта ошибка теперь исправлена.

 Cheng Chen10 окт. 2012 г., 08:58
@jeroenh: C # 4.5 VS2012.
 Cheng Chen10 окт. 2012 г., 09:19
@leppie: LOL I 'Я просто делаю то же самое.
 leppie10 окт. 2012 г., 09:03
Подтверждено на VS2012. Получаетвведите аргумент 'T' нарушает ограничение параметра типа 'T'. ' что интересно
 BoltClock14 дек. 2012 г., 08:56
Почему вы чувствуете необходимость оштукатурить ссылку и фиксированный статус по всему вопросу?
 The Dag11 окт. 2012 г., 11:58
Я нахожу это странным. Isn»t делегат там, используете ли вы явно ключевое слово делегата или нет? Я думал, что эти два синтаксиса были эквивалентны, и поэтому удивлен, что они могут привести к различному IL, если фактическийразбор была ошибка с более далеко идущими последствиями.
 svick10 окт. 2012 г., 13:58
Это похоже наstackoverflow.com/questions/5290559/...хотя это и вызвалоBadImageFormatException и MS утверждает, что это было исправлено.
 leppie10 окт. 2012 г., 09:14
Вывод из PEVerify указывает, что компилятор действительно имеет ошибку ...[IL]: Error: [ConsoleApplication3.exe : ConsoleApplication3.Derived::n__FabricatedMethod1[T]][ offset 0x00000001] Unable to resolve token. 1 Error(s) Verifying ConsoleApplication3.exe
 leppie10 окт. 2012 г., 10:05
Кстати, если вы удалитеwhere T : class ограничение от виртуального метода. Код проверяет и работает правильно.
 jeroenh10 окт. 2012 г., 08:55
Ваш код работает для меня. Какую версию C # /. Net / Visual Studio вы используете? На какую платформу вы ориентируетесь?
 BrandonAGr15 окт. 2012 г., 18:06
@TheDag Doesn 'Синтаксис делегата {} создает дополнительный анонимный метод, который затем вызывает Foo, где в качестве нового Action (base.Foo <строка>) вызывает Foo напрямую без лишнего косвенного обращения?
 leppie10 окт. 2012 г., 10:19
@DannyChen: :) Я добавил сюда ссылку для справки.
 leppie10 окт. 2012 г., 10:07
where T : struct тоже не получается, ноwhere T : IComparable или жеwhere T : Base работает. Редактировать:where T : new() также не удается.
 Cheng Chen10 окт. 2012 г., 10:16
@leppie: Сообщено в MS, номер билета: 766845
 user74338210 окт. 2012 г., 09:38
Я думаю, основываясь на комментариях, вы можете с уверенностью сказать, что выМы нашли ошибку и ответим на ваш вопрос. Единственный способ, которым это может быть что-то кроме ошибки компилятора, это если спецификация языка нет позволяетbase вызовы методов в делегатах (у меня нетне проверено), но даже в этом случае отсутствие надлежащей диагностики является отсутствующей желательной функцией в компиляторе. (Конечно, сообщите об этом в Microsoft.)
 jeroenh10 окт. 2012 г., 09:02
Я пробовал с VS2010, C # 4 и 3.5. Дон»Сейчас у нас нет доступа к 2012 году, но, безусловно, попробую сегодня вечером.

Ответы на вопрос(2)

Решение Вопроса

сейчас исправлено

Обновление: статья Connect больше не существует. Ошибка исправлена.

 leppie14 дек. 2012 г., 08:55
Жаль, что мы никогда не узнаем, когда это достигнет нас. Microsoft действительно должна лучше общаться на этом сайте ...

но, вероятно, не ответ на ваш вопрос. (Но комментарии нене иметь кодирования)

Я считаю, что это похоже на это:Внешняя переменная ловушка, потому что вы используете метод Foo () в качестве переменной и есть ошибка (или, возможно, особенность) в .NET

Я пытался изменить метод Bang () к этому

public void Bang()
{
    Action baseMethod = base.Foo<string>;
    Action bang = new Action(delegate { baseMethod(); });
    bang();    //VerificationException is thrown
}
</string>

И это работает, и результат "база"

Надеюсь, это немного поможет.

 Adam Robinson25 окт. 2012 г., 17:53
К вашему сведению, комментарииделать есть форматирование кода, вы можете простоt включают разрывы строк и все еще ограничены общим количеством символов (включая уценку)

Ваш ответ на вопрос