Sep 8, 2010

C# Code Contracts - Argument Validators

I’m just getting started with C#’s CodeContracts. In some ways CodeContracts overlap a little with some code analysis done by ReSharper. One particular technique I use for ReSharper was causing me problems. I have a utility method ThrowIfNull(someObject). This method cleans up my code because instead of adding a test for null and conditionally throwing an exception I just call the method. I had to attribute this method so that ReSharper would recognize that I was checking for possible null reference exceptions. The same holds true for Code Contracts. The required attributes aren’t in the mscorlib so I had to navigate to:

C:\Program Files (x86)\Microsoft\Contracts\Languages\CSharp

and add the ContractExtensions.cs file to my assembly. Then I could just decorate ThrowIfNull() with [ContractArgumentValidator] and put the Contract.EndContractBlock() legacy call at the end of the method and now C# Code Contracts know that ThrowIfNull() is a contract. One problem was I have a tendency to reduce if() block levels by doing things like

if (object != null) return;

//All the test and throw code will go here

Unfortunately with this approach when I append the EndContractBlock() call the compiler detects it as unreachable so I just reversed the if logic., My final method is a little noisy  with all these attributes but it’s short enough that it shouldn’t cause any bad headaches.

//Use attributes so both ReSharper and CodeContracts know this method is a contract
[AssertionMethod, ContractArgumentValidator]
public static void ThrowIfNull(
    [AssertionCondition(AssertionConditionType.IS_NOT_NULL)]object objectToTest, string objectName)
{
    if (objectToTest == null)
    {
        string msg = string.Format(StringResources.P0_PropertyIsNull, objectName);
        throw new InvalidOperationException(msg);  
    }
    Contract.EndContractBlock(); 
}

What does cause a bit of a headache is the fact that this method won’t work if it’s called within a try/catch or using block. The CodeContract team is working on this so we may not have this limitation in a future revision.

About Me

My photo
Tod Gentille (@todgentille) is now a Curriculum Director for Pluralsight. He's been programming professionally since well before you were born and was a software consultant for most of his career. He's also a father, husband, drummer, and windsurfer. He wants to be a guitar player but he just hasn't got the chops for it.