The SLAR on ArgumentNullException


To continue sharing some of the color found in the .NET Framework Standard Library Annotated Reference Vol 1, here is some information from the ArgumentNullException class.


   public class ArgumentNullException : ArgumentException


   {


          // Constructors


          public ArgumentNullException ();


          public ArgumentNullException (string paramName);


          public ArgumentNullException (string paramName, string message);


   MS CF  protected ArgumentNullException (SerializationInfo info, StreamingContext context);


   }


 


 


BA This class goes down in the API design hall of shame. ArgumentNullException does not follow the exception constructor pattern given in the Design Guidelines Specification, which says the constructor overloads should include at least:


       public XxxException ();


       public XxxException (string message);


       public XxxException (string message, Exception inner);


The rationale for violating this guideline was that the parameter name would be much more commonly specified than the message text. However, because nearly every other exception in the system does follow the pattern, the usual result is that the force


of habit wins out. Developers commonly make this mistake:


throw new ArgumentNullException (“must pass an employee name”);


Rather than:


throw new ArgumentNullException (“Name”, “must pass an employee name”);


This mistake means that we end up with an error message such as this one:


Unhandled Exception: System.ArgumentNullException: Value cannot be null.


Parameter name: “must pass employee name”


Lesson learned: Just follow the pattern.


 


JR In addition to Brad’s comments, a properly designed exception class should


also allow for serializability. Specifically, this means that the class should have the


System.SerializableAttribute applied to it and the class should implement


the ISerializable interface with its GetObjectData method and special constructor.


These two methods should serialize/deserialize any fields in the class and be sure to


call the base class methods so that any fields in the base class are also serialized/


deserialized. If the exception class is sealed, the constructor can be marked private;


otherwise, mark the constructor as protected. Since GetObjectData is an interface


method, mark it as public.


 —- 


Amazon Rank: 30,643 up from 1,026 right after my last post… Maybe this post have the same effect 😉

Comments (8)

  1. IM says:

    Because nearly every… BECAUSE NEARLY EVERY WHAT!?!

    :’¬(

  2. Giampiero says:

    Damn you Brad!

  3. Brad Abrams says:

    Ahh, thanks IM, I fixed the post… turns out I left out a lot of it!

  4. Keith Patrick says:

    It’s too bad reflection takes such a performance hit, because all things equal, I’d go so far as to implement it like so:

    ArgumentNullException(ParameterInfo parameter, String message, Exception innerException)

    I strongly dislike using strings to represent various objects, even if it is convenient, because it requires parsing to add any kind of context to the thing. FWIW: I *do* actually have exceptions like these, but because of the reflection-based speed hit, I don’t count on exceptions as often as some to catch unexpected scenarious, instead depending on conditionals more where speed is an issue. I generally only throw exceptions of this nature during configuration inits, when these values are initially set, which I don’t consider performance-critical enough to trade the reflection-based contextual object(s) that it buys me for speed and convenience of generating "quick n dirty" exceptions.

  5. John Lewicki says:

    While I agree that it is somewhat vexing that ArgumentNullException doesnt follow the pattern, I actually like the convenience of the single string constructor. I cant remember the last time I felt the need to include an error message when throwing ArgumentNullException; the paramerter name is almost always sufficient.

    After all, if you get an exception that tells you the foo parameter was null, do you really need an error message saying something like ‘must pass a foo value’?.

    Call me crazy.

  6. James Bellinger says:

    Frankly I wished ArgumentException accepted the parameter name first also…

  7. I throw exceptions all the time from my properties – well, rather I do validation checks, and throw custom exceptions when validation fails. ArgumentNullException is a favorite, so’s StringTooLongException, IntegerOutOfRangeException, and others.

    My thoughts expounded here: http://udidahan.weblogs.us/archives/018833.html – Exceptionally speaking, that is.