Contract.Requires usage
Asked Answered
C

3

48

Here is my problem. I am a very big fan of Design by contract, I am using this concept especially when developing libraries that can be used by other developers. I just found out a new way of doing this which is: Contract.Requires instead of Exception: So instead of having:

public void SomeMethod(string name){
   if(name==null) throw new NullArgumentException("Null values not supported");
} 

I now have:

public void SomeMethod(string name){
   Contract.Requires(name != null);
}

EDIT: I am working under VS2010 on debug mode.

Problem: Contract.Requires does not do anything, even when name is null!

The MSDN documentation says:

Specifies a precondition contract for the enclosing method or property.

But nothing is specified in case the condition is not met!

I also noticed there are other Contract.Requires overloads that throw exception, display message... but then what is Contract.Requires(Boolean) for?

EDIT Answer below highlighted that a plug-in must be installed to have the full power of Contract API but then what about Mono users who want their code to behave the same on different platforms?

Cakewalk answered 28/11, 2011 at 18:56 Comment(2)
You might find this useful: https://mcmap.net/q/371922/-code-contracts-for-monoEpic
Thanks for the tip. With all this hassle I think I better have to stick to the old way of throwing exceptionsCakewalk
S
26

You should do the following:

  1. Install the Code Contracts add-in as nfechner has noted
  2. Go to the project properties, 'Code Contracts' folder
  3. Check 'Perform Runtime Contract Checking'
  4. Switch 'Assembly Mode' to 'Standard Contract Requires'
  5. Substitute your Contract.Requires with Contract.Requires<SomeException> (the first one throws System.Diagnostics.ContractException while the second throws the exception you specified which is important for public methods)

That's the basic setup. For more accurate configuration, refer to the manual

If you use Mono, probably, Contract class is empty. I haven't done this, but chapter seven from the Contracts manual seems to explain how to provide your own implementation.

Stillmann answered 28/11, 2011 at 19:19 Comment(4)
+1 for these tips. I would rather stick to exceptions in this case. Is there a similar tool for MONO?Cakewalk
I am not only interested in using this in MONO but looking for portability from Windows to Linux and vice versaCakewalk
I'm not sure how it works, but I do think you should try implementing custom contract runtime. It should not be very difficult. I expect the implementation to be easily portable. If you do this and if you have VS Professional+, then you'll get the benefits of compile-time contract checking, which are valuable. I would give it a try.Stillmann
@GETah: The Code Contracts plug-in performs a post-compilation step that rewrites the IL in your assembly to in include the runtime checks. If your assembly is compatible with Mono, it will perform the Contract.Requires(...) checks on both Windows and Linux. The only issue is with compiling the code on Linux, where the IL rewriter is not available. If you do all your development on Windows then Code Contracts will not in any way affect cross-platform compatibility.Hickerson
S
11

From the Contract class docs:

Important

You must install a Visual Studio add-in to enforce contracts. The Code Contracts Premium Edition add-in lets you specify static and run-time checking of code contracts on the project Properties page. If you do not enable run-time checking, contracts such as the Contract.Ensures method will not throw exceptions during run time if a contract is violated. The Visual Studio add-in does not ship with Visual Studio 2010 or the Windows SDK.

Skylab answered 28/11, 2011 at 19:1 Comment(1)
+1 for the tip but this resolves the problem only on one end. Please see my updates on the questionCakewalk
I
2

With a message like this it is usually helpful to specify exactly what you have done.

For example, you do not mention in the original message if you have installed the VS Addon, nor that you have enabled it under your project properties, or that you are actually running in debug vs release mode, etc.

Re Contract.Requires vs Contract.Requires<Exception>

Contract.Requires is recommended. According to the manual

If your code must throw a particular exception on failure of a particular precondition, you can use the generic overloaded form below. (Please read Section 5.1 before committing to this form in your code. You cannot use Requires < Exn <Exn>> without running the contract tools on all builds. If you do, you will get a runtime failure everytime.)

Indoaryan answered 28/11, 2011 at 19:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.