C# by Contract – Using Expression Trees

Last time I created a simple, but powerful, little design by contract library in C# 3.0. It took hardly any lines of code, and covered a broad range of possible usage scenarios. See here, for more on DBC. One thing that bothered me was the fact that if something failed a check, it wouldn’t tell what went wrong. I had a little free time today, so I thought I’d fix that. I wanted the exceptions it threw to have the text of the check we were performing. Developers need to see exactly what test failed. Generic “assertion failed” error messages are useless.

In my previous efforts at .NET DBC, I used strings to pass around the predicate body that I wished to evaluate. That allowed me to have a copy of the text handy, but with lots of drawbacks. In those frameworks, I created a new class that derived from the one being tested, but with the predicates inserted at the beginning and end of the methods they were attached to. That allowed me to do things like this:

[Requires("arg1 > 10")]
[Requires("arg2 < 100")]
[Ensures("$after(Prop1) == $before(Prop1) + 1")]
public void TestMethod(int arg1, int arg2, string arg3)
{
    Prop1 = Prop1 + 1;
    System.Diagnostics.Debug.WriteLine("MyTestClass.TestMethod.Prop1 == " + prop1.ToString());
}

This let me to test private fields and properties, but on the other hand it stopped me from testing sealed classes. There’s trade-offs no matter what you do unless you control the compiler, as is the case of Spec#, Eiffel or D. The attribute based approach is not dissimilar to Spec#, where a contract specification is part of the method signature rather than in the body of the method.

int BinarySearch(object[ ]! a, object o, int lo, int hi)
    requires 0 <= lo && lo <= hi && hi <= a.Length;
{ . . . }

The difference is that Spec# uses syntactical enhancements, whereas I used Attributes. As I mentioned in another post, you can’t use lambda functions in Attributes, nor could you use Expression trees based on lambda functions because the attribute itself cannot be generic. Another major drawback of the textual approach shown earlier is that it isn’t type-safe. You could type any old garbage into that string, and you’d never know till run-time. You don’t get intellisense either. We need a better way.

Expression trees are great for what we want, they are strongly typed, they can be assigned from lambda functions and they needn’t be compiled until they’re needed. Another cool thing is that the changes needed to use lambda expressions are trivial. Here’s the Require extension method I showed you last time. It uses Expressions now.

public static void Require<T>(this T obj, Expression<Func<T, bool>> pred)
{
    var x = pred.Compile();
    if (!x(obj))
        throw new ContractException(pred.ToString());
}

All I had to do was convert the Func<T, bool> into an Expression<Func<T, bool>>. The compiler, seeing the method signature, knows that it needs to do some background conversion. It doesn’t convert and pre-compile the lambda function that you pass into the extension method. Instead it first converts it to an expression tree. The Expression<Func<T, bool>> has a Compile method that will convert it to an anonymous method, which we call just before invoking it. You may be wondering why we would bother?

Because Expression<Func<T, bool>> also overrides ToString() giving the source code of the lambda function that it was created from. That’s so cool! Now I can pass the code I was trying to run into the exception class if the code fails!. Here’s the kind of output you get if the check fails.

TestCase ‘Tests.TestPredicates.MyFailingMethod’
failed: Contracts.ContractException : x => (value(Tests.TestPredicates).MyInt = x.before().MyInt)

That’s more readable than a plain old ‘ApplicationException’, don’t you think?  The predicates needn’t be one-liners either; you can have very complex predicates in this system too. Here’s an example from another project I’m working on. The use of scopes is more like the DBC implementation in the D Programming Language.

public bool Insert(string location, string xmlFragment)
{
    this.Require(x => !string.IsNullOrEmpty(location));
    this.Require(x => !string.IsNullOrEmpty(xmlFragment));

    XDocument fragDoc = XDocument.Parse(xmlFragment);
    object tmpInsertPoint = LobDocument.XPathEvaluate(location);
    bool result = false;

    using (new PredicateScope(this, fragDoc, tmpInsertPoint))
    {
        this.Ensure(x => tmpInsertPoint != null);

        if (tmpInsertPoint != null)
        {
            if (tmpInsertPoint is XElement)
            {
                XElement insertPoint = tmpInsertPoint as XElement;
                insertPoint.Add(fragDoc);
                result = true;
            }
        }

        this.Ensure(x =>
            {
                XElement originalInsertPoint = tmpInsertPoint.before() as XElement;
                XElement currentInsertPoint = tmpInsertPoint as XElement;
                int countbefore = originalInsertPoint.Elements(fragDoc.Root.Name).Count();
                int countafter = currentInsertPoint.Elements(fragDoc.Root.Name).Count();
                return countafter == (countbefore + 1);
            });
    }
    return result;
}

This is a fairly advanced use of lambdas and expression trees, but it certainly doesn’t plumb the depths of what we could do. Those of you who’ve read some of the stuff I did in ’06 and ’07 on the internals of LINQ will remember that expression trees will be storing references to all the properties and other parameters of the lambda function. That means we can add them to the ContractException. We can also show what values they were before and after the operation. Perhaps next time I’ll explore what can be done with all that extra data we’ve now got.

Till then, enjoy!

About these ads

13 comments

  1. I recently discovered some DBC ideas in the .NET 3.5 framework via Reflector. Your approach is definitely an interesting use of expression trees and lambdas. It’s especially nice that you can get the string that represents the expression. How much extra do you think this approach gives you in production compared with the stack trace of a traditional exception that Require(…) could throw?

    This is my first time at your blog, I’ll definitely add it to my reader. Keep up the interesting work!

  2. Hi Jeff,

    I noticed the same (frustratingly internal) things too. I also enjoyed your post very much. I’m sorry I didn’t give you any link love at the time of writing – I forgot the URL between me reading your post and revisiting this issue myself.

    Using a stack trace might be acceptable, except that it only tells me _where_ the exception got thrown (not why). That where part will be in the predicate method, not in the method that called the predicate, so it will not be so useful. Also being able to literally show the code (rather than its location) is really useful when you’re potentially just looking in log files. An exception class or stack trace can’t do this normally – that’s why I had to resort to LambaExpressions.

    Going back to the disassembly of the System.Core assembly, it looks as though there’s a method called ‘Old’ that seems to serve the same purpose as my ‘before’ extension method. It’s not clear how or where that gets used, but it definitely requires the spec# assembly rewriter to provide those snapshot services. My ‘before’ extension method allows me to describe the effects that the method will produce if you meet the contract in the require clauses of the method. Which is critical to DBC, in ensuring that you the service provider meet the terms of the contract.

    Unfortunately, one critical aspect of the DBC picture is still missing from my implementation – inheritance. In Eiffel, and attributes in .NET, you can control the inheritance of a constraint. With virtual methods, a specialisation relationship increases the total constraints as new constraints get added to the method in the sub-class. Using constraints within the body of the method denies me that ability. That’s the reason I was so set on using attributes to begin with, where the ‘GetCustomAttributes’ method will retrieve all of the attributes all the way up the inheritance hierarchy.

    I see that flaw as pretty major in my implementation, but right now I can’t see a way around it. If you have any ideas, please let me know. I think DBC is a very powerful way to increase the quality of my code, and to help me think about how it works in the abstract. So I’d like to get it right.

    Cheers

    Andrew

  3. I definitely think that to do DBC well, we’ll need framework and compiler support. I really hope Spec# goes mainstream into a future version of C#. It appears that the Boogie component of Spec# does some nice static analysis/proving of conditions. I’d love to see these tools all converge to something like much better compiler errors that would tell you that “If I compiled this code, it’d produce a contract violation.”

    Right now in my production code, I’m sort of doing a hybrid of a “Guard” class for basic contracts and Asserts for ensure clauses. I’ll be checking this blog for ideas on how to go further than that though.

  4. Very nice article (as always). I cam see how the Require function alone is massively helpful.

    Im just coming to terms with all the DBC / Spec# stuff and I had a very quick question .. does this mean that Ensure has exactly the same syntax as Require ?

  5. Thanks Stephen,

    Thanks for your kind remarks – glad to know you (too) are getting something out of this! ;-)

    Yes, In this case the syntax of any predicate will be of the form:

    static void Assert(bool testresult){if(!test) throw new Exception();}

    but there is an implied semantic difference, which is why I’ve distinguished between the two (needlessly). A Require-type method is equivalent to any other ‘Assert’ type method – it checks the incoming boolean, and if false it throws. The Ensure, on the other hand could do a more complicated job, because it it not only testing the current state, but comparing it to the previous state.

    In addition, the Ensure could throw a different contract exception like EnsureException or something like that. I’ve done this before to distinguish the type of predicate I was testing. I haven’t done it with this little system, but I probably should. That would be easier to implement if I had two predicate testing methods: Require and Ensure.

    Cheers

    Andrew

  6. I like the use of extension methods for this but I don’t like the extraneous “x =>” when the parameter is not actually being used for anything in the lambda. I don’t know how much of an improvement it would be, but you could change your predicate to take a Func (no input parameters) and use the no-parameter syntax:

    this.Require(() => !string.IsNullOrEmpty(location));

    At least that way the reader isn’t looking around thinking, “Ok, there’s this parameter x . . . what’s it for?”

  7. Hi Eric,

    Yes, that would be nicer. I guess that with closures I don’t need to worry too much about whether the objects I want to make comparisons on are in scope within the lambda when it gets invoked inside the predicate checking method. I guess that parameter stemmed from earlier incarnations, but it’s really not needed any more.

    Cheers

    Andrew

  8. Great idea!

    I’ve just extended this to check that arguments are not null.

    Here is the method

    ———————————-
    public static void RequireArgumentNotNull( this object obj, Expression<Func> expr )
    {
    var x = expr.Compile();
    var o = x();

    if( o == null )
    {
    string paramName = “”;

    if( expr.Body is MemberExpression )
    {
    paramName = ((MemberExpression)expr.Body).Member.Name;
    }

    throw new ContractException( expr.ToString(), new ArgumentNullException( paramName ) );
    }
    }
    ———————————-

    And an example of its usage

    ———————————-
    public void TestArg( string someArg )
    {
    this.RequireArgumentNotNull( someArg );


    }
    ———————————-

    The great thing about this is that the param name is now not a string as it used to be with a simple “throw new ArgumentNullException(…)”, so refactorings work etc. Naturally you need to rely on the user using the method correctly but since in this case I’m my only user its not a problem :)

    Andre

  9. Design by contract is not simple as that. When you writing contracts you are writing policy for both client ( invoker ) and method it self. If any of this sides are trying to break policy ( for client precondition and for method postcondition ) the exception will be thrown which will tell us that illegal call of method is invoked, if precondition is not satisfied ,or method is not properly implemented if precondition is satisfied but postconditions are not.
    One more thing, contracts are not spoused to be implemented in production code. That is why contract methods should be putted in comments of method or as attributes, not in method body/implementation. Look onto JML, which is made for Java, or bogor… If all went OK, dynamic and static analyzes are passed in whole application, then contracts are satisfied and application is working properly so contracts are not needed any more! so there is no need for abnormal amount of ArgumentNullExceptions, for instance, just to ensure that method is not called with null argument.

    I must say this is good article, but be aware that some things can and will some times put you on wrong way.

    I’m currently working on VS2008 Tool which will do static and dynamic analyze of code. But I’m just at start because its working with IL code and there is lots of work to do. In min time I’m googleing if someone has done it already for .NET :) so I can be focused on my projects full time :)

    One more thing, DBC is not test driven design, it is mathematical prove that your application is working correctly.

    Regards,
    Milan

  10. Nice! I changed the extension name to “Requires” and named the parameter “that” by convention, so you end up with:

    this.Requires(that => username.IsNotNullOrEmpty());

    Reads a bit better.

Comments are closed.