Elegant Invariant Checking with C# 3
Of all the great advice in The Pragmatic Programmer, one of the ideas I’ve found most useful is that of Design by Contract. Most commonly, I check method preconditions using something like:
private void MyMethod(object arg1, string arg2) { Invariant.ArgumentNotNull(arg1, "arg1"); // throws ArgumentNullException Invariant.ArgumentNotEmpty(arg2, "arg2"); // throws ArgumentOutOfRangeException // do stuff }
I quite often check invariants at other points in a method too:
private void MyMethod(object arg1, string arg2) { var myVar = AnotherMethod(); Invariant.IsNotNull(myVar); // throws InvalidOperationException // do stuff with myVar }
This approach works well but, in the case of preconditions, having to duplicate the argument name as a string is obviously not ideal. Perhaps using some of the new features of C# 3 we can do better?
Here’s one API I’ve been playing with:
private void MyMethod(object arg1, string arg2) { Check.Argument(() => arg1.IsNotNull); // throws ArgumentNullException Check.Argument(() => arg2.IsNotEmpty); // throws ArgumentOutOfRangeException // do stuff }
And for simple invariants:
private void MyMethod(object arg1, string arg2) { var myVar = AnotherMethod(); Check.Invariant(() => myVar.IsNotNull); // throws InvalidOperationException // do stuff with myVar }
This approach leverages expression trees and extension methods to create a more fluent API and allows us to do away with the string argument when checking arguments.
Although I’m not 100% happy with it, I think I prefer this API. What do you think?
Download the code here.
Trackbacks
Use this link to trackback from your own site.



Elegant Invariant Checking with C# 3 …
You’ve been kicked (a good thing) - Trackback from DotNetKicks.com…
One problem I see is that it will pollute intellisense with IsNotNull, IsNotEmpty, etc methods.
Perhaps, although one advantage is that these methods can actually be useful on their own. i.e:
if (myString.IsNotEmpty())
{
// instead of !string.IsNullOrEmpty()
}
Even IsNull() is similar to the Ruby idiom of nil?
Attributes can also be used to hide the methods from intellisense.
I’m liking the look of this, although I haven’t been so concerned with the issue to evaluate it properly yet.
http://research.microsoft.com/SpecSharp/
Cool!
Tought in boo it is much more simple :)
def DbC[[Required(extendee != null, "extendee must be not null")]extendee as object]:
PS
What about ensures?
What about putting the magic method later in the fluent API, outside the expression, something like:
Check.That(()=> arg1).IsNotNull();
In that case there’d be no extension methods, but would be too many parentheses for my liking…
What about
Require.Value( () => arg1);
Whats wrong with:
Invariant.ArgumentNotNull(arg1);
or
Invariant.Argument(arg1).IsNotNull();
- reflection should help us reveal the parameters real name….
I’m not so sure I see a big improvement. Invariant.ArgumentIsNotNull has the advantage of having the requirement at the beginning, not polluting intellisense and not having an ugly parameterless lambda function. Your new method only saves the need to specify the name of the argument in addition to its value.
this code can be used in generating documentation.
Invariant.ArgumentNotNull(arg1, “arg1″); // throws ArgumentNullException
Invariant.ArgumentNotEmpty(arg2, “arg2″); // throws ArgumentOutOfRangeException
it’s cool
Have you seen this?
http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=38#body
Regarding your use of C# 3 syntax to get around the redundancy, I suggested something similar to the CuttingEdge.Conditions library:
http://www.codeproject.com/script/Forums/View.aspx?fid=1498290&msg=2640907
But the author said:
I’m sorry Judah,
but it’s even worse than you would expect. I just did some performance testing. I compared the following two lines:
a.Requires(”a”).IsNotNull();
compared to:
a.Requires(() => a).IsNotNull();
What’s the difference? Well, the first line actually doesn’t even allocate a string. It just uses a reference (a 32 bit number) to reference a string that is already allocated (and as long as that string isn’t used, there only the cost of copying an Int32 on the stack).
The second isn’t a simple delegate allocation. It actually allocates 7 new objects on the heap, makes at least 9 (non-inlinable) method calls and does some heavy reflection to build up the Expression (see for yourself with Reflector). And the worst part is that it doesn’t do this only once during initialization. No, it does this every time a call to Requires(() => a) is made.
I found that the second statement is actually over 200 times slower than the first. here
you can take a look at my test code.
I like the idea its got me thinking. The question I have is:
Check.Argument(() => arg1.IsNotNull); // throws ArgumentNullException
How would you determine the argument name when constructing your ArgumentNullException.
Without that its the equivalent of your original code minus the string argument name.
Invariant.ArgumentNotNull(arg1);
Stuart,
This is done by picking apart and inspecting the expression tree resulting from the lambda.
Cheers,
Andrew.