[Mono-list] Design by Contract

Stephen Touset stephen@touset.org
Mon, 27 Dec 2004 11:46:16 -0500 (EST)


I've been using C# for quite awhile now, but one feature that I wish was
available in the language is support for Design by Contract:
automatically-enforced preconditions and postconditions on functions, and
invariants on classes.

Having done some research into the problem, the best approach seems to be
using attributes. Using statements inside functions works, but induces a
lot of programmatic overhead; specifically, inheritance rules for DBC
would need to be implemented manually. Invariants, also, would be tedious:
code to check against the invariant would need to be added before the
preconditions and after the postconditions of every function in the class.
Worse still is that postconditions must be inserted above every return
statement. This isn't too bad if you insist upon only one return statement
per function, but for anyone with multiple returns, this becomes tedious
quickly. And of course, all of these are clear violations of the Don't
Repeat Yourself rule.

Attributes seem to be the way to go. The pre/postconditions and invariants
are, at the core, metadata about the functions and class. The attributes
themselves would be able to understand their own inheritance criteria, and
code can automatically be generated to verify the terms of the contract
wherever needed. Unfortunately, the way attributes in C# are implemented,
there seems to be no way to practically use them. Reflection may be
powerful, but there doesn't appear to be a way that an attribute can
access (or even determine) the function or class that it applies to.

My initial approach was to use the CodeDom libraries to insert code into
functions that would be dynamically based upon the applicable attributes,
and enforce the conditions correctly. However, the inability for
attributes to access the "calling" class all but cripples this attempt. My
next thought was to simply have a script which would understand the
attributes and insert the applicable statements at compile-time. However,
the need for attribute inheritance quickly caused this approach to become
unwieldy.

Does anyone have an idea about how this could be done in a reasonable
fashion? If so, would anyone be willing to help on the project?

-- 
Stephen Touset <stephen@touset.org>