Что произойдет, если мое выражение переключателя C# не является исчерпывающим?
В C# 8 были введены выражения переключения. Что происходит, если выражение switch не является исчерпывающим? Другими словами, что произойдет, если я не проверю все возможные значения?
static void Main(string[] args)
{
int x = 1;
int imExhaustive = x switch
{
3 => 4,
_ => 0 // x = 1 matches this
};
int okFine = x switch
{
1 => 4 // x = 1 matches this
};
int noMatch = x switch
{
3 => 4 // No match
};
}
4 ответа
Если switch
выражение не является исчерпывающим, компилятор выдает предупреждение. Во время выполнения, если вы передаете значение, которое не обрабатывается, SwitchExpressionException
брошен
Это описано в спецификации для новых шаблонов в C# 8.0: https://github.com/dotnet/csharplang/blob/master/proposals/csharp-8.0/patterns.md#switch-expression
Компилятор должен выдать предупреждение, если он доказывает (используя эти методы), что некоторое возможное входное значение может не совпадать с некоторым switch_expression_arm во время выполнения.
Во время выполнения результатом switch_expression является значение выражения первого switch_expression_arm, для которого выражение слева от switch_expression соответствует шаблону switch_expression_arm, и для которого case_guard switch_expression_arm, если имеется, оценивает к истине.
Если такого switch_expression_arm нет, switch_expression генерирует экземпляр исключения System.Runtime.CompilerServices.SwitchExpressionException.
Зависит.
Если есть совпадение: оно совпадает, и все хорошо.
Если нет совпадений: A SwitchExpressionException
брошен
Лучше всего писать исчерпывающие выражения переключателей. Если нет, и ничего не взрывается, возможно, вам просто повезло.
Компилятор предупредит вас, если ваше выражение switch не является исчерпывающим, но это не ошибка, и он все равно скомпилируется и запустится.
(Просто наткнулся на это, поэтому подумал, что поделюсь - пока нигде в документации нет, хотя C# 8 все еще в Preview)
Чтобы удалить это предупреждение, добавьте выражение по умолчанию.
exception switch
{
ValidationException vExp => new ValidationErrorDetail
{
},
ApiException apiExp => new ApiErrorDetail
{
},
ProcessException pExp => new ErrorDetail
{
},
_ => new ErrorDetail
{
}
};
Добавлять
_ =>
и Выражение по умолчанию для выполнения.
В случае безымянных значений перечисления я считаю поведение C# по выбрасыванию исключений правильным и желательным. Поэтому я отключаю предупреждение в своем .editorconfig:
[*.cs]
dotnet_diagnostic.CS8524.severity = none # The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value.