Многие из вас, те кто из мира .NET, наверное уже в курсе, что не так давно (месяц назад) Microsoft выпустила Visual Studio 2017 RC, в комплекте с которой разумеется идет C# 7. Что называется на суд энтузиастов. Изучая возможности новой версии, у меня внезапно упала Visual Studio. Каким образом — читайте под катом.

Итак, для воспроизведения бага вам понадобиться Visual Studio 2017 RC. Далее создаем консольное приложение и вставляем этот незамысловатый код:

class Program
{
    class IwillCrash
    {
        public void Deconstruct(out int x) { x = 0; }
    }

    static void Main(string[] args)
    {                        
        //var (x) = new IwillCrash();   // BOOM! deconstruction feature crashes VS2017 RC
    }    
}

Для тех кто не понял код, давайте разберемся, что он означает. Здесь используются такие нововведения C# 7 как:

— Tuples — кортежи
— Deconstruction — так и переводиться
Кортежи, скажем так, очередной синтаксический сахар языка.

Раньше было:

Tuple<int, string> MyFunc(Tuple<decimal, long> param)

Теперь можно:

(int, string) MyFunc( (decimal, long) param )

Учтите, что для использования этой возможности нужно установить сборку System.ValueTuple.
Install-Package «System.ValueTuple» -IncludePrerelease

Деконструкция, а точнее деконструкция-декларация или разрушающая декларация (deconstructing declaration) — это возможность разобрать кортеж на переменные, с одновременным их определением.

Например так:

(string first, string middle, string last) = LookupName(id1);

Где метод объявлен таким образом:

(string, string, string) LookupName(long id)

Результатом конструкции выше, будет декларация трех новых переменных: first, middle, last, которые вернет метод LookupName как кортеж. Другими словами, кортеж разобъется на три переменных.

Разрушающая декларация применима не только к кортежам, но и к пользовательским классам. Одним условием является определение метода-деконструктора с именем Deconstruct. Как в примере выше. Эта возможность позволяет разбивать объект класса на составные части.

Пример:

class Point
{
 public void Deconstruct(out int x, out int y) { x = 1; y = 2; }
}

(var myX, var myY) = new Point(); // вызывает Deconstruct(out myX, out myY);

Как вы поняли, в результате у нас будет myX=1, myY=2.

Вроде во всем разобрались. Теперь сделайте вдох и разкомментируйте код, который в начале поста.

image Фокус удался — студия пропала, тестировщиков наверное уволили, и одним тикетом в дашбоарде разработчиков студии стало больше.

Хотя, справедливости ради, для .NET Core этот код работает. Может это такая хитрая задумка?
В релизе должно быть исправлено, так как в баг репорт отправили до появления поста.

> Хорошое описание новых возможностей C# 7 можной найти тут (англ.)

UPD: По просьбе хабраюзера Varim в комментариях, я таки нашел место, где Microsoft держит список известных багов в Visual Studio. Описанный в посте баг — здесь.
Поделиться с друзьями
-->

Комментарии (17)


  1. Varim
    17.12.2016 05:46

    Может стоит добавить ссылку на баг-репорт


    1. nrcpp
      17.12.2016 10:54

      Насколько я знаю, Microsoft не выкладывает баг-репорты в открытом доступе. Знакомые отправили раньше.


      1. nrcpp
        18.12.2016 20:26

        Незнал, но нашел это труднодоступное место благодоря Visual Studio Community. + В карму за бдительность ;)


  1. Danov
    17.12.2016 11:06
    +1

    В релизной Visual Studio 2008 был похожий баг с рекурсивным get'ером.
    Если правильно помню, достаточно было написать

    sometype PropertyName { get { return PropertyName;} } 
    

    … и студия сразу падала без каких либо предупреждений.


    1. Danov
      17.12.2016 11:14

      И, кстати, у меня VS2017RC не упала… (Console App, .Net 4.5.2 || .Net 4.6.1)


      1. nrcpp
        17.12.2016 11:25

        А ОС какая?


        1. Danov
          17.12.2016 12:30

          Microsoft Windows [Version 10.0.14393] (Windows 10 Pro Multilanguage)


    1. nrcpp
      17.12.2016 11:28

      Да, знали бы вы сколько я багов выловил пока писал свой компилятор С++ по стандарту, а затем проверял тот же код в VS… :) VS конечно «машина» мощная, но такие core-фичи должны были быть покрыты тестами.


      1. sleeply4cat
        17.12.2016 15:49

        А как успехи с компилятором?


        1. nrcpp
          17.12.2016 15:55
          +1

          Дело было в универе >10 лет назад, но помню, что довел его до определенного релиза. :) Делает препроцессинг, потом проверяет лексику, синтаксис, семантику по стандарту ANSI98 (кроме шаблонов, неосилил) и генерирует трехадресный код. Лежит на github'e сейчас, должен собираться под VS2012 и выше.


          1. acedened
            17.12.2016 16:28
            +1

            Массивненько.


  1. ShaltaiBoltai
    19.12.2016 12:39

    Багов там еще много. Я получал «Internal compiler error», когда компайлил C код, падения при открытии многих существующих проектов, падения при открытии файлов… Надеюсь, к релизу это все исправят.


    1. nrcpp
      19.12.2016 12:40

      Полный список для VS2017 здесь


  1. devlev
    19.12.2016 13:58

    image
    А это нормально? Вместо «Записать последние изменения» везде написано «Записать после изменения» (VS2015 RU)


    1. nrcpp
      19.12.2016 21:59

      Ненормально, но локализаторам не дозволено лезьть в код, насколько знаю. Поэтому размер кнопки они изменить не могут, чтобы туда влезла надпись. Разве что запрос в Редмонд отправить могут. И имхо, юзать русскую студию — это издевательство.


      1. devlev
        20.12.2016 09:17

        В VS2012 было нормально переведено. Размер кнопки там все позволяет. Это я просто так скриншот обрезал чтобы не замазывать конфиденциальные данные. А по поводу русской студии, знаю, грешу, не судите строго)
        image


        1. nrcpp
          20.12.2016 11:49
          +1

          Ок, но мы сравниваем RC и релиз. Думаю в 2017-ой студии к релизу все поправят.