16

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
  • 39,551
  • 56
  • 175
  • 291
Yuval K
  • 301
  • 2
  • 11
  • 1
    Might be useful to read [expression vs statement](https://stackoverflow.com/q/19132/1997232). – Sinatr Jan 14 '20 at 08:13

4 Answers4

25

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
  • 213,210
  • 22
  • 193
  • 313
  • 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
8

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
  • 314
  • 3
  • 9
7

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
  • 5,290
  • 3
  • 20
  • 40
  • @Sweeper right, corrected. any reasoning behind your "but just don't do this"? – Markus Dresch Jan 14 '20 at 08:57
  • 2
    Because the switch expression is not designed to be used like this? – Sweeper Jan 14 '20 at 12:04
  • It works just fine - don't see the problem. – lightw8 Apr 20 '21 at 15:29
  • 1
    @lightw8 think of it in terms of the "recent" javascript craze: just because you *can* doesn't necessarily mean you *should*. – Shai Cohen Jun 30 '21 at 17:22
  • @ShaiCohen yeah...but besides the extra bloat, it's more functional/declarative and some might like that. – lightw8 Jul 02 '21 at 05:43
  • @Shai Cohen and Sweeper, sometimes it's simply nice to have the choice: to still use the switch expression when there are a large number of cases where all but 1 or 2 outliers nicely fit the switch expression form. Versus being restricted to using the classic form for the entire switch statement because of a few outliers that I'd prefer to handle in a manner such as the OP suggests. – Richard II Jun 13 '22 at 18:51
0

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