Вопрос, который я задаю, относится к Как вы пишете код, логика которого защищена от будущих дополнительных перечислений? , но имеет возможность быть более общим.
Для простотыЯ рассмотрю только эти два ответа ( 1 , 2 ) на этот вопрос , потому что я не хочу слишком сильно реструктурировать код.
Решение 1 обрабатывает ситуацию, генерируя исключение времени выполнения в блоке по умолчанию оператора switch, когда значением switch является значение enum, которое специально не обрабатывается.Если это происходит во время тестирования, разработчику будет предложено пересмотреть код и добавить код обработки для этого конкретного значения перечисления в операторе switch.
Решение 2 делает это с помощью шаблона посетителя.поэтому любое добавление значений перечисления создаст время компиляции, если код, использующий это перечисление, не обновлен для отражения дополнительного значения.
Теперь оба решения являются действительными и хорошими.Тем не менее, я предпочитаю ошибку времени компиляции, а не исключение времени выполнения, если мой охват кода во время тестирования пропускает эту часть.Кроме того, более естественным является написание кода, подобного решению 1, над решением 2 (слишком длинным).
Поэтому я хотел бы знать, существует ли решение, обладающее как преимуществами ошибки времени компиляции решения 2, так ипростое добавление кода в решение 1?Можно ли написать какой-либо настраиваемый атрибут, чтобы указать, что конкретное перечисление при использовании в переключателе должно проверяться на предмет всех возможных значений перечисления в этом переключателе, и чтобы компилятор жаловался, если это нарушено.
[allValuesMustBeCheckedInSwitch]
enum Fruit {Apple, Banana, Coconut}
Fruit aFruit = Fruit.Apple;
switch (aFruit)
{
case Fruit.Apple:
//do something
break;
case Fruit.Banana:
//do something
break;
default:
break;
}
Было бы даже лучше, если бы я мог добавить что-то подобное к коммутатору, чтобы выборочно отключить ошибку компилятора (и, возможно, изменить его на предупреждение).
[checkOnly(Fruit.Apple,Fruit.Banana)]
Я сказал, что мой вопрос носит более общий характер, потому чтоЯ хотел бы знать, насколько выразительными могут быть пользовательские атрибуты, если раньше они не использовались.Этот пример является лишь одним конкретным ограничением, которое я хотел бы определить в своем коде, могут быть другие ограничения другого типа.
Если есть другие инструменты, которые могут выполнять аналогичные задачи, я хотел бы знать об этомтоже.