Elegant method parameter validation with Code Contracts support

February 25, 2015, (updated on February 26, 2015), 1 comment, Software Development

Each C# developer knows the drill: Each method parameter has to be validated against null values, wrong value ranges or other contract constraints. When also validating using Code Contracts, the resulting code may take up most of the method body:

public void Foo(object a, string b)
{
    Contract.Requires(a != null);
    Contract.Requires(b != null);
    Contract.Requires(b != string.Empty);

    if (a != null)
        throw new ArgumentNullException("a");
    if (string.IsNullOrEmpty(b))
        throw new ArgumentNullException("b");

    ...
}

Note: When Code Contracts runtime validation is enabled, the call to Requires may throw an exception and the own code for throwing an ArgumentNullException is not needed. However, often the runtime validation is disabled and I still want that the exception is thrown – this is why there is the redundant code.

The previous code can be reduced using the EndContractBlock method. I still think it is a little bit too long:

public void Foo(object a, string b)
{
    if (a != null)
        throw new ArgumentNullException("a");
    if (string.IsNullOrEmpty(b))
        throw new ArgumentNullException("b");

    Contract.EndContractBlock();

    ...
}

This is why I created extension methods which reduces the code further to the following, elegant calls:

public void Foo(object a, string b)
{
    a.CheckNotNull(nameof(a));
    b.CheckNotNullOrEmpty(nameof(b));

    ...
}

These extension method invocations support Code Contracts, throw ArgumentExceptions and are inlined to avoid performance problems. In the sample code I use the nameof operator which will be available in C# 6 – when compiling with earlier C# versions you should use hard-coded strings for optimal performance.

Let’s have a look at one of the extension methods:

public static class CodeContractExtensions
{
    [ContractAbbreviator]
    [DebuggerStepThrough]
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void CheckNotNull([ValidatedNotNullAttribute] this object value, 
        string parameterName)
    {
        Contract.Requires<ArgumentNullException>(value != null, 
            "The value '" + parameterName + "' cannot be null. ");

        if (value == null)
            throw new ArgumentNullException(parameterName);
    }

    ...

    [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
    public sealed class ValidatedNotNullAttribute : Attribute
    {
    }
}

The most important part here is the ContractAbbreviatorAttribute: This attribute defines that the contained Code Contracts are “copied” to the calling site and applied there. The DebuggerStepThroughAttribute tells the debugger not to break inside the method but on the call site if an exception is thrown. The MethodImplAttribute with the AggressiveInlining option instructs the compiler to inline the method if possible. To avoid FxCop warnings, the value parameter is decorated with a ValidatedNotNullAttribute which disables the static validation of the parameter. The content of the extension method looks the same as the original code sample…

I think the usage of these extension methods produce very readable code. What do you think about this approach to method parameter validation?

Source code

The full source code of the extension class can be found here:

Tweet about this on TwitterShare on FacebookEmail this to someoneShare on TumblrShare on LinkedIn

Tags: , , , , , ,

One response to “Elegant method parameter validation with Code Contracts support”

  1. Jeremy says:

    Thanks a lot for this, removes a lot of boilerplate code!

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax