8

I fail to find documentation addressing this issue. (perhaps I am just bad at using google...) My guess is that the answer is negative, however I didn't understand where this is addressed in the documentation. To be precise my question is the following.

Suppose, I want to execute something like this:

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()
};

I understand that I can achieve the desired behavior by using the regular switch or if/else, however I was curious whether it is possible to use switch expression in this case.

Uwe Keim
  • 38,279
  • 56
  • 171
  • 280
Yuval K
  • 121
  • 1
  • 10
  • Might be useful to read [expression vs statement](https://stackoverflow.com/q/19132/1997232). – Sinatr Jan 14 '20 at 08:13

4 Answers4

14

however I didn't understand where this is addressed in the documentation

This is stated pretty clear here:

There are several syntax improvements here:

  • The variable comes before the switch keyword. The different order makes it visually easy to distinguish the switch expression from the switch statement.
  • The case and : elements are replaced with =>. It's more concise and intuitive.
  • The default case is replaced with a _ discard.
  • The bodies are expressions, not statements.

{ someDir.Delete(); ... MoreActions} is not an expression.

However, you can abuse every feature, as they say :)

You can make the switch expression evaluate to an Action, and invoke that action:

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

You can even reduce this to a single statement:

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

But just don't do this...

Sweeper
  • 176,635
  • 17
  • 154
  • 256
  • 1
    Why "but just don't do this..."? It looks still better than old switch or many if statements. – ca9163d9 Jan 17 '20 at 21:46
  • 3
    @ca9163d9 do you actually think this looks better, or is it just because it’s a new feature and it’s shiny? I don’t like this because 1. The switch expression is designed for expressions, not blocks of statements. 2. You need the word `Action` somewhere in there, which can be considered noise and is unsightly. Note that I’m not saying that you shouldn’t use the switch expression at all (just in case you have misunderstood). There are situations where the switch statement is suitable, and situations where the switch expression is suitable. – Sweeper Jan 17 '20 at 22:26
  • The switch statement is bulky when there is only one statement for each case. Every case will have at least three lines, `case:`, the statement, and the easy to be forgotten `break;`. In the simple case, I would like to use switch expression unless there is any performance issue. – ca9163d9 Jan 17 '20 at 22:48
  • 1
    @ca9163d9 well, how do you know that each case will always only have one statement? There could be a change in requirements that requires you to add another line in one of the cases. Plus, you can write the case label, the statement, and `break;` all on the same line if you prefer. Conversely, you can also write each case of the switch expression across multiple lines. Number of lines doesn’t quite matter here. As for the performance, I haven’t done any benchmarks so I don’t know. My guess is that the expression will be slower but it likely isn’t significant. – Sweeper Jan 17 '20 at 22:59
  • For example, each case just need to call a method/function. The changes go to the functions. – ca9163d9 Jan 23 '20 at 01:05
  • I think latter is ok when you are use returning lambdas: aka "block expressions". – Risord Apr 29 '21 at 12:48
6

As per documentation: The bodies are expressions, not statements.

You can do something like this though:

Action fn = response switch
{
    "yes" => () => { BlockTest(); },
     _ => () => { OldTest(); }
};
Markus Dresch
  • 4,873
  • 3
  • 20
  • 37
4

You can also introduce local function (C# 7.0 and above) and do something like:

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

void DoSomething()
{
    someDir.Delete();
    ... MoreActions
}
rePhat
  • 152
  • 1
  • 8
0

I think this feature will be there very soon. Proposal for this