views:

97

answers:

2

I have seen the following exception case several times

    public SomeClass(IEnumerable<T> someValues)
    {
        if (null == someValues)
        {
            throw new ArgumentNullException("someValues");
        }

        int counter = 0;
        foreach (T value in someValues)
        {
            if (null == value)
            {
                string msg = counter + "th value was null";
                // What exception class to use?
                throw new ArgumentException(msg, "someValues");
            }
            counter++;
        }
    }

Is there a guideline for handling these cases? And in general is there any guidelines describing "exception style" a bit more detailed than the MSDN documentation for

+7  A: 

Throw ArgumentNullException if there was a null argument.

Throw ArgumentOutOfRange exception if there was an argument out of its range (like a negative number where only positive numbers were expected.)

Throw ArgumentException if the argument was invalid for a reason other than it was out of range or null.

Throw InvalidOperationException if the call was invalid for a reason not pertaining specifically to a value of an argument.

In this particular case I'd probably choose ArgumentException. The argument is invalid because its contents are invalid.

Of course, all of these are exceptions which indicate that the caller has a bug. It's a good habit to give the best possible error so that the author of the buggy caller can rapidly diagnose the problem. I'd therefore consider also adding a custom message to the exception saying "element of sequence blah was unexpectedly null" or some such thing.

Eric Lippert
Thanks. Is this documented somewhere? Or should I just take your word on it since you write the compiler :)
Mads Ravn
A search for InvalidArgumentException returned classes in Microsoft.SharePoint.Portal.Alerts and Microsoft.SqlServer.Management.Common. I'm not sure it's the case here.
Alfred Myers
Whoops, you're right. I was misremembering that. Thanks!
Eric Lippert
@Eric: Rereading my original comment it can be construed like I was being a smartass. This was not the intention.
Mads Ravn
+4  A: 

Yes there is, as described here, you should throw framework exceptions when possible and throwing the most derived exception that is applicable. In this case ArgumentNullException is thrown because an argument is null and ArgumentException is thrown because the contents of the enumeration are not directly a parameter of the function, so what you can say is that the argument is invalid, but it is not because it i null or is out of range.

If knowing why it is invalid becomes absolutely necessary you could derive from Argument Exception; something like ArgumentCollectionContainsNullException.

Wilhelm
Thanks for the links: http://msdn.microsoft.com/en-us/library/ms229007.aspx contained exactly what I was looking for.
Mads Ravn