I would like to present here a little argument verification library that does not require you to type any string for specifying the name of the parameter you are checking. This lets the library faster to use, not intrusive in the actual method code, and refactor friendly. As a bonus you can use it by just embedding a single file. We can see below an example, just to get immediately to the point:
As we can see, there is no magic string at all. All the argument name are guessed thanks to the metadata contained in the linq Expression we use. For example the method at line 14 if called with a null value will report:
Value cannot be null.
Parameter name: arg1
The same happens to the more complex check we do at line 46, when we write:
Contract.Expect(() => array).Meet(a => a.Length > 0 && a.First() == 0);
We have a complex predicate do meet, described by a lambda, standing that the input array should have first element zero, and non zero length. Notice that the name of the parameter is array, but we need to use another name for the argument of the lambda ( in this case I used ‘a’ ), the library is smart enough to understand that ‘a’ actually refers to array, and the error message will report it correctly if the condition does not meet. Just to clarify, the message in case of failure would be:
Precondition not verified:((array.First() == 0) AndAlso (ArrayLength(array) > 1))
Parameter name: array
Well it is not supposed to be a message to an end real user, it is a programmer friendly message, but such validation error are supposed to be reported to a developer ( an end user should not see method validation errors at all, should he ? )
Well Meet is a cutting edge function we can use for complex validations. Out of the box, for simpler cases we have some functions too, as we can see on the IContract interface definition:
An interesting portion of the codebase proposed is the one renaming the parameter on the lambda expression, to achieve the reported message reflect the correct offending parameter. It is not so easy because plain string replacement would not work:we can have a parameter named ‘a’, seen in any place in the expression string representation and a plain replacement would resolve in a big mess, furthermore Expressions are immutable. So I found help on StackOverflow, and a reply to this question solved the problem, let see the “Renamer” at work ( Thanks to Phil ):
Basically is a reusable class that take the new name of the parameter and returns a copy of the input expression with the (single) argument changed.
To improve the library or just use it, please follow/check out the project on Bitbucket, suggestions and comments are always welcome.