Is there a way to have the c# compiler display warnings when a switch statement do have unhandled cases?
Asked Answered
B

6

9

Consider the following code :

        private enum myEnum
        {
            A,
            B
        }
        private void myMethod(myEnum m)
        {
            switch (m)
            {
                case myEnum.A:
                    //do stuff
                break;
                case myEnum.B:
                   //do stuff
                break;
                default:
                   throw new NotImplementedException(m.ToString());
            }
        }

If I ever add a third member C to myEnum, I will only be warned at runtime by a NotImplementedException

What I'd like to do is have the compiler warn me when there's a switch with unhandled cases and no default: case.

Is there a way to do that, or other solution to this problem, the ultimate goal being to be warned at compile-time that something is missing?

Beseem answered 2/4, 2009 at 8:33 Comment(0)
S
6

Unfortunately here is no compiler feature to do this for you.

Instead of having an enum, have a base class or an interface. MyMethod is defined on the interface.

Each each enum member now becomes a class with different behaviour for myMethod. If you add a class (to extend the options, currently you'd add an enum item)but don't implement myMethod, you'll get a compiler error.

having lots of place's in code where you provide different behaviour in select statements is a smell that you may need to use polymorphism.

EDIT

The best advice I can give is to build unit tests for each function that relies on the switch statement, and call it for each value in the enumeration (you can get the values at runtime with the GetValues member on the Enum class)

Shamanism answered 2/4, 2009 at 8:38 Comment(4)
That's a good point. But in my situation, I don't think it applies (it would lead to almost empty classes, containing some logic that's not of their responsibility. Typically, I have some DataContracts containing enumerated member, and my GUI switches on those members to see how to format them.)Beseem
A good pattern, but use it with care. If your enum is large and your switch only needs to handle a few cases you probably don't want to create a zillion classes.Higginson
You should post your edit as a separate answer, unit tests combine run-time knowledge with failing before the code gets into productionSwaziland
@janv8000: The answer is 11 years old, if you feel strongly that the edit detracts from the answer then by all means edit it out.Shamanism
R
2

No, there's nothing in the language to check this.

You can have a:

default:
    throw new ArgumentOutOfRangeException("Invalid value or bug");

case, but obviously that's execution-time rather than compile-time.

Resolutive answered 2/4, 2009 at 8:53 Comment(0)
E
1

Never used it, but FxCop may be helpful. It supports writing custom rules. Of course, that's not a compile-time check, but something that can be integrated into your processes.

Eventuality answered 2/4, 2009 at 11:5 Comment(0)
W
0

This can become a maintenance nightmare, had to spend a looooooot of time trying to debug a missing enum value in a switch statement.

Wrote a small class to make switch statements over a little more maintenance friendly,

enter image description here

The class makes sure that all the enum values are either handled or explicitly ignored, it throws a NotImplementedExpcetion otherwise.

Check out the source code and more details here

Whirl answered 30/4, 2013 at 22:49 Comment(0)
C
0

I have written a library for doing Discriminated Unions in C#, which would be a solution for providing exhaustive matching at compile time. See https://github.com/mcintyre321/OneOf

Install-Package OneOf

It has the generic types in it for doing DUs e.g. OneOf all the way to OneOf. Each of those has a .Match, and a .Switch statement which you can use for compiler safe typed behaviour, e.g.:

OneOf<A, B> aOrB = GetValue(); 
aOrB .Switch(
    a=> DoSomething(a),
    b=> DoSomethingElse(b)
)
Cabin answered 9/11, 2018 at 11:5 Comment(0)
A
0

You can use the JetBrains ReSharper extension or Rider IDE to perform this check.

ReSharper analysis will find cases where some of the enum values are not handled or are handled in the default section.

For detecting cases where value is not handled or handled with default, see: https://www.jetbrains.com/help/resharper/SwitchStatementHandlesSomeKnownEnumValuesWithDefault.html

For detecting only the cases where there is no default section: https://www.jetbrains.com/help/resharper/SwitchStatementMissingSomeEnumCasesNoDefault.html

You can increase the severity of such cases to be reported as errors. You can also use the free JetBrains InspectCode tool in your build pipeline to detect such errors, see: https://www.jetbrains.com/help/resharper/InspectCode.html

Aweather answered 22/1 at 20:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.