views:

107

answers:

3

i just noticed the guard method/class mentioned in this question and i don't really get the concept from the answers. And alas, Jon Skeet's link to an MS site never loaded. A few quick Google searches seemed to yield only products, not software engineering concepts.

Any explanation and/or samples would be appreciated. (Especially from the .Net side of things.)

A: 

This is a pretty good rundown of what a typical guard clause use-case looks like:

Refactoring guard clauses, or “How to ask politely”

Gurdas Nijor
i looked at that article from the link and honestly from the discussion afterwards it seems more like how NOT to do guard clauses.
Paul Sasik
+1  A: 

Guard clauses are a part of aspect oriented programming, where you can define what is an allowable input to a method.

From what I know of the .Net implementation (which I haven't really looked into), you do this with attributes, e.g.

public static void NeverGetNull([ThisParamNotNull]MyClass i, [ThisParamNotNull]OtherClass j)
{
   // Will never need to check for null values on i or j!
}

I actually know what guard expressions are from Erlang, where the method dispatch is dependant on the guard methods. I'll give a bit of psuedocode below to illustrate the point:

myMethod(input i) where i is an int
{
 return i + 10
}
myMethod(input i) where i is an int and i > 10
{
 return i - 10
}

var i = myMethod(1) // returns 11
var i = myMethod(i) // returns 1

As might not be obvious, you could provide an expression in the guard which is evaluated during dispatch. Pretty neat, hey?

Khanzor
Interesting. What happens when the input is not allowable? Such as in your pseudo code example, you start with a value of -5?
Paul Sasik
Well, if all the guards fail, then the method call fails. There is no match for it. It's the same as when you try to call a method that you don't have a matching signature for in C#. But in my example, -5 is a valid input, so first you'd get 5, then 15, calling the method a third time would yield 5. Hope that clears it up?
Khanzor
A: 

If you don't specify an exception then .NET will throw a RaiseContractFailedEvent, but you can specify ArgumentOutOfRangeException or ArgumentNullException.

If you look at Jon Skeet's link, at the documentation pdf you will see many examples, one is:

Contract.Requires( x ! = null );

This is part of Contract Design, where you specify preconditions and postconditions. The advantage is that you don't have to do a lot of validation before using the input parameters, and it helps the calling function to know that the result will be according to the contract, so, if the string return isn't allowed to be a null then you don't have to test for null when calling the function, due to the precondition checking.

James Black