Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

May I have a C# compile time error when a switch doesn't handle one or more enum values? [duplicate]

Suppose I have a switch over some variable holding an enum:

SomeEnum variable;
switch( variable ) {
   case Option1:
      Magic1;
      break;
   case Option2:
      Magic2;
      break;
   default:
      throw new InvalidOperationException();
}

and I know that the switch must handle all possible enum values so that if a new value is added into the enum the switch must be altered and this is why I add default that throws an exception.

The problem is there's no error indication until the code is run and control passed through default and the exception is thrown (and btw the exception can well be silenced somewhere up the call stack).

I'd like to have a compile time error here. For example, Visual C++ can emit C4062 warning when there's no default and one or more value is unhandled and that warning can be promoted to an error. I could have just eliminated default in my code and make use of that warning.

Can I have something similar in C#?

like image 624
sharptooth Avatar asked Mar 05 '14 08:03

sharptooth


Video Answer


1 Answers

No, you will need to write a unit test. The compiler won't do that for you.

A unit test might look something like:

public void TestSwitch()
{
    foreach (var variable in (SomeEnum[])Enum.GetValues(typeof(SomeEnum)))
        Assert.DoesNotThrow(() => YourMethod(variable), "Value {0} not supported", variable);
}

depending on your test framework.

Actually, any value of the underlying integral type (for example all 4,294,967,296 values if the underlying type is int which it almost always is) are possible, and you never write that many case labels, I presume. I know you want only the values with names, but as I said, the compiler will not check that for you. It only checks if two case refer to the same value.

I suggest you put:

if (!Enum.IsDefined(typeof(SomeEnum), variable))
    throw new InvalidOperationException();

somewhere, if your enum does not have the [Flags] attribute, but it clearly only works at runtime.

like image 138
Jeppe Stig Nielsen Avatar answered Oct 21 '22 08:10

Jeppe Stig Nielsen