TL; DR
Это невозможно. In C# 8
switch expression
не может вернуть void
. Он должен возвращать значение, и это значение должно быть использовано (присвоено переменной, передано как аргумент методу, возвращено как результат метода, et c.). Но есть обходной путь. Мы можем написать switch expression
, которое возвращает delegate
(например, типа Action
), а затем сразу вызывает его:
(stringValue switch
{
"Add" => (Action) Add,
"Subtract" => Subtract
})();
Пояснение
Возможно ли это?
В C# 8
это невозможно. Это ограничение описано в C# specification
.
Обратимся к C# specification
. На страницах Recursive Pattern Matching - Switch Expression
и Statements
мы можем узнать, что:
-
switch_expression
не допускается в качестве expression_statement
.
expression_statement
оценивает данное выражение. Значение, вычисленное выражением, если оно есть, отбрасывается.
Из этих двух операторов мы можем сделать вывод, что switch_expression
не может использоваться в контексте expression_statement
, и его значение результата не может быть отброшено . Значение результата должно использоваться, например, оно должно быть присвоено переменной, передано методу в качестве аргумента или возвращено как результат метода. Поэтому компилятор жалуется, что switch expression
нельзя использовать как оператор.
если нам просто нужно включить строковое значение и выполнить метод, который ничего не возвращает (без возвращаемого типа / void), как мы go об этом? Я думаю о какой-то форме Fun c, но не уверен в точном синтаксисе.
Мы можем использовать следующий подход: написать switch expression
, который возвращает delegate
, а затем сразу вызывает его . Например:
(stringValue switch
{
"Add" => (Action) Add,
"Subtract" => Subtract
})();
Этот подход также можно использовать для объявления expression bodied members
:
private static void Demo(string str) =>
(str switch
{
"Add" => (Action) Add,
"Subtract" => Subtract,
_ => throw new ArgumentOutOfRangeException()
})();
Вот полный образец .
На мой взгляд, такой обходной путь выглядит некрасиво, и лично я предпочел бы использовать switch-case
или if-else
вместо такой конструкции.
Возможно, в будущей версии C#
это ограничение будет ослаблено ( см. Эту ссылку ):
switch_expression
не допускается как expression_statement
.
Мы планируем смягчить это в будущих версиях.
Но я не нашел подходящего предложения в csharplang repo
.