Есть ли способ, чтобы компилятор c # отображал предупреждения, когда оператор switch имеет необработанные случаи? - PullRequest
9 голосов
/ 02 апреля 2009

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

        private enum myEnum
        {
            A,
            B
        }
        private void myMethod(myEnum m)
        {
            switch (m)
            {
                case myEnum.A:
                    //do stuff
                break;
                case myEnum.B:
                   //do stuff
                break;
                default:
                   throw new NotImplementedException(m.ToString());
            }
        }

Если я когда-нибудь добавлю третий элемент C в myEnum, я буду предупрежден во время выполнения только NotImplementedException

Я хотел бы, чтобы компилятор предупреждал меня, когда есть переключатель с необработанными регистрами и без значения по умолчанию: case.

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

Ответы [ 5 ]

6 голосов
/ 02 апреля 2009

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

Вместо перечисления используйте базовый класс или интерфейс. MyMethod определен в интерфейсе.

Каждый член перечисления теперь становится классом с различным поведением для myMethod. Если вы добавите класс (для расширения опций, в настоящее время добавите элемент enum), но не реализует myMethod, вы получите ошибку компилятора.

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

EDIT

Лучший совет, который я могу дать, - это создавать модульные тесты для каждой функции, которая опирается на оператор switch, и вызывать ее для каждого значения в перечислении (значения можно получить во время выполнения с помощью члена GetValues ​​класса Enum)

2 голосов
/ 02 апреля 2009

Нет, в языке нет ничего, чтобы это проверить.

Вы можете иметь:

default:
    throw new ArgumentOutOfRangeException("Invalid value or bug");

, но очевидно, что это время выполнения, а не время компиляции.

1 голос
/ 02 апреля 2009

Никогда не использовал, но FxCop может быть полезным. Он поддерживает написание пользовательских правил. Конечно, это не проверка во время компиляции, а то, что можно интегрировать в ваши процессы.

0 голосов
/ 09 ноября 2018

Я написал библиотеку для создания дискриминированных союзов в C #, которая была бы решением для обеспечения полного соответствия во время компиляции. Смотри https://github.com/mcintyre321/OneOf

Install-Package OneOf

В нем есть общие типы для создания DU, например OneOf на всем пути к OneOf. У каждого из них есть .Match и оператор .Switch, которые вы можете использовать для безопасного типизированного поведения компилятора, например ::10000

OneOf<A, B> aOrB = GetValue(); 
aOrB .Switch(
    a=> DoSomething(a),
    b=> DoSomethingElse(b)
)
0 голосов
/ 01 мая 2013

Это может стать кошмаром обслуживания, тратя много времени на попытки отладки отсутствующего значения enum в операторе switch.

Написал небольшой класс, чтобы сделать операторы переключения более удобными для обслуживания,

enter image description here

Класс гарантирует, что все значения перечисления либо обработаны, либо явно проигнорированы, в противном случае он генерирует NotImplementedExpcetion.

Проверьте исходный код и более подробную информацию здесь

...