tags:

views:

193

answers:

4

When I'm writing a function in a utility module to be used again, I tend to leave lots of comments at the top of functions and some simple input checks to throw up a message in the debugger if a function is used inappropriately, w/o simply using a throw command.

What's the best methodology of handling such situations? What functionality is easiest to use for this in C#?

In my CS classes a decade ago, we would simply use an assert(...) command in C++ and let the program bomb out if something was used incorrectly.

Now that I'm using C# I've used two methods, throwing up a MessageBox.Show("...") to clarify why a function is returning prematurely or a Console.WriteLine("...") to have it explained only in the debug console.

I'm currently leaning toward writing a custom ErrorMessage fuction that would check the build type and possibly a #define master toggle before displaying anything and probably saving to a .log file if I'm in a beta environment.

What's the best method to use in such utility modules?

+4  A: 

Throw an exception. It's the clearest way of indicating that something's wrong, and it's much harder to ignore than a console message or even a message box.

In particular, it means that that code path won't keep going, assuming that everything's fine. Even if the user (whether in beta or not) notices the message box, they're not going to be happy to find out that as soon as they click on "OK" the application goes ahead and wipes their data out just because the utility method wasn't used properly.

Jon Skeet
If you have the time, would you explain the syntax to give a clear error message in C# when throwing an exception?
Fred
Who do you want the error message to go to? If it's to the user, that's up to the calling code - usually I'd let the exception bubble up the stack, probably to near the top, and then display some suitable error message explaining that their operation couldn't be completed.
Jon Skeet
The general question of working out what to tell users is a hugely tricky one though, certainly. If it's a validation error (i.e. user has messed up) that's easy - but if it's due to a bug or external conditions it's a lot harder to get right. I think that's a whole different question.
Jon Skeet
(And I think it's a question I'd let someone else answer :)
Jon Skeet
I'm more looking at if the function was called with a valid string but in a format that I am not handling. I want it to silently be aborted at times if the coder expects the problem but is handling it but in the case that the coder didn't use it properly I want him to get a clear text explanation.
Fred
@Fred: If the coder was expecting the problem, he should be catching the exception. Throw a FormatException - and also provide a TryXXX method so that you can avoid using exceptions for this sort of flow control.
Jon Skeet
+5  A: 

If the method is being called with invalid arguments then it should throw an ArgumentException, or an exception derived from it. If the method is being called that cannot be called currently due to the state of the object then it should throw an InvalidOperationException.

Other people calling your library will not thank you for doing things in a non-standard or a non-obvious manner. Such as showing message boxes. Especially if they are calling your library from a web site or a windows service that can't display UI. And outputting to the debug window is far too likely to get missed.

pipTheGeek
+1  A: 

I agree with Jon's answer, but you also have Debug.Assert as part of your toolkit. Sometimes this can serve you better if you want to warn developers of something, but want it to slide through in production code.

Michael Meadows
+1  A: 

I like pipTheGeek's answer, but I thought I'd throw in a plug for an MSR technology that may be in the pipeline for C# 4.0: Code Contracts

The obvious answer is to use the standard exceptions that come packaged in the .Net base-class libraries(ArgumentNullException, InvalidOperationException, NotImplementedException etc), or invent your own specific exception if you feel that a consumer of your class might need to know a bit more detail about why they're receiving an exception.

If your code is going to be used later, be sure to list the possible exceptions in the Xml comments section.

Stack information is filled in on your behalf by the CLR, so all you need to do is throw that bad-boy and let the consumer deal with the consequences.

Since you asked about the syntax:

    /// <summary>
    /// Summary: 
    ///     Does stuff.
    /// Exceptions:
    ///     ArgumentNullException:
    ///        args must be non-null
    /// </summary>
    /// <param name="args"></param>
    public static void DoStuff(string[] args)
    {
        if(args == null)
        throw new ArgumentNullException("args", "'args' parameter cannot be null.");

        ...
    }
TheMissingLINQ
Your link seems to be broken atm.
Fred
But the info especially the code block was very helpful. I've been using summary blocks a lot I especially like it giving me a spot to explain the arguments especially if I'm using overloading.
Fred
There's an exception recommendation for XML code comments: http://msdn.microsoft.com/en-us/library/w1htk11d.aspx#
Michael Meadows