【问题标题】:Using blocks in C# switch expression?在 C# switch 表达式中使用块?
【发布时间】:2020-04-30 22:10:49
【问题描述】:

我找不到解决此问题的文档。 (也许我只是不擅长使用谷歌......) 我的猜测是答案是否定的,但是我不明白文档在哪里解决了这个问题。 确切地说,我的问题如下。

假设,我想执行如下操作:

DirectoryInfo someDir = new DirectoryInfo(@".\someDir");
Console.WriteLine($"Would you like to delete the directory {someDir.FullName}?");
string response = Console.ReadLine().ToLower();

response switch
{
    "yes" => { someDir.Delete(); ... MoreActions},
     _ => DoNothing()
};

我知道我可以通过使用常规开关或 if/else 来实现所需的行为,但是我很好奇在这种情况下是否可以使用开关表达式。

【问题讨论】:

标签: c# c#-8.0 switch-expression


【解决方案1】:

但是我不明白文档在哪里解决了这个问题

这说得很清楚here:

这里有几个语法改进:

  • 变量位于 switch 关键字之前。不同的顺序使得在视觉上很容易区分 switch 表达式和 switch 语句。
  • case 和 : 元素被替换为 =>。它更简洁直观。
  • 默认大小写替换为 _ 丢弃。
  • 正文是表达式,而不是语句。

{ someDir.Delete(); ... MoreActions} 不是表达式。

然而,你可以滥用每一个功能,正如他们所说:)

可以使 switch 表达式计算为 Action,并调用该操作:

Action a = response switch
{
    "yes" => () => { ... },
     _ => () => { .... }
};
a();

您甚至可以将其简化为一条语句:

(response switch
{
    "yes" => (Action)(() => { ... }),
     _ => () => { ... }
})();

但不要这样做......

【讨论】:

  • 为什么“但不要这样做……”?它看起来仍然比旧的 switch 或许多 if 语句好。
  • @ca9163d9 你真的认为这看起来更好,还是仅仅因为它是一个新功能并且它很闪亮?我不喜欢这个,因为 1. switch 表达式是为表达式设计的,而不是语句块。 2.你在某处需要Action这个词,这可以被认为是噪音并且不美观。请注意,我并不是说您根本不应该使用 switch 表达式(以防您误解了)。有适合switch语句的情况,也有适合switch表达式的情况。
  • 当每个 case 只有一个语句时,switch 语句是庞大的。每个案例至少有三行,case:、声明和容易被遗忘的break;。在简单的情况下,除非有任何性能问题,否则我想使用 switch 表达式。
  • @ca9163d9 好吧,你怎么知道每个案例总是只有一个语句?要求可能会发生变化,要求您在其中一种情况下添加另一行。另外,如果您愿意,您可以将 case 标签、语句和 break; 都写在同一行。相反,您也可以跨多行编写 switch 表达式的每个 case。行数在这里并不重要。至于性能,我没有做过任何基准测试,所以我不知道。我的猜测是表达式会变慢,但可能并不重要。
  • 例如,每个案例只需要调用一个方法/函数。更改转到函数。
【解决方案2】:

As per documentation: 正文是表达式,而不是语句。

你可以这样做:

Action fn = response switch
{
    "yes" => () => { BlockTest(); },
     _ => () => { OldTest(); }
};

【讨论】:

  • @Sweeper 正确,已更正。您的“但不要这样做”背后的任何理由?
  • 因为switch表达式不是这样设计的?
  • 它工作得很好 - 看不到问题。
  • @lightw8 以“最近”的 JavaScript 热潮来考虑它:仅仅因为你可以并不一定意味着你应该
  • @ShaiCohen 是的......但除了额外的臃肿之外,它更具功能性/声明性,有些人可能会喜欢这样。
【解决方案3】:

你也可以引入local function(C# 7.0 及以上)并做类似的事情:

response switch
{
    "yes" => DoSomething(),
     _ => DoNothing()
};

void DoSomething()
{
    someDir.Delete();
    ... MoreActions
}

【讨论】:

    【解决方案4】:

    我认为这个功能很快就会出现。 Proposal for this

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-14
      • 1970-01-01
      • 1970-01-01
      • 2020-04-30
      • 2014-11-06
      相关资源
      最近更新 更多