LP on .NET

December 7, 2009

Checking for Null Arguments

Filed under: .NET,C#,Software Development — Larry Parker @ 10:26 pm

Checking for null arguments in a method is not a very glamorous programming task, but it can be worth the time investment.  Instead of your code reacting to a null argument at some unexpected place (and throwing a NullReferenceException), you can be more proactive and check for null arguments at the beginning of the method and throw an ArgumentNullException yourself.

For example, say we have a method called PostIt that takes two arguments – a URI of a web page, and an XML document to post to it.  In this case, neither of these arguments should be null, so we can check for valid arguments like this:

public void PostIt(Uri uri, XmlDocument document)
{
    if (uri == null)
        throw new ArgumentNullException("uri");

    if (document == null)
        throw new ArgumentNullException("document");

    // Arguments are good -- continue...
}

There’s nothing wrong with this approach, but writing code like this everywhere can become a bit tedious.  Furthermore, the above code is not immune to refactoring.  Renaming the method’s arguments will not change the literal passed into the exception’s constructor.

To make things a bit easier and more immune to refactoring, I created a static helper method that takes one or more lambda expressions, checks each for null, and throws an ArgumentNullException if it encounters one.

This is what the PostIt method looks like using the helper method:

public void PostIt(Uri uri, XmlDocument document)
{
    Helper.CheckArgumentNull(() => uri, () => document);

    // Arguments are good -- continue...
}

Instead of four lines of code, we have one.  Furthermore, renaming the arguments will rename the variables in the lambda expression.

Here’s the code:

public static void CheckArgumentNull(
    params Expression<Func<Object>>[] exprs)
{
    foreach (var expr in exprs)
    {
        if (expr.Compile().Invoke() == null)
            throw new ArgumentNullException(
                (expr.Body as MemberExpression).Member.Name);
    }
}

The CheckArgumentNull method uses the params keyword to allow for a variable number of parameters to be passed in.  The type of the parameter is a lambda expression that has no parameters and returns an object.  This works well for passing in arguments from the calling method.

The helper method iterates through each lambda expression, and for each expression it compiles it and executes it.  If it evaluates to null, an ArgumentNullException is thrown.  We want to pass in the name of the argument into ArgumentNullException’s constructor, so to do this we need to decompose the lambda expression.

The expression’s body is actually a member expression, so we cast to that, get the Member object, access its Name property, and finally pass this value to the constructor.

Of course there is a nominal performance cost with this approach (nothing is for free), so if your method will be called in a tight loop then it might make sense to just code the null check yourself.

But my performance testing showed the overhead to be very acceptable, and the time spent executing CheckArgumentNull was usually minimal in the context of executing the entire method.

Hope you find this useful.

December 4, 2009

Conditional Attributes

Filed under: .NET,C#,Software Development — Larry Parker @ 8:42 am

Just when I gave up hope that I would have to retire a handful of attributes from my source code because they contained sensitive information (e.g. the name of the code reviewer), I came across this little gem in .NET – conditional attributes.

Now those “troublesome” attributes look something like this:

[Conditional("DEBUG")]
[AttributeUsage(AttributeTargets.All)]
public class CodeQualityAttribute : Attribute
{
    public String Author { get; set; }
    public String CodeReviewer { get; set; }
    public String UnitTestCompleted { get; set; }
    public Boolean OptimizationNeeded { get; set; }
}

By applying the Conditional attribute with “DEBUG” in the constructor, an attribute will only be compiled for debug builds — not only when it’s defined, but also when it’s used.

Now I can have the best of both worlds – sensitive information in my debug assemblies (which I can submit to a reflection utility for reporting), and clean release assemblies.

Pretty cool feature, huh?

Blog at WordPress.com.