Почему для оператора switch-case для строковой константы требуется значение по умолчанию в Visual Studio 2019 (до 16.0.3), а не в Visual Studio 2017? - PullRequest
11 голосов
/ 05 апреля 2019

Я пробую Visual Studio 2019 на основе кода, написанного в Visual Studio 2017, и сразу обнаруживаю проблему сборки. У меня есть оператор switch case, в котором регистр выбирается на постоянной строке. Это не случай по умолчанию, что хорошо в Visual Studio 2017, но выдает ошибку сборки в Visual Studio 2019.

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

public class Program
{
    public const string Database = "MongoDB";

    public static string GetDb()
    {
        switch (Database)
        {
            case "MongoDB":
                return Database;
        }
    }
}

Репозиторий github, содержащий пример решения, можно найти по адресу https://github.com/martineyles/NoDefaultCase Сюда входит архив примера решения в состоянии до его добавления в github.

В Visual Studio 2017 выходные данные сборки выглядят так:

1>------ Rebuild All started: Project: NoDefaultCase, Configuration: Debug Any CPU ------
1>  NoDefaultCase -> C:\Users\MartinEyles\source\repos\NoDefaultCase\NoDefaultCase\bin\Debug\NoDefaultCase.exe
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

В Visual Studio 2019 выходные данные сборки выглядят так:

1>------ Rebuild All started: Project: NoDefaultCase, Configuration: Debug Any CPU ------
1>C:\Users\MartinEyles\source\repos\NoDefaultCase\NoDefaultCase\Program.cs(9,30,9,35): error CS0161: 'Program.GetDb()': not all code paths return a value
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Я нацеливаюсь на .net framework 4.7.2 и языковую версию по умолчанию. Я также попытался уменьшить языковую версию до C # 6.0 и установить языковую версию вручную на C # 7.3 с теми же результатами.

Конкретная версия Visual Studio, которую я использую:

Microsoft Visual Studio Enterprise 2017 
Version 15.9.11
VisualStudio.15.Release/15.9.11+28307.586
Microsoft .NET Framework Version 4.7.03056

и

Microsoft Visual Studio Enterprise 2019 
Version 16.0.0
VisualStudio.16.Release/16.0.0+28729.10
Microsoft .NET Framework Version 4.7.03056

Проблема решена в:

Microsoft Visual Studio Enterprise 2019
Version 16.0.3
VisualStudio.16.Release/16.0.3+28803.352
Microsoft .NET Framework Version 4.7.03056

Ответы [ 2 ]

8 голосов
/ 11 апреля 2019

Похоже, или спецификация будет обновлена ​​с новыми правилами достижимости, или это ошибка в Roslyn, возможно, из-за изменений, внесенных с выражениями переключателей.

Важный вопрос для компилятора: достижим ли конец метода - что будет, если и только если достижим конец оператора switch.

Стандарт ECMA C # 5 раздел 13.8.3 описывает достижимость конца оператора switch:

Конечная точка оператора switch достижима, если хотя бы одно из следующих условий верно:

  • Оператор switch содержит оператор достижимости break, который выходит из оператора switch.
  • Оператор switch достижим, выражение switch является непостоянным значением и метка по умолчанию отсутствует.
  • Оператор switch достижим, выражение switch является константным значением, которое не соответствует ни одной метке регистра, и метка по умолчанию не являетсяприсутствует.

В вашем примере, похоже, нет ни одного из них:

  • Нет операторов прерывания
  • Выражение-переключательконстантное значение
  • константное значение соответствует совпадению с меткой регистра

Таким образом, для правил C # 5 конечная точка этого оператора switch равна not достижимо, и должно без проблем скомпилироваться.Черновая спецификация в GitHub имеет такой же текст, поэтому, похоже, она там еще не изменилась ...

0 голосов
/ 05 апреля 2019

В C # 6 выражение соответствия должно быть выражением, которое возвращает значения следующих типов:

символ.
строка.
a bool.
целое значение,
, например, int или long.
значение перечисления.
Начиная с C # 7.0, выражение соответствия может быть любым ненулевое выражение.

В документации сказано, что в c # 7.0 выражением соответствия может быть любое ненулевое выражение. в c # 7 строка становится обнуляемым типом, поэтому необходимо добавить регистр по умолчанию (для нулевого регистра)

...