Click here to Skip to main content
Click here to Skip to main content

Small sample of using Code Contracts

, 29 Sep 2010
Rate this:
Please Sign up or sign in to vote.
I had read about Code Contracts long time ago, but I didn’t see a reason to use contract instead of simple tests and argument's check with Exception's throws. Only now I’m trying to use them at real project. I didn’t see why I need to write: Contract.Requires(argument == null); Instead of l

I had read about Code Contracts long time ago, but I didn’t see a reason to use contract instead of simple tests and argument's check with Exception's throws. Only now I’m trying to use them at real project. I didn’t see why I need to write:

Contract.Requires<ArgumentNullException>(argument == null);

Instead of like I did it before:

if (argument == null)  
    throw new ArgumentNullException(“argument”)

Couple of weeks ago I had reinstall my Windows 7 on my laptop (I bought SSD for my laptop). After I install ReSharper with Visual Studio 2010 after run I accidental choosed “Go to the metadata” instead of like usual “Go to Object Explorer” by Ctrl and Mouse Click. So when I clicked on some class of System.xxx (basic classes of .NET) I looked at source code of these classes and found that they are using Code Contracts. I thought this is why I need to understand why I need to use contracts in my code, so I started to use them in some small applications and tried to find some interesting case.

You can look at previous blog post and find that I used code contracts in this sample. Actually it was first using code contracts. If you don’t know how to start using code contract in your project: you should go to the Microsoft Research site, download last code contracts installer and better to download last Editor Extension as well. When you will do this, you will see two additional tabs in project properties window.

So, let's look at an example. We have class like this:

public sealed class HotKey  
{ 
    private IntPtr _handle; 
  
    public HotKey(Window window) 
        :this (new WindowInteropHelper(window)) 
    { 
    } 
  
    public HotKey(WindowInteropHelper window) 
        :this(window.Handle) 
    { 
    } 
  
    public HotKey(IntPtr windowHandle) 
    { 
        _handle = windowHandle; 
    } 
}

In this class we are working with window’s handle, but we allow to create instance of this class not only with Handle as paramters, but with Window or WindowInteropHelper objects as well. What will happen if user will try to create new HotKey instance and put null instead of Window object (first constructor)? We will get Exception with message “Value cannot be null. Parameter name:window.”, this exception will throw constructor of type WindowInteropHelper. So it is good luck that we will get understandable message. But what about null instead of WindowInteropHelper (second constructor)? Try it. You will get NullReferenceException with message “Object reference not set to an instance of and object”. No good. How we can handle it? We can try to use separate method Initialize:

public sealed class HotKey 
{ 
    private IntPtr _handle; 
  
    public HotKey(Window window) 
    { 
        if (window == null) 
            throw new ArgumentNullException("window"); 
  
        Initialize(new WindowInteropHelper(window).Handle); 
    } 
  
    public HotKey(WindowInteropHelper window) 
    { 
        if (window == null) 
            throw new ArgumentNullException("window"); 
  
        Initialize(window.Handle); 
    } 
  
    public HotKey(IntPtr windowHandle) 
    { 
        Initialize(windowHandle); 
    } 
  
    private void Initialize(IntPtr windowHandle) 
    { 
        _handle = windowHandle; 
    } 
}

Аnd also you can use contracts:

public sealed class HotKey  
{ 
    private IntPtr _handle; 
  
    public HotKey(Window window) 
        : this (new WindowInteropHelper(window)) 
    { 
        Contract.Requires(window != null); 
    } 
  
    public HotKey(WindowInteropHelper window) 
        : this(window.Handle) 
    { 
        Contract.Requires(window != null); 
    } 
  
    public HotKey(IntPtr windowHandle) 
    { 
        _handle = windowHandle; 
    } 
}

Looks like that if you will pass null instead of WindowInteropHelper in second constructor you will get NullReferenceException again, because first will executed code in base constructor and next constructor’s body which we invoke. And R# tell us that we don’t need to check window!=null, because we used this variable before considering that it can not be null (I created bug in ReSharper Youtrack):

Untitled

Actually contracts works before method execution, so we will see Precondition failed exception:

Capture

Also if you want to see ArgumentNullException instead of ContractException you can write:

public sealed class HotKey  
{ 
    private IntPtr _handle; 
  
    public HotKey(Window window) 
        : this (new WindowInteropHelper(window)) 
    { 
        Contract.Requires<ArgumentNullException>(window != null); 
    } 
  
    public HotKey(WindowInteropHelper window) 
        : this(window.Handle) 
    { 
        Contract.Requires<ArgumentNullException>(window != null); 
    } 
  
    public HotKey(IntPtr windowHandle) 
    { 
        _handle = windowHandle; 
    } 
}

Or:

public sealed class HotKey 
{ 
    private IntPtr _handle; 
  
    public HotKey(Window window) 
        :this (new WindowInteropHelper(window))    
    { 
        if (window == null) 
            throw new ArgumentNullException("window"); 
        Contract.EndContractBlock(); 
    } 
  
    public HotKey(WindowInteropHelper window) 
        : this(window.Handle) 
    { 
        if (window == null) 
            throw new ArgumentNullException("window"); 
        Contract.EndContractBlock(); 
    } 
  
    public HotKey(IntPtr windowHandle) 
    { 
        _handle = windowHandle; 
    } 
}

So all next code only with contracts!

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

outcoldman
Software Developer (Senior) Mobile Systems International Ltd
Russian Federation Russian Federation
I'm MVP Client App Dev. At sum have more than 5 years’ experience in developing applications and components. You can find more information about me and read all of my articles on my personal site http://outcoldman.ru.
Follow on   Twitter

Comments and Discussions

 
Generalinteresting PinmemberCIDev30-Sep-10 7:25 
GeneralRe: interesting Pinmemberoutcoldman30-Sep-10 7:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140814.1 | Last Updated 29 Sep 2010
Article Copyright 2010 by outcoldman
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid