Rico Suter's blog.
 


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:



Discussion