Binding a switch to an Enum at compile time?

G

Guest

Is it possible to bind a switch statement to an Enum such that a compile-time
error is raised if not all values within the Enum are handled in the switch
statement? I realise you can use default: to catch unhandled cases, but of
course this is only at run-time.

Example:
public enum MyEnum
{
one, two, three, four
}

....

MyEnum myVar;
switch (myVar)
{
case MyEnum.one:
break;
case MyEnum.two:
break;
case MyEnum.three:
break;
// I would like this to raise a compilation error as there is no case
for MyVar.four
}

Thanks, Adam
 
B

Benoit Vreuninckx

Adam said:
Is it possible to bind a switch statement to an Enum such that a compile-time
error is raised if not all values within the Enum are handled in the switch
statement? I realise you can use default: to catch unhandled cases, but of
course this is only at run-time.

Example:
public enum MyEnum
{
one, two, three, four
}

....

MyEnum myVar;
switch (myVar)
{
case MyEnum.one:
break;
case MyEnum.two:
break;
case MyEnum.three:
break;
// I would like this to raise a compilation error as there is no case

default:
System.Diagnostics.Debug.Assert(false, "unhandled enum value");
break;
for MyVar.four
}

Thanks, Adam

That compiler option does not exist (or I must be unaware of it).
I suggest calling Debug.Assert(false) in the default clause. This way
you are notified of any unhandled values, that is, in the debug version
of your application. The release version will silently ignore the
assert statement. You could also throw an exception in the default
case, but this would also happen in the release version, which might not
be very appealing.
BTW, I added some code inline.

Cheers,

Benoit.
 
G

Guest

Thanks for your response. Your idea is useful, but unfortunately it still
relies on traversing all code paths (and developers to be watching the Output
window).

Adam
 
S

Sahil Malik

A compilation error doesn't make sense there since during compile time, the
value of myVar is not populated.
You do want a runtime error though, and Debug.Assert is a good suggestion
there. Debug.Assert will not require the developers to look at the output
window.

You could always throw an exception for a little bit more intrusive alert.

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik
 
G

Guest

What i was after is an indication - at compilation - if there *could ever be*
a value of myVar that is not handled.
 
G

Guest

My point is that the value myVar *must* be one of the 4 values in the Enum
MyEnum (so the compiler does in fact know what we might be sending down that
code path - it is either one, two, three or four; nothing else) but only 3 of
them are handled by the switch statement. I know that at compilation myVar
has no value, but it is logically possible to determine that the switch
statement does not handle all possible values.

regards, Adam
 
N

Nicole Calinoiu

Adam Blair said:
My point is that the value myVar *must* be one of the 4 values in the Enum
MyEnum (so the compiler does in fact know what we might be sending down
that
code path - it is either one, two, three or four; nothing else)

Unfortunately, that's not the case. myVar can be assigned any value from
the enum's underlying type (usually an integer).

but only 3 of
them are handled by the switch statement. I know that at compilation myVar
has no value, but it is logically possible to determine that the switch
statement does not handle all possible values.

Your best approach here might be a custom FxCop rule. In addition to
screening for all values from the enum, you might also want to consider
also enforcing using of a default clause to handle possible values that are
not defined by the enum.
 
C

cody

System.Diagnostics.Debug.Assert(false, "unhandled enum value");

For such things

System.Diagnostics.Debug.Fail("unhandled enum value");

is shorter :)
 
B

Benoit Vreuninckx

Sahil said:
Right, and as I said .. the values are not populated at compile time, so the
compiler has no way of knowing what you might be sending down that code
path. Which is why the default keyword.

In short - not possible to do.

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik





but of

Hi,

He just wanted to know if the compiler is able to check if all the
possible values of an enumeration have a corresponding case in the
switch statement. So if one adds a new value to the enumeration, the
compiler should throw a warning/error on all switch statements not
explicitly handling that new value.

Cheers,
Benoit.
 
G

Guest

I disagree. If i define an Enum as in my example and then attempt to assign
myVar to, say, 5 (myVar = 5) I recieve the build error "Cannot implicitly
convert type 'int' to 'MyEnum'". myVar *must* be one of the 4 values in the
Enum and so this scenario could be trapped at compile time.

I can accept that this is not possible (apart from the partial solutions
already posted) but maybe a syntax could be supported along the lines of

switch (myVar : MyEnum)
{
case one:
....
}
 
G

Guest

Hang on, you are right! I have succeeded in assigning myVar to 5 (myVar =
(MyEnum)5;) so I accept your point. Although I am slightly confused why it
should be possible to assign a Enum typed variable to a value outside of the
enum range.

Adam
 
J

James Curran

In short - not possible to do.

Nonsense.

The compiler knows that myVar is of type MyEnum.
The compiler knows that MyEnum can legally have any of 4 values.
The compiler knows that only 3 of them are represented in switch
statement.

Hence the compiler knows enough to generate a warning.

Your argument that myVar could also hold illegal values is irrelevant.

--
Truth,
James Curran
[erstwhile VC++ MVP]
Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
 
N

Nicole Calinoiu

Adam Blair said:
Hang on, you are right! I have succeeded in assigning myVar to 5 (myVar =
(MyEnum)5;) so I accept your point. Although I am slightly confused why it
should be possible to assign a Enum typed variable to a value outside of
the
enum range.

At least two reasons:

1. Inter-version compatibility.
2. Combinations in flagged enums.

These are also reasons why it might be best to use FxCop to detect
deviations from full coverage in a switch. In some cases, it might be
desirable to omit particular values and/or a default clause, and FxCop
allows one to save reasons for exceptions to rule violations, so you
wouldn't need to re-visit each exception at each compilation.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top