Shi*_*aru 22 c# switch-statement c#-8.0 switch-expression
我知道C# 8 switch expression返回值或属性匹配的方法的语法。但是如果我们只需要打开一个字符串值并执行一个不返回任何内容(没有返回类型/void)的方法,那么我们该怎么做呢?我正在考虑某种形式的 Func 但不确定确切的语法。我知道我们可以用常规的 case 语句用旧的方式来做,但试图看看我们是否可以用新的语法实现同样的效果。
这是问题的例子
switch (stringvalue)
{
case "Add": Add(); break;
case "Subtract": Subtract(); break;
}
Run Code Online (Sandbox Code Playgroud)
可能是这样的:
stringvalue switch
{
"Add" => Add(),
"Subtract" => Subtract()
}
// but this complains that there needs to be assignment on left side for this
Run Code Online (Sandbox Code Playgroud)
这可能吗?
Ili*_*hev 24
这不可能。在C# 8 switch expression无法返回void。它必须返回一个值并且必须使用该值(分配给变量、作为参数传递给方法、作为方法的结果返回等)。但是有一个解决方法。我们可以编写 aswitch expression返回 adelegate(Action例如类型),然后立即调用它:
(stringValue switch
{
"Add" => (Action) Add,
"Subtract" => Subtract,
_ => throw new ArgumentOutOfRangeException()
})();
Run Code Online (Sandbox Code Playgroud)
这种方法也可以与expression bodied methods. 这是演示。
这可能吗?
在C# 8它是不可能的。此限制在 中描述C# specification。
让我们参考C# specification。从网页Recursive Pattern Matching - Switch Expression和Statements我们可以得知:
所述
switch_expression不允许作为expression_statement。
An
expression_statement计算给定的表达式。表达式计算的值(如果有)将被丢弃。
从这两个语句我们可以得出结论,switch_expression不能在 的上下文中使用expression_statement,并且它的结果值不能被丢弃。必须使用结果值,例如,必须将其分配给变量、作为参数传递给方法或作为方法的结果返回。因此编译器抱怨switch expression不能用作语句。
如果我们只需要打开一个字符串值并执行一个不返回任何内容(无返回类型/void)的方法,我们该怎么做?我正在考虑某种形式的 Func 但不确定确切的语法。
我们可以使用下一种方法:编写switch expression返回 a 的 adelegate然后立即调用它。例如:
(stringValue switch
{
"Add" => (Action) Add,
"Subtract" => Subtract,
_ => throw new ArgumentOutOfRangeException()
})();
Run Code Online (Sandbox Code Playgroud)
这种方法也可用于声明expression bodied members:
private static void Demo(string str) =>
(str switch
{
"Add" => (Action) Add,
"Subtract" => Subtract,
_ => throw new ArgumentOutOfRangeException()
})();
Run Code Online (Sandbox Code Playgroud)
这是完整的示例。
在我看来,这种解决方法看起来很丑陋,我个人更喜欢使用switch-case或if-else代替这种结构。
可能在未来版本中C#会放宽此限制(请参阅此链接):
所述
switch_expression不允许作为expression_statement。我们正在考虑在未来的修订中放宽这一点。
但是我在csharplang repo.
正如伊利亚尔告诉你的那样,这是不可能的。我有时使用的解决方法是添加一个始终返回 true 的本地函数,并在开关分配中使用丢弃字符。我发现这种解决方案比使用委托的解决方案更清晰一些。
\n例如,您可以在切换之前将其添加到代码中:
\nbool Add() { [HEREYOURCODEToAdd]; return true;}\nbool Substract() { [HEREYOURCODETOSubstract]; return true;}\nRun Code Online (Sandbox Code Playgroud)\n然后你会这样称呼它:
\n_ = stringvalue switch {\n "Add" => Add(),\n "Substract" => Substract(),\n};\nRun Code Online (Sandbox Code Playgroud)\n我认为这种方法有一些用例。例如,如果您想在 switch 中使用元组模式,它将比许多已确定的 if 更具可读性。这是我正在使用的代码,我认为这种方法比 ifs 更好:
\n bool agregar(int \xc3\xadndiceInicial, int \xc3\xadndiceFinal) { visitasJson.Add(json[\xc3\xadndiceInicial..\xc3\xadndiceFinal]); return true; };\n _ = (\xc3\xadndiceInicial, \xc3\xadndiceFinal) switch {\n (0, -1) => agregar(\xc3\xadndiceInicial + 1, \xc3\xadndiceFinal - 3),\n (_, -1) => agregar(\xc3\xadndiceInicial, \xc3\xadndiceFinal - 1),\n (0, _) => agregar(\xc3\xadndiceInicial + 5, \xc3\xadndiceFinal),\n (_, _) => agregar(\xc3\xadndiceInicial, \xc3\xadndiceFinal),\n };\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
5641 次 |
| 最近记录: |