views:

426

answers:

11

Should I throw NotImplementedException() on default: if I have cases for all possible enum types?

A: 

It really depends on the specific process, but yes, it's good process to respond in the default: case if something wasn't supposed to be there.

C. Ross
+2  A: 

That sounds like a reasonable option.

Personally, I would create a new type of exception (perhaps an InvalidEnumException or give it another name that will make sense to the support team) and throw that.

David Stratton
I'd personally try and reuse one of the myriad of existing exception types. http://blogs.msdn.com/jaredpar/archive/2008/10/20/custom-exceptions-when-should-you-create-them.aspx
Joe
Agreed, downvoted because I don't think this is a case for a custom exception type.
Brian Schroth
+1  A: 

I'd throw ApplicationException because if your code reaches default and you didn't expected it this means that something in your code is not behaving as you where thinking.

despart
Isn't the use of ApplicationException frowned upon?
Philip Wallace
I never heard that
despart
A: 

I'd say at least you should put a Debug.Fail() there.

You should throw an exception in case if the method in no way can proceed. But if you are like converting your enum values to string representations, then you can just return some warning string instead. The product will not crash on users due to an obvious mistake, there will be probably a workaround, and everyone will be happy.

Yacoder
+5  A: 

Maybe not NotImplementedException, but ArgumentException. It would really depend on where you're using it.

Yuriy Faktorovich
+1  A: 

It really depends on your use case. It will be helpful if you throw an exception during the early days of integration. The users of your library can immediately come to know the errors

aJ
A: 

If you threw the exception what would happen? In what context is the switch statement being executed? Should that situation ever happen? Should it ever happen at run-time in production code? Do your unit tests cover this situation? If so, perhaps an assert would be better.

A: 

You should first consider what it would mean if you got a value outside of the known cases- what does the variable being switched on represent? Then you might simply use an exception type that fits what is actually happening.

Brian Schroth
A: 

If I remember correctly default part is optional. In case of switching on enum it imposable to be in default branch if You

have cases for all possible enum types.

How can it be? I can't imagine...

So simply write switch statement without default part.

kemiisto
-1: For a start, you can set an enum to any value, even those not defined in it. Also, you want to cater for cases where more values are added to the enum in future.
Greg Beech
typically you would add the default case to cover for the day when someone adds a new enum value, but doesn't add the corresponding case to the switch statement. This will prevent the code from proceeding in a case in which it shouldn't.
Daniel
If the underlying type is an int (which is default) there are 4294967296 possible values, regardless of how many of them have names. I have never seen a switch that comes even close to handle all possible cases...
Guffa
@Greg Thanks for downvoting. =) Is it really true that "you can set an enum to any value"? Can you give me some example?@Daniel Good point, but only "to cover for the day when someone adds a new enum value"...
kemiisto
@Daniel BTW, on MSDN (http://msdn.microsoft.com/en-us/library/sbbt4032%28lightweight%29.aspx) in subsection Robust Programming there is a point about that problem. The solution: "If other developers will be using your code, you should provide guidelines about how their code should react if new elements are added to any enum types."Provide guidelines and not rise exceptions.
kemiisto
@kemiisto - http://msdn.microsoft.com/en-us/library/cc138362.aspx. "It is possible to assign any arbitrary integer value to meetingDay."
Philip Wallace
@PhilipW Thanks for link. So I was "rewarded" according to my deserts. =) I really didn't now it. And I'm shocked...
kemiisto
+10  A: 

If you're looking for a value that must, by definition, correspond to the value of an enumeration, and you've received something else, that's definitely an invalid argument.

But now you have to consider the context.

Is the method private, and only accessible by members of your class library or application? If it is, it's a coding error that shouldn't EVER occur in the first place. Assert and fail.

If, on the other hand, it's a public or protected method, and can be accessed by clients consuming your library, you should definitely throw with a meaningful message (and preferably a well-known exception type).

It's important to remember that enumerations are not range-checked in the Framework. I may specify that a method requires a parameter of type Environment.SpecialFolder; but it will accept any 32-bit integer value.

So, in short, if your method is for public consumption, yes, by all means, throw. If it's not for public consumption, Assert.

Mike Hofer
+1 well said. If the unexpected value comes from your own, Assert and fail. On the other hand, if it comes from someone else using your code then you should throw an exception and give the calling code a chance to recover.
Jerry Fernholz
Why is Assert better than throwing ? Maybe that condition is a rare case and the developer does not hit it, and it is hit only by the tester, who uses the Release build (with no Assert compiled in) and the error gets swallowed. Is it better to swallow the errors, don't crash but do a hard to debug incorrect thing, instead of crashing with a stack trace ?
csuporj
Another question is how much error checking is worth to put in code, if you don't write API's for other companies ? Short code is I think more readable than code in which each method size is doubled because of error checking. Isn't it ?
csuporj
@csuporj - In regards to your first question, if you're that worried about really obscure bugs, use Fail instead. A bug that is that obscure is going to slip through anyways. One can hope to mitigate those circumstances with thorough unit tests and up front QA tests, but *there is no such thing as modern bug free software.*
Mike Hofer
@csuporj - Regarding your second question, Error checking and the default case in a switch structure are not exactly the same thing. He's got to do something specific based on what the value of the enumeration is. If it's not one of the enumeration's *known* values, what should he do? The caller is going to expect *something.* And if the parameter type specifies an enumeration value, anything other than that is a violation of the method's contract. Failure to ensure that leads to your first question.
Mike Hofer
+3  A: 

I prefer to throw NotSupportedException.

Jakub Šturc