在 C# switch 表达式中使用块?

Posted

技术标签:

【中文标题】在 C# switch 表达式中使用块?【英文标题】:Using blocks in C# switch expression? 【发布时间】: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 来实现所需的行为,但是我很好奇在这种情况下是否可以使用开关表达式。

【问题讨论】:

阅读expression vs statement可能会有用。 【参考方案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

【讨论】:

以上是关于在 C# switch 表达式中使用块?的主要内容,如果未能解决你的问题,请参考以下文章

第三課

c# 8.0 switch 表达式中的多个案例[重复]

有没有办法让 switch 使用 C# 8 switch 表达式返回字符串值?

C#探索之路:表现力不够但简洁的switch 表达式

c# 8 switch 表达式:没有找到 switch 表达式的最佳类型

C# switch 表达式 null 大小写