Internal Error and enums

  • Thread starter Thread starter alunharford
  • Start date Start date
A

alunharford

When I'm coding in Java, I might write the following (contrived) code:

boolean b = SomeMethod();
switch (b) {
case true:
return 1;
case false:
return 0;
default:
throw new InternalError();
}

InternalError indicates that something has gone massively wrong with
either the compiler or the virtual machine.

In C#, the avaliability of enums means that this seems more vital.

enum Foobar {
ONE,
TWO,
THREE
}
....
Foobar foobar = SomeMethod();
switch (foobar) {
case Foobar.ONE:
return 1;
case Foobar.TWO:
return 2;
case Foobar.THREE:
return 3;
default:
//What do I put here?
}

I could just change case "Foobar.THREE:" to "default:", but that
reduces readability.

I've been looking for an equivalent of InternalError in C#, but can't
find one in the standard. What do other people do in a situation like
this?

Alun Harford
 
When I'm coding in Java, I might write the following (contrived) code:

boolean b = SomeMethod();
switch (b) {
case true:
return 1;
case false:
return 0;
default:
throw new InternalError();
}

InternalError indicates that something has gone massively wrong with
either the compiler or the virtual machine.

In C#, the avaliability of enums means that this seems more vital.

enum Foobar {
ONE,
TWO,
THREE
}
...
Foobar foobar = SomeMethod();
switch (foobar) {
case Foobar.ONE:
return 1;
case Foobar.TWO:
return 2;
case Foobar.THREE:
return 3;
default:
//What do I put here?
}

I could just change case "Foobar.THREE:" to "default:", but that
reduces readability.

I've been looking for an equivalent of InternalError in C#, but can't
find one in the standard. What do other people do in a situation like
this?

You need to handle it as it would be possible to assign any int value to
foobar. It is an enum, but the underlying type by default for enum is int.
So you can assign a value of 4. For example, the body of SomeMethod could
be:

return (Foobar)4;

This would compile and run fine and hit your default. In your instance you
might consider throwing either a System.ArgumentException or
System.ComponentModel.InvalidEnumArgumentException.
 
Tom said:
(e-mail address removed) wrote:

You need to handle it as it would be possible to assign any int value to
foobar. It is an enum, but the underlying type by default for enum is int.
So you can assign a value of 4.

Good point. The problem can still occur though. Take the following
code:

switch((byte)foo) {
case 0:
return 0;
break;
case 1:
return 1;
break;
...
...
case 254:
return 254;
break;
case 255:
return 255;
break;
default:
//What here?
}

Alun Harford
 
When I'm coding in Java, I might write the following (contrived) code:

boolean b = SomeMethod();
switch (b) {
case true:
return 1;
case false:
return 0;
default:
throw new InternalError();
}

Except that Java doesn't let you switch on booleans :)
InternalError indicates that something has gone massively wrong with
either the compiler or the virtual machine.

In C#, the avaliability of enums means that this seems more vital.

enum Foobar {
ONE,
TWO,
THREE
}
...
Foobar foobar = SomeMethod();
switch (foobar) {
case Foobar.ONE:
return 1;
case Foobar.TWO:
return 2;
case Foobar.THREE:
return 3;
default:
//What do I put here?
}

I could just change case "Foobar.THREE:" to "default:", but that
reduces readability.

I've been looking for an equivalent of InternalError in C#, but can't
find one in the standard. What do other people do in a situation like
this?

InvalidOperationException is often appropriate:
"The exception that is thrown when a method call is invalid for the
object's current state."
 
Good point. The problem can still occur though. Take the following
code:

switch((byte)foo) {
case 0:
return 0;
break;
case 1:
return 1;
break;
...
...
case 254:
return 254;
break;
case 255:
return 255;
break;
default:
//What here?
}

Alun Harford

Hi Alun,

I think if, in the cases you are describing, the default case is ever
reached, then any code you put in there won't be executed anyway, or the
exceution will be undefined, because the CLI has more than likely given up.
 
Good point. The problem can still occur though. Take the following
code:

switch((byte)foo) {
case 0:
return 0;
break;
case 1:
return 1;
break;
...
...
case 254:
return 254;
break;
case 255:
return 255;
break;
default:
//What here?
}

Same answer as before, throw an exception with relevant information. There
isn't an equivalent to java's InternalError, but you could use
InvalidOperationException, InvalidEnumArgumentException or
InvalidArgumentException. BTW, you don't need the break if you are
returning directly from within the case.
 
In the "for what it's worth department", MS (online documentation, at
least) recommends that one's application generate an
ApplicationException. Of course you could inherit from this class and
invent your own exceptions. We do this. The benefit, if it is indeed a
benefit, is that one can intercept the application-generated exceptions
explicitly.
 
Bob Jones said:
In the "for what it's worth department", MS (online documentation, at
least) recommends that one's application generate an
ApplicationException. Of course you could inherit from this class and
invent your own exceptions. We do this. The benefit, if it is indeed a
benefit, is that one can intercept the application-generated exceptions
explicitly.

That used to be the case - but now ApplicationException is reckoned
(even by MS) to be a bad idea, as it doesn't add much other than an
extra level of hierarchy.

Note that it's always been fine to "reuse" system exceptions where they
accurately describe the situation - it's not worth reinventing the
wheel, just because it happens to be an application that generates the
exception.

See http://blogs.msdn.com/kcwalina/archive/2006/06/23/644822.aspx for a
bit more.
 

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

Back
Top