我知道用于返回值或属性匹配的方法的 C#8 switch expression 语法.但是,如果我们只需要打开一个字符串值并执行不返回任何内容的方法(不返回类型/void),那么我们该如何处理呢?我在考虑某种形式的Func,但不确定确切的语法.我知道我们可以使用常规的case语句以旧方式完成此操作,但是试图查看是否可以使用较新的语法实现相同的功能.
I'm aware of the C# 8 switch expression syntax for methods that return a value or for property matching. But if we just need to switch on a string value and execute a method that returns nothing (no return type/void), then how do we go about it? I am thinking some form of Func but not sure of the exact syntax. I know we can do it the old way with regular case statements but was trying to see if we can achieve the same with the newer syntax.
这是问题的例子
switch (stringvalue) { case "Add": Add(); break; case "Subtract": Subtract(); break; }可能像:
stringvalue switch { "Add" => Add(), "Subtract" => Subtract() } // but this complains that there needs to be assignment on left side for this这可能吗?
推荐答案TL; DR
不可能. 在 C#8 中 switch表达式无法返回 void .它必须返回一个值,并且必须使用此值(分配给变量,作为参数传递给方法,作为方法的结果返回等).但是有一种解决方法.我们可以编写一个 switch表达式,该表达式返回一个 delegate (例如,类型为 Action 的代表),然后立即调用它:
TL;DR
It is not possible. In C# 8 switch expression cannot return void. It must return a value and this value must be consumed (assigned to a variable, passed as an argument to a method, returned as a result of a method, etc.). But there is a workaround. We can write a switch expression that returns a delegate (of type Action, for example) and then immediately invokes it:
(stringValue switch { "Add" => (Action) Add, "Subtract" => Subtract, _ => throw new ArgumentOutOfRangeException() })();这种方法也可以与表达式主体方法一起使用.这是演示.
Such approach also can be used with expression bodied methods. Here is demo.
这可能吗?
在 C#8 中是不可能的.此限制在 C#规范中描述.
In C# 8 it is not possible. This limitation is described in C# specification.
请参考 C#规范.从页面 递归模式匹配-开关表达式 和 声明 ,我们可以了解到:
Lets refer to C# specification. From pages Recursive Pattern Matching - Switch Expression and Statements we can learn that:
不允许将 switch_expression 作为 expression_statement .
expression_statement 评估给定的表达式.由表达式计算的值(如果有的话)将被丢弃.
An expression_statement evaluates a given expression. The value computed by the expression, if any, is discarded.
从这两个语句可以得出结论, switch_expression 不能在 expression_statement 的上下文中使用,并且其结果值 不能被丢弃.必须使用结果值,例如,必须将结果值分配给变量,将其作为参数传递给方法或作为方法的结果返回.因此,编译器抱怨 switch表达式不能用作语句.
From these two statements we can conclude that switch_expression cannot be used in the context of expression_statement, and its result value cannot be discarded. The result value must be used, for example, it must be assigned to a variable, passed to a method as an argument or returned as a result of a method. Therefore compiler complains that switch expression cannot be used as a statement.
如果我们只需要打开一个字符串值并执行一个方法,什么都不返回(没有返回类型/void),我们该如何处理呢?我是在考虑某种形式的Func,但不确定确切的语法.
if we just need to switch on a string value and execute a method that returns nothing (no return type/void), how do we go about it? I am thinking some form of Func but not sure of the exact syntax.
我们可以使用下一种方法:编写一个 switch表达式,该表达式返回一个 delegate ,然后立即调用它.例如:
We can use the next approach: write a switch expression that returns a delegate and then immediately invokes it. For example:
(stringValue switch { "Add" => (Action) Add, "Subtract" => Subtract, _ => throw new ArgumentOutOfRangeException() })();此方法也可以用于声明表达式主体成员:
This approarch also can be used to declare expression bodied members:
private static void Demo(string str) => (str switch { "Add" => (Action) Add, "Subtract" => Subtract, _ => throw new ArgumentOutOfRangeException() })();这里是完整示例.
我认为这样的解决方法看起来很丑陋,我个人更喜欢使用 switch-case 或 if-else 代替这种构造.
In my opinion such workaround looks ugly and personally I would prefer to use switch-case or if-else instead of such construction.
可能在 C#的未来版本中,此限制将得到放松(查看此链接):
May be in future version of C# this limitation will be relaxed (see this link):
不允许将 switch_expression 作为 expression_statement .
我们正在考虑在将来的版本中放松这一点.
We are looking at relaxing this in a future revision.
但是我没有在 csharplang回购 .
But I haven't found an appropriate proposal in csharplang repo.
更多推荐
无效方法的C#8开关表达式
发布评论