3

Just had a look at the "new" C# 8.0 Features

So I tried to rewrite the following code

    private static void RunExample(ExampleCode exampleCode)
    {
        switch(exampleCode)
        {
            case ExampleCode.DefaultInterfaceMethod:
                RunDefaultInterfaceMethodExample();
                break;
            case ExampleCode.PatternMatchingEnhancements:
                RunPatternMatchingEnhancementsExample();
                break;
        }      
    }

to this:

    private static void RunExample(ExampleCode exampleCode)
    {
        exampleCode switch
        {
            ExampleCode.DefaultInterfaceMethod => RunDefaultInterfaceMethodExample(),
            ExampleCode.PatternMatchingEnhancements => RunPatternMatchingEnhancementsExample()
        };           
    }

However, I am getting the following compile error:

Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement.

Compile Error

How can I rewrite this in the new syntax?

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
Fabian Bigler
  • 10,403
  • 6
  • 47
  • 70
  • What options are you compiling with? What does that prominent "Show potential fixes" suggest? – underscore_d Jan 06 '20 at 14:14
  • 1
    @underscore_d .NET Core 3.0. Potential fixes shows literally 'Nothing' ;-) – Fabian Bigler Jan 06 '20 at 14:16
  • As the error is pointing you are not allowed to fire and forget, which means that the new pattern matching switch is expecting to return something (this is common for expression, it happens so that c# does not treat void as actual result), if your cases where returning results and then assign the result to variable you will be OK. – vasil oreshenski Jan 06 '20 at 14:19
  • @vasiloreshenski Then how would you resolve it beautifully? – Fabian Bigler Jan 06 '20 at 14:21
  • @Fabian Refer this link https://dotnetcoretutorials.com/2019/06/25/switch-expressions-in-c-8/ – Ishwar Gagare Jan 06 '20 at 14:23
  • @IshwarGagare Thanks for your reply, but this does not solve the issue at hand. – Fabian Bigler Jan 06 '20 at 14:28
  • @FabianBigler this is a completely new switch *expression*. Like all expressions, it *has* to produce a value. It's not alternative syntax for the old switch *statement* – Panagiotis Kanavos Jan 07 '20 at 12:03
  • @FabianBigler in any case, the original code isn't using pattern matching, it looks like switching on enum values. You can't use exhaustive pattern matching with enum values (they are just numbers after all), so you won't get any benefit from using a switch expression – Panagiotis Kanavos Jan 07 '20 at 12:05

1 Answers1

3

As pointed in the comments the new switch based pattern matching is expecting result to be returned.

In F# because everything is an expression, the void type is actually a valid return type for an expression and this would have worked.

In case like yours i think it is best to use the old code, but if you really want to use the new syntax you can do something like this:

Action methodToExecute = exampleCode switch
{
  ExampleCode.DefaultInterfaceMethod => RunDefaultInterfaceMethodExample,
  ExampleCode.PatternMatchingEnhancements => RunPatternMatchingEnhancementsExample,
  _ => throw new NotImplementedException()
};     
methodToExecute();

(this will work only if the methods you are executing for each case have the same definitions)

It is good practice to use exhaustive pattern, this is why i am using the last case with the underscore. In C# enum values are compiled to integers and even if your switch handles all enum labels the compiler still does not know you have handled all cases and when you add new label to the enum you won't have proper warrning that you are have unhandled case.

Whenever you are using enums it is best to use default case where all unhandled cases will fall in.

vasil oreshenski
  • 2,788
  • 1
  • 14
  • 21