switch 表达式中的多个语句:C# 8

JL0*_*0PD 12 c# c#-8.0 switch-expression

Switch 表达式是在 C# 8 中引入的。代码库中有很多地方可以用这种新风格重写。

例如,我有一些代码,用于从字节流中解析数据包:

switch (command)
{
    case Command.C1:
        return new P1();
    case Command.C2:
        return new P2();
    default:
        stream.Position++;
        return null;
}
Run Code Online (Sandbox Code Playgroud)

问题是 - 它不能转换为像这样的 switch 表达式

return command switch
{
    Command.C1 => new P1(),
    Command.C3 => new P2(),
    _ => { stream.Position++; return null; }
};
Run Code Online (Sandbox Code Playgroud)

我想到的第一件事是使用 a Func<>,它编译:

return command switch
{
    Command.C1 => new P1(),
    Command.C3 => new P2(),
    _ => new Func<AbstractPacket>(() => { stream.Position++; return null; })()
};
Run Code Online (Sandbox Code Playgroud)

F# 已经允许在每个分支中包含多个语句的代码:

match command with
| Command.C1 -> Some(P1() :> AbstractPacket)
| Command.C2 -> Some(P2() :> AbstractPacket)
| _ ->
    stream.Position <- stream.Position + 1
    None
Run Code Online (Sandbox Code Playgroud)

现在我被困在使用 switch 语句中,但是有没有任何选项可以将其编写为 switch 表达式而没有任何奇怪的技巧?

Joh*_*ord 13

您唯一支持的选择是像您一样的 func 。有关更多信息,请参阅此文章。他的例子:

var result = operation switch
{
"+" => ((Func<int>)(() => {
    Log("addition");
    return a + b;
}))(),
"-" => ((Func<int>)(() => {
    Log("subtraction");
    return a - b;
}))(),
"/" => ((Func<int>)(() => {
    Log("division");
    return a / b;
}))(),
_ => throw new NotSupportedException()
};
Run Code Online (Sandbox Code Playgroud)

仅仅因为 switch 表达式是新的并不意味着它们是所有用例的最佳选择。它们并非旨在包含多个命令。

  • _“它的设计目的不是包含多个命令。”_并且当然不更具可读性。 (4认同)
  • @Jeroen van Langen 这是今年最轻描淡写的说法。 (2认同)

小智 6

和:

TRes Call<TRes>(Func<TRes> f) => f();
Run Code Online (Sandbox Code Playgroud)

它看起来像:

return command switch {
  Command.C1 => new P1(),
  Command.C3 => new P2(),
  _ => Call(() => { stream.Position++; return null; }),
};
Run Code Online (Sandbox Code Playgroud)

或者:

var result = operation switch {
  "+" => Call(() => {
    Log("addition");
    return a + b;
  }),
  "-" => Call(() => {
    Log("subtraction");
    return a - b;
  }),
  "/" => Call(() => {
    Log("division");
    return a / b;
  }),
  _ => throw new NotSupportedException(),
};
Run Code Online (Sandbox Code Playgroud)

  • 这也基本上剥夺了我的答案 (3认同)
  • 一般来说,如果答案包含对代码用途的解释,以及为什么在不介绍其他内容的情况下解决问题的原因,那么它们会更有帮助。 (2认同)