C# 8 switch expression for void methods

TL;DR

It is not possible. In C# 8 switch expression cannot return void. It must return a value and this value must be consumed (assigned to a variable, passed as an argument to a method, returned as a result of a method, etc.). But there is a workaround. We can write a switch expression that returns a delegate (of type Action, for example) and then immediately invokes it:

(stringValue switch
 {
    "Add" => (Action) Add,
    "Subtract" => Subtract,
    _ => throw new ArgumentOutOfRangeException()
 })();

Such approach also can be used with expression bodied methods. Here is demo.


Explanation

Is this possible?

In C# 8 it is not possible. This limitation is described in C# specification.

Lets refer to C# specification. From pages Recursive Pattern Matching - Switch Expression and Statements we can learn that:

  • The switch_expression is not permitted as an expression_statement.

  • An expression_statement evaluates a given expression. The value computed by the expression, if any, is discarded.

From these two statements we can conclude that switch_expression cannot be used in the context of expression_statement, and its result value cannot be discarded. The result value must be used, for example, it must be assigned to a variable, passed to a method as an argument or returned as a result of a method. Therefore compiler complains that switch expression cannot be used as a statement.


if we just need to switch on a string value and execute a method that returns nothing (no return type/void), how do we go about it? I am thinking some form of Func but not sure of the exact syntax.

We can use the next approach: write a switch expression that returns a delegate and then immediately invokes it. For example:

(stringValue switch
 {
    "Add" => (Action) Add,
    "Subtract" => Subtract,
    _ => throw new ArgumentOutOfRangeException()
 })();

This approarch also can be used to declare expression bodied members:

private static void Demo(string str) =>
    (str switch
     {
         "Add" => (Action) Add,
         "Subtract" => Subtract,
         _ => throw new ArgumentOutOfRangeException()
     })();

Here is complete sample.

In my opinion such workaround looks ugly and personally I would prefer to use switch-case or if-else instead of such construction.


May be in future version of C# this limitation will be relaxed (see this link):

The switch_expression is not permitted as an expression_statement.

We are looking at relaxing this in a future revision.

But I haven't found an appropriate proposal in csharplang repo.