Можно ли выдать предупреждение, когда переключатель (enum) не охватывает все значения перечисления AT COMPILE C # - PullRequest
1 голос
/ 19 апреля 2019

Итак, у меня есть

public enum Type
{
    Cat,
    Dog,
    Horse,
}

private void SomeFunc(Type type)
{
    switch (type)
    {
        case Type.Cat:
            // ...
            break;
        case Type.Dog:
            // ...
            break;

        default:
            throw new System.Exception();
    }
}

Скажите, что сначала у нас есть только кошка и собака. И мы уже написали миллионы таких функций, как SomeFunc, которые используют переключатель (тип).

Теперь мы представили Horse, поэтому я собираюсь применять Horse для каждого переключателя.

Но люди в других рабочих ветках не знают об этом добавлении. И когда их ветви слились в master, появится функция, не содержащая Horse в переключателях.

Что ж, если мы проведем юнит-тестирование с каждым типом позже, мы сможем получить исключения, но мы не можем себе этого позволить.

Если мы сможем проверить, все ли случаи явно перечислены в каждом переключателе (enum), это было бы идеально. Есть идеи? Это вообще возможно (без упаковки)?

1 Ответ

4 голосов
/ 19 апреля 2019

Нет, это невозможно - по крайней мере, не из коробки. Операторы switch в C # не должны быть исчерпывающими, и нет способа требовать, чтобы они были исчерпывающими.

(Переключатель выражений в C # 8 выдаст предупреждение, если они не являются исчерпывающими, но это, вероятно, не поможет вам прямо сейчас.)

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

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

Файл проекта:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Roslyn.Analyzers" Version="1.0.3.4" PrivateAssets="All" />
  </ItemGroup>

</Project>

Код:

using System;

enum Color
{
    Red, Green, Blue
}

sealed class Program
{
    static void Main(string[] args)
    {
        Color c = Color.Red;

        switch (c)
        {
            case Color.Red:
                Console.WriteLine("Red");
                break;
            case Color.Green:
                Console.WriteLine("Green");
                break;
//            case Color.Blue:
//                Console.WriteLine("Blue");
//                break;
            default:
                Console.WriteLine("Undefined color");
                break;
        }
    }
}

Результат:

Program.cs (14,9): предупреждение ENUM0001: Добавить недостающие регистры переключателей. Переключатель считается незавершенным, если в нем отсутствует возможное значение перечисления или регистр по умолчанию.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...