Click here to Skip to main content
12,348,536 members (38,953 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

11.4K views
2 bookmarked
Posted

Small Sample of Using Code Contracts

, 29 Sep 2010 Ms-PL
Rate this:
Please Sign up or sign in to vote.
This is a small sample of using code contracts.

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 in 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(&ldquo;argument&rdquo;)

Couple of weeks ago, I had to reinstall my Windows 7 on my laptop (I bought SSD for my laptop). After I installed ReSharper with Visual Studio 2010 after I run, I accidentally chose “Go to the metadata” instead of the 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 the 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 my 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 the last code contracts installer and it is 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 parameters, 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 an 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 an 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; 
    } 
}

And 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 the second constructor, you will get NullReferenceException again, because first it will execute 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 cannot be null (I created bug in ReSharper Youtrack):

Untitled

Actually, the 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)
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
Generalinteresting Pin
CIDev30-Sep-10 7:25
memberCIDev30-Sep-10 7:25 
GeneralRe: interesting Pin
outcoldman30-Sep-10 7:50
memberoutcoldman30-Sep-10 7:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    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 | Terms of Use | Mobile
Web02 | 2.8.160621.1 | Last Updated 29 Sep 2010
Article Copyright 2010 by outcoldman
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid