How to indicate that a method was unsuccessful - c#

I have several similar methods, say eg. CalculatePoint(...) and CalculateListOfPoints(...). Occasionally, they may not succeed, and need to indicate this to the caller. For CalculateListOfPoints, which returns a generic List, I could return an empty list and require the caller to check this; however Point is a value type and so I can't return null there.
Ideally I would like the methods to 'look' similar; one solution could be to define them as
public Point CalculatePoint(... out Boolean boSuccess);
public List<Point> CalculateListOfPoints(... out Boolean boSuccess);
or alternatively to return a Point? for CalculatePoint, and return null to indicate failure. That would mean having to cast back to the non-nullable type though, which seems excessive.
Another route would be to return the Boolean boSuccess, have the result (Point or List) as an 'out' parameter, and call them TryToCalculatePoint or something...
What is best practice?
Edit: I do not want to use Exceptions for flow control! Failure is sometimes expected.

Personally, I think I'd use the same idea as TryParse() : using an out parameter to output the real value, and returning a boolean indicating whether the call was successful or not
public bool CalculatePoint(... out Point result);
I am not a fan of using exception for "normal" behaviors (if you expect the function not to work for some entries).

Why would they fail? If it's because of something the caller has done (i.e. the arguments provided) then throwing ArgumentException is entirely appropriate. A Try[...] method which avoids the exception is fine.
I think it's a good idea to provide the version which throws an exception though, so that callers who expect that they will always provide good data will receive a suitably strong message (i.e. an exception) if they're ever wrong.

Another alternative is to throw an exception. However, you generally only want to throw exceptions in "exceptional cases".
If the failure cases are common (and not exceptional), then you've already listed out your two options. EDIT: There may be a convention in your project as how to handle such non-exceptional cases (whether one should return success or the object). If there is no existing convention, then I agree with lucasbfr and suggest you return success (which agrees with how TryParse(...) is designed).

If the failure is for a specific reason then I think its ok to return null, or bool and have an out parameter. If however you return null regardless of the failure then I don't recommend it. Exceptions provide a rich set of information including the reason WHY something failed, if all you get back is a null then how do you know if its because the data is wrong, you've ran out of memory or some other weird behavior.
Even in .net the TryParse has a Parse brother so that you can get the exception if you want to.
If I provided a TrySomething method I would also provide a Something method that threw an exception in the event of failure. Then it's up to the caller.

The model I've used is the same one MS uses with the TryParse methods of various classes.
Your original code:
public Point CalculatePoint(... out Boolean boSuccess);
public List CalculateListOfPoints(... out Boolean boSuccess);
Would turn into
public bool CalculatePoint(... out (or ref) Point CalculatedValue);
public bool CalculateListOfPoints(... out (or ref) List CalculatedValues);
Basically you make the success/failure the return value.

To summarise there are a couple of approaches you can take:
When the return type is a value-type, like Point, use the Nullable feature of C# and return a Point? (aka Nullable), that way you can still return null on a failure
Throw an exception when there's a failure. The whole argument/discussion regarding what is and isn't "exceptional" is a moot point, it's your API, you decide what's exceptional behaviour.
Adopt a model similar to that implemented by Microsoft in the base types like Int32, provide a CalculatePoint and TryCalculatePoint (int32.Parse and int32.TryParse) and have one throw and one return a bool.
Return a generic struct from your methods that has two properties, bool Success and GenericType Value.
Dependent on the scenario I tend to use a combination of returning null or throwing an exception as they seem "cleanest" to me and fit best with the existing codebase at the company I work for. So my personal best practice would be approaches 1 and 2.

It mostly depends on the behavior of your methods and their usage.
If failure is common and non-critical, then have your methods return a boolean indicating their success and use an out parameter to convey the result. Looking up a key in a hash, attempting to read data on a non-blocking socket when no data is available, all these examples fall in that category.
If failure is unexpected, return directly the result and convey errors with exceptions. Opening a file read-only, connecting to a TCP server, are good candidates.
And sometimes both ways make sense...

Return Point.Empty. It's a .NET design patter to return a special field when you want to check if structure creation was successful. Avoid out parameters when you can.
public static readonly Point Empty

A pattern that I'm experimenting with is returning a Maybe. It has the semantics of the TryParse pattern, but a similar signature to the null-return-on-error pattern.
I'm not yet convinced one way or the other, but I offer it for your collective consideration. It does have the benefit of not requiring a variable to defined before the method call to hold the out parameter at the call site of the method. It could also be extended with an Errors or Messages collection to indicate the reason for the failure.
The Maybe class looks something like this:
/// <summary>
/// Represents the return value from an operation that might fail
/// </summary>
/// <typeparam name="T"></typeparam>
public struct Maybe<T>
{
T _value;
bool _hasValue;
public Maybe(T value)
{
_value = value;
_hasValue = true;
}
public Maybe()
{
_hasValue = false;
_value = default(T);
}
public bool Success
{
get { return _hasValue; }
}
public T Value
{
get
{ // could throw an exception if _hasValue is false
return _value;
}
}
}

I would say best practice is a return value means success, and an exception means failure.
I see no reason in the examples you provided that you shouldn't be using exceptions in the event of a failure.

Using an exception is a bad idea in some cases (especially when writing a server). You would need two flavors of the method. Also look at the dictionary class for an indication of what you should do.
// NB: A bool is the return value.
// This makes it possible to put this beast in if statements.
public bool TryCalculatePoint(... out Point result) { }
public Point CalculatePoint(...)
{
Point result;
if(!TryCalculatePoint(... out result))
throw new BogusPointException();
return result;
}
Best of both worlds!

The bool TrySomething() is at least a practice, which works ok for .net's parse methods, but I don't think I like it in general.
Throwing an exception is often a good thing, though it should not be used for situations you would expect to happen in many normal situations, and it has an associated performance cost.
Returning null when possible is in most cases ok, when you don't want an exception.
However - your approach is a bit procedural - what about creating something like a PointCalculator class - taking the required data as parameters in the constructor? Then you call CalculatePoint on it, and access the result through properties (separate properties for Point and for Success).

You don't want to be throwing exceptions when there is something expected happening, as #Kevin stated exceptions are for exceptional cases.
You should return something that is expected for the 'failure', generally null is my choice of bad return.
The documentation for your method should inform the users of what to expect when the data does not compute.

We once wrote an entire Framework where all the public methods either returned true (executed successfully) or false (an error occurred). If we needed to return a value we used output parameters. Contrary to popular belief, this way of programming actually simplified a lot of our code.

Well with Point, you can send back Point.Empty as a return value in case of failure. Now all this really does is return a point with 0 for the X and Y value, so if that can be a valid return value, I'd stay away from that, but if your method will never return a (0,0) point, then you can use that.

Sorry, I just remembered the Nullable type, you should look at that. I am not too sure what the overhead is though.

Related

Method naming depending on returntype

Trying to avoid Tell-don't-ask, I want to combine a bool property that I was asking before calling a method, into a new method returning bool.
I try to follow the pattern, that if a method can't perform the action implied by it's name, it will throw an exception. For example if SendMail can't send the mail, it will throw an exception.
I want this particular method to return a bool to indicate the success. And am considering if I should change the name to something like TrySendMail, perhaps looking at the method signature with the bool return type should be enough?
Naming the method TrySendMail seems like a not too bad approach. However, being consistent with your overall naming sceme is the most important thing.
The whole TryWhatever naming pattern seems to be a fairly recent thing coming from Microsoft, but the behavior (try to do something, throw if it fails, return a meaningful strongly-typed value if it doesn't) has been around for a long time.
In theory, TryWhatever should be used if the method takes a ref parameter that receives the result, and returns a bool. If the method fails, it returns false. If it succeeds, the result is stored in the ref parameter (always the last parameter), and returns true.
You can use the DateTime.TryParse method as an example. If the method doesn't match that pattern, it's not a candidate for this naming convention.
For me, when using this convention, consistency is key. Don't surprise developers. Some of us are very scary people!
The TrySomething pattern is, as you know, used in several .NET BCL methods (various TryParse methods), and people are accustomed to it, so it shouldn't surprise anyone.
If your method's signature is simply bool TrySendMail(Mail mail), then it should be pretty obvious what's going on. And I would prefer to see that signature over something like:
bool WasMailSentSuccessfully(Mail mail);
because it is not so clear from the latter method that the method is actually sending the mail. So you are making the right naming choice if you go with the Try prefix, as far as I am concerned.
On the other hand, when I see the Try prefix, I usually expect to see the out keyword inside the argument list, which would follow these conventions:
bool TrySendMail(Mail mail, out string error);
And be used as:
string error = null;
if (!TrySendMail(mail, out error))
Console.WriteLine(error);
This convention, although pretty common, is actually rather ugly from an OOP point of view. It is basically a method which returns two values, and instead of passing one of the arguments by reference, a proper OOP way would be to wrap all of the return values in a new class.
So I would prefer something like:
SendResult SendMail(Mail mail);
and then you could use it like this:
SendResult sendResult = SendMail(mail);
if (!sendResult.Success)
Console.WriteLine(sendResult.Value);
where SendResult could be something like:
public class SendResult : ActionResult<string>
{ ... }
public class ActionResult<T>
{
public bool Success { get; private set; }
public T Value { get; private set; }
public ActionResult<T>(bool success, T value)
{
Success = success;
Value = value;
}
}
The benefit is that later adding a bunch of additional return values does not change your method's signature.
I remember reading a piece in Code Complete 2 (although I can't remember where abouts exactly) about naming conventions, aside from trying to keep them generic so they can be used for multiple applications they should all have some consistency. In this case calling it "SendMail" keeps it straight to the point and allows you to easily reuse it without the user having to worry about the implementation details, it's obvious what it does.
Setting the return type as a boolean should be a sure sign that the method works on a Success/Fail operation, making the "Try" part redundant.
private bool SendMail()
{
try
{
//Send mail
return true;
}
catch()
{
//Handle exception
}
return false;
}
If you were to add the XML header for the method you can even add an explanation as to what the method does when you try to call it through IntelliSense.
Be careful with the exceptions. For instance, if the address passed into the SendMail is badly formed, I don't think it appropriate to throw an exception. Exceptions are for exceptional behaviour, and to my mind not sending a mail because the address is badly formed is expected behaviour, not exceptional. I would definitely return a false (and maybe a string reason) if the mail isn't sent rather than throwing an exception. Throwing exceptions is not just slow, but means that the stack gets unwound so has to worry about leaving everything in a good state.

Is it necessarily bad style to ignore the return value of a method

Let's say I have a C# method public void CheckXYZ(int xyz) {
// do some operation with side effects
}
Elsewhere in the same class is another method public int GetCheckedXYZ(int xyz) {
int abc;
// functionally equivalent operation to CheckXYZ,
// with additional side effect of assigning a value to abc
return abc; // this value is calculated during the check above
}
Is it necessarily bad style to refactor this by removing the CheckXYZ method, and replacing all existing CheckXYZ() calls with GetCheckedXYZ(), ignoring the return value? The returned type isn't IDisposable in this case. Does it come down to discretion?
EDIT: After all the responses, I've expanded the example a little. (Yes, I realise it's now got out in it, it's especially for #Steven)
public void EnsureXYZ(int xyz) {
if (!cache.ContainsKey(xyz))
cache.Add(xyz, random.Next());
}
public int AlwaysGetXYZ(int xyz) {
int abc;
if (!cache.TryGetValue(xyz, out abc))
{
abc = random.Next();
cache.Add(xyz, abc);
}
return abc;
}
It entirely depends upon what that return value is telling you and if that is important to know or not. If the data returned by the method is not relevant to the code that is calling it then ignoring it is entirely valid. But if it indicates some failure/counter/influential value then ignore it at your peril.
Usually it's bad style, yes. It's allowed and ok where methods return an instance of the class for chaining (foo.bar().baz().xyz().asdf() => asdf returns the instance foo but you don't need it anymore)
In your case the point of bad style wouldn't be the ignored return value but the methods with side effects. A CheckXyz() function should always return a boolean and have no further side effects.
In general, side effects are bad and if you call a method and can ignore the returned value it means that the method/object/library/program might be poorly designed.
A common C convention is to write this:
(void)GetCheckedXYZ();
The cast to void has no effect, but by convention it shows that the developer knows that the return value is being ignored, i.e. it shows it's deliberate.
C# won't let you do that, but I've seen this instead (Also in Java):
/*(void)*/GetCheckedXYZ();
Which some may feel lacks aesthetics, but it does convey the intent of the developer without resorting to alternative versions of methods, which to my eye seems worse.
A lot of these answers have good points. I'd just add that if you choose to ignore a return value, then comment it along the lines of "don't care about the return value because...", so that the next person who comes into the code will see that you have not missed it by accident and that you have thought things through
EDIT: better still, put your comment inside an empty block
if (!something()) {
// Not worried if this fails because blah
}
IMHO it's generally best to have one (and only one) way of doing things to avoid duplicating your codebase. Generally though, if you sometimes use and sometimes don't use the return value, it's probably a sign that your code could be broken down in a better way. In your example, it would probably be fine if both of those functions called a third (common) function to avoid duplicating the core functionality.
Error codes should always be checked for and handled but if the function's just returning information then what you do with that information is up to you.
[Edit] ...and as dbemerlin points out, side effects should be avoided wherever possible.
you could work with out parameters as well.

When to check for nulls

This is kinda an open ended question but I'm trying to sharpen my skills with good practices in exception handling specifically when to check for nulls in general.
I know mostly when to check for nulls but I have to say half the time I don't and that's bothering to me. I know ints cannot be set to null unless you use a nullable int. I know strings can be set to null OR empty hence you can check for IsNullOrEmpty.
Obviously in constructors you want to add your explicit checks there also. That's a given. And that I think you should check for null anytime you're passing in an array, generic object, or other objects into a method that can be set to null basically right?
But there is more here to exception handling. For instance I don't know when to always check and throw a null ref exception explicitely in code. If I've got incoming params, usually it's pretty straight forward but there are always cases where I ask myself, is an explicit null throw needed?
I don't really have specific examples but wondering if there's a good reference out there that really talks about exception handling in reference to when to throw them (inside methods, classes, you name it).
You shouldn't throw NullReferenceException. If it is an argument that is null throw ArgumentNullException instead.
I prefer to check for null for all reference types parameters of public/protected methods. For private methods, you may omit the check if you're sure all calls will always have valid data.
Unless you're using Code Contracts, I'd say it's good practice to check arguments for any public/protected member - as well as explicitly documenting whether they can or can't be null. For private/internal methods it becomes a matter of verifying your own code rather than someone else's... it's a judgement call at that point.
I sometimes use a helper extension method for this, so I can write:
public void Foo(string x, string y, string z)
{
x.ThrowIfNull("x");
y.ThrowIfNull("y");
// Don't check z - it's allowed to be null
// Method body here
}
ThrowIfNull will throw an ArgumentNullException with the appropriate name.
By checking explicitly before you make any other calls, you know that if an exception is thrown, nothing else will have happened so you won't have corrupted state.
I admit I'll omit such checks where I know for certain that the first call will do the same checks - e.g. if it's one overload piggybacking onto another.
With Code Contracts, I'd write:
public void Foo(string x, string y, string z)
{
Contract.Requires(x != null);
Contract.Requires(y != null);
// Rest of method here
}
This will throw a ContractException instead of ArgumentNullException, but all the information is still present and no-one should be catching ArgumentNullException explicitly anyway (other than possibly to cope with third party badness).
Of course the decision of whether you should allow null values is an entirely different matter. That depends entirely on the situation. Preventing nulls from ever entering your world does make some things easier, but at the same time nulls can be useful in their own right.
My rules of thumb for when to check for nulls are:
Always check the arguments passed to a public/protected method of any class.
Always check the arguments to constructors and initialize methods.
Always check the arguments in an indexer or property setter.
Always check the arguments to methods that are interface implementations.
With multiple overloads, try to put all argument preconditions in a single method that other overloads delegate to.
Early notification of null arguments (closer to the point of error) are much better than random NullReferenceExceptions that occur far from the point of the error.
You can use utility methods to clean up the typical if( arg == null ) throw new ArgumentNullException(...); constructs. You may also want to look into code contracts in C# 4.0 as a way to improve your code. Code contracts perform both static and runtime checks which can help identify problems even at compile time.
In general, writing preconditions for methods is a time consuming (and therefore often omitted) practice. However, the benefit to this type of defensive coding is in the hours of potentially saved time debugging red herrings that occur because you didn't validate your inputs.
As a side note, ReSharper is a good tool for identifying potential access to arguments or local members that may be null at runtime.
The earlier the better. The sooner you catch the (invalid) null, the less likely you'll be throwing out in the middle of some critical process. One other thing to consider is using your properties (setters) to centralize your validation. Often I reference my properties in the constructor, so I get good reuse on that validation.
class A
{
private string _Name
public string Name
{
get { return _Name; }
set
{
if (value == null)
throw new ArgumentNullException("Name");
_Name = value;
}
}
public A(string name)
{
//Note the use of property with built in validation
Name = name;
}
}
Depends on your type of method/api/library/framework. I think its ok for private methods that they dont check for null values unless they are kind of assertion methods.
If you programm defensive and litter your code with "not null"-tests or "if"-statements your code will be unreadable.
Define the areas where a client can mess up your code by submitting wrong/empty/null arguments. If you know where, you can draw the line where to do your null checks. Do it at your api entry points just like the security works in real life.
Imagine you would be bothered every minute to show your ticket in a cinema every movie would suck.
I prefer using static template methods for checking input constraints. the general format for this would be something like:
static class Check {
public static T NotNull(T arg) {
if( arg == null ) throw new ArgumentNullException();
}
}
The benefit to using this is that your method or constructor can now wrap the first use of the argument with Check.NotNull() as exampled here:
this.instanceMember = Check.NotNull(myArgument);
When I get to .Net 4, I'll likely convert to code contracts, but until then this works. BTW, You can find a more complete definition of the Check class I use at the following url:
http://csharptest.net/browse/src/Shared/Check.cs

When should I use out parameters?

I don't understand when an output parameter should be used, I personally wrap the result in a new type if I need to return more than one type, I find that a lot easier to work with than out.
I have seen method like this,
public void Do(int arg1, int arg2, out int result)
are there any cases where that actually makes sense?
how about TryParse, why not return a ParseResult type? or in the newer framework return a null-able type?
Out is good when you have a TryNNN function and it's clear that the out-parameter will always be set even if the function does not succeed. This allows you rely on the fact that the local variable you declare will be set rather than having to place checks later in your code against null. (A comment below indicates that the parameter could be set to null, so you may want to verify the documentation for the function you're calling to be sure if this is the case or not.) It makes the code a little clearer and easier to read. Another case is when you need to return some data and a status on the condition of the method like:
public bool DoSomething(int arg1, out string result);
In this case the return can indicate if the function succeeded and the result is stored in the out parameter. Admittedly, this example is contrived because you can design a way where the function simply returns a string, but you get the idea.
A disadvantage is that you have to declare a local variable to use them:
string result;
if (DoSomething(5, out result))
UpdateWithResult(result);
Instead of:
UpdateWithResult(DoSomething(5));
However, that may not even be a disadvantage, it depends on the design you're going for. In the case of DateTime, both means (Parse and TryParse) are provided.
I think out is useful for situations where you need to return both a boolean and a value, like TryParse, but it would be nice if the compiler would allow something like this:
bool isValid = int.TryParse("100", out int result = 0);
Well as with most things it depends.
Let us look at the options
you could return whatever you want as the return value of the function
if you want to return multiple values or the function already has a return value, you can either use out params or create a new composite type that exposes all these values as properties
In the case of TryParse, using an out param is efficient - you dont have to create a new type which would be 16B of overhead (on 32b machines) or incur the perf cost of having them garbage collected post the call. TryParse could be called from within a loop for instance - so out params rule here.
For functions that would not be called within a loop (i.e. performance is not a major concern), returning a single composite object might be 'cleaner' (subjective to the beholder). Now with anonymous types and Dynamic typing , it might become even easier.
Note:
out params have some rules that need to be followed i.e. the compiler will ensure that the function does initialize the value before it exits. So TryParse has to set the out param to some value even if parse operation failed
The TryXXX pattern is a good example of when to use out params - Int32.TryParse was introduced coz people complained of the perf hit of catching exceptions to know if parse failed. Also the most likely thing you'd do in case parse succeeded, is to obtain the parsed value - using an out param means you do not have to make another method call to Parse
Years late with an answer, I know.
out (and ref as well) is also really useful if you do not wish your method do instantiate a new object to return. This is very relevant in high-performance systems where you want to achieve sub microsecond performance for your method. instantiating is relatively expensive seen from a memory access perspective.
Definitely, out parameters are intended to be used when you have a method that needs to return more than one value, in the example you posted:
public void Do(int arg1, int arg2, out int result)
It doesn't makes much sense to use an out parameter, since you are only returning one value, and that method could be used better if you remove the out parameter and put a int return value:
public int Do(int arg1, int arg2)
There are some good things about out parameters:
Output parameters are initially considered unassigned.
Every out parameter must be definitely assigned before the method returns, your code will not compile if you miss an assignment.
In conclusion, I basically try use out params in my private API to avoid creating separate types to wrap multiple return values, and on my public API, I only use them on methods that match with the TryParse pattern.
Yes, it does make sense. Take this for example.
String strNum = "-1";
Int32 outNum;
if (Int32.TryParse(strNum, out outNum)) {
// success
}
else {
// fail
}
What could you return if the operation failed in a normal function with a return value? You most certainly could not return -1 to represent a fail, because then there would be no differentiation between the fail-return value and the actual value that was being parsed to begin with. This is why we return a Boolean value to see if it succeeded, and if it did then we have our "return" value safely assigned already.
Creating a type just for returning values sounds little painful to me :-)
First i will have to create a type for returning the value then in the calling method i have assign the value from the returned type to the actual variable that needs it.
Out parameters are simipler to use.
It does annoy me that I can't pass in null to the out parameter for the TryParse functions.
Still, I prefer it in some cases to returning a new type with two pieces of data. Especially when they're unrelated for the most part or one piece is only needed for a single operation a moment after. When I do need to save the resulting value of a TryParse function I really like having an out parameter rather than some random ResultAndValue class that I have to deal with.
If you always create a type, then you can end up with a lot of clutter in your application.
As said here, one typical use case is a TrySomething Method where you want to return a bool as an indicator for success and then the actual value. I also find that a little bit cleaner in an if-statement - all three options roughly have the same LOC anyway.
int myoutvalue;
if(int.TryParse("213",out myoutvalue){
DoSomethingWith(myoutvalue);
}
vs.
ParseResult<int> myoutvalue = int.TryParse("213");
if ( myoutvalue.Success ) {
DoSomethingWith(myoutvalue.Value);
}
vs.
int? myoutvalue = int.TryParse("213");
if(myoutvalue.HasValue){
DoSomethingWith(myoutvalue.Value);
}
As for the "Why not return a Nullable Type": TryParse exists since Framework 1.x, whereas Nullable Types came with 2.0 (As they require Generics). So why unneccessarily break compatibility or start introducing inconsistencies between TryParse on some types? You can always write your own extension Method to duplicate functionality already existing (See Eric Lipperts Post on an unrelated subject that includes some reasoning behind doing/not doing stuff)
Another use case is if you have to return multiple unrelated values, even though if you do that that should trigger an alarm that your method is possibly doing too much. On the other hand, if your Method is something like an expensive database or web service call and you want to cache the result, it may make sense to do that. Sure, you could create a type, but again, that means one more type in your application.
I use out parameters sometimes for readability, when reading the method name is more important than whatever the output of the method is—particularly for methods that execute commands in addition to returning results.
StatusInfo a, b, c;
Initialize(out a);
Validate(a, out b);
Process(b, out c);
vs.
StatusInfo a = Initialize();
StatusInfo b = Validate(a);
StatusInfo c = Process(b);
At least for me, I put a lot of emphasis on the first few characters of each line when I'm scanning. I can easily tell what's going on in the first example after acknowledging that some "StatusInfo" variables are declared. In the second example, the first thing I see is that a bunch of StatusInfo is retrieved. I have to scan a second time to see what kind of effects the methods may have.

What is the preferred method for handling unexpected enum values?

Suppose we have a method that accepts a value of an enumeration. After this method checks that the value is valid, it switches over the possible values. So the question is, what is the preferred method of handling unexpected values after the value range has been validated?
For example:
enum Mood { Happy, Sad }
public void PrintMood(Mood mood)
{
if (!Enum.IsDefined(typeof(Mood), mood))
{
throw new ArgumentOutOfRangeException("mood");
}
switch (mood)
{
case Happy: Console.WriteLine("I am happy"); break;
case Sad: Console.WriteLine("I am sad"); break;
default: // what should we do here?
}
What is the preferred method of handling the default case?
Leave a comment like // can never happen
Debug.Fail() (or Debug.Assert(false))
throw new NotImplementedException() (or any other exception)
Some other way I haven't thought of
I guess most of the above answers are valid, but I'm not sure any are correct.
The correct answer is, you very rarely switch in an OO language, it indicates you are doing your OO wrong. In this case, it's a perfect indication that your Enum class has problems.
You should just be calling Console.WriteLine(mood.moodMessage()), and defining moodMessage for each of the states.
If a new state is added--All Your Code Should Adapt Automatically, nothing should fail, throw an exception or need changes.
Edit: response to comment.
In your example, to be "Good OO" the functionality of the file mode would be controlled by the FileMode object. It could contain a delegate object with "open, read, write..." operations that are different for each FileMode, so File.open("name", FileMode.Create) could be implemented as (sorry about the lack of familiarity with the API):
open(String name, FileMode mode) {
// May throw an exception if, for instance, mode is Open and file doesn't exist
// May also create the file depending on Mode
FileHandle fh = mode.getHandle(name);
... code to actually open fh here...
// Let Truncate and append do their special handling
mode.setPosition(fh);
}
This is much neater than trying to do it with switches... (by the way, the methods would be both package-private and possibly delegated to "Mode" classes)
When OO is done well, every single method looks like a few lines of really understandable, simple code--TOO simple. You always get the feeling that there is some big messy "Cheese Nucleus" holding together all the little nacho objects, but you can't ever find it--it's nachos all the way down...
I prefer to throw new NotImplementedException("Unhandled Mood: " + mood). The point is that the enumeration may change in the future, and this method may not be updated accordingly. Throwing an exception seems to be the safest method.
I don't like the Debug.Fail() method, because the method may be part of a library, and the new values might not be tested in debug mode. Other applications using that library can face weird runtime behaviour in that case, while in the case of throwing an exception the error will be known immediately.
Note: NotImplementedException exists in commons.lang.
In Java, the standard way is to throw an AssertionError, for two reasons:
This ensures that even if asserts are disabled, an error is thrown.
You're asserting that there are no other enum values, so AssertionError documents your assumptions better than NotImplementedException (which Java doesn't have anyway).
My opinion is that since it is a programmer error you should either assert on it or throw a RuntimException (Java, or whatever the equivalent is for other languages). I have my own UnhandledEnumException that extends from RuntimeException that I use for this.
The correct program response would be to die in a manner that will allow the developer to easily spot the problem. mmyers and JaredPar both gave good ways to do that.
Why die? That seems so extreme!
The reason being that if you're not handling an enum value properly and just fall through, you're putting your program into an unexpected state. Once you're in an unexpected state, who knows what's going on. This can lead to bad data, errors that are harder to track down, or even security vulnerabilities.
Also, if the program dies, there's a much greater chance that you're going to catch it in QA and thus it doesn't even go out the door.
For pretty much every switch statement in my code base, I have the following default case
switch( value ) {
...
default:
Contract.InvalidEnumValue(value);
}
The method will throw an exception detailing the value of the enum at the point an error was detected.
public static void InvalidEnumValue<T>(T value) where T: struct
{
ThrowIfFalse(typeof(T).IsEnum, "Expected an enum type");
Violation("Invalid Enum value of Type {0} : {1}", new object[] { typeof(T).Name, value });
}
For C#, something worth knowing is that Enum.IsDefined() is dangerous. You can't rely on it like you are. Getting something not of the expected values is a good case for throwing an exception and dying loudly.
In Java, it's different because enums are classes not integers so you really can't get unexpected values (unless the enum is updated and your switch statement isn't), which is one big reason why I much prefer Java enums. You also have to cater for null values. But getting a non-null case you don't recognize is a good case for throwing an exception too.
You could have a trace for the default calling out the value of the passed enum. Throwing exceptions is OK but in a large application there will be several places where your code does not care about other values of the enum.
So, unless you are sure that the code intends to handle all possible values of the enum, you'll have to go back later and remove the exception.
This is one of those questions that proves why test driven development is so important.
In this case I'd go for a NotSupportedException because literally the value was unhandled and therefore not supported. A NotImplementedException gives more the idea of: "This is not finished yet" ;)
The calling code should be able to handle a situation like this and unit tests can be created to easily test these kind of situations.
Call it an opinion or a preference, but the idea behind the enum is that it represents the full list of possible values. If an "unexpected value" is being passed around in code, then the enum (or purpose behind the enum) is not up to date. My personal preference is that every enum carry a default assignment of Undefined. Given that the enum is a defined list, it should never be out-of-date with your consuming code.
As far as what to do if your function is getting either an unexpected value or Undefined in my case, a generic answer doesn't seem possible. For me, it depends on the context of the reason for evaluating the enum value: is it a situation where code execution should halt, or can a default value be used?
It is the responsibility of the calling function to provide valid input and implicitely anything not in the enum is invalid (Pragmatic programmer seems to imply this). That said, this implies that any time you change your enum, you must change ALL code that accepts it as input (and SOME code that yields it as output). But that is probably true anyways. If you have an enum that changes often, you probably should be using something other than an enum, considering that enums are normally compile-time entities.
I usually try to define undefined value (0):
enum Mood { Undefined = 0, Happy, Sad }
That way I can always say:
switch (mood)
{
case Happy: Console.WriteLine("I am happy"); break;
case Sad: Console.WriteLine("I am sad"); break;
case Undefined: // handle undefined case
default: // at this point it is obvious that there is an unknown problem
// -> throw -> die :-)
}
This is at least how I usually do this.

Categories