tags:

views:

183

answers:

7

I wonder if there is a less verbose way to do Input Verification in my methods. For example, i commonly write stuff like this:

public string SomeFunction(string param1, int param2)
{
    if(string.IsNullOrEmpty(param1)){
        throw new ArgumentException("bla", "param1");
    }
    if(param2 < 0 || param2 > 100 || param2 == 53)
    {
         throw new ArgumentOutOfRangeException("eek", "param2");
    }
}

Now, I wonder if there is a way to set up constraints on the parameters and have the compiler already handle that for me? I believe that this is called "Contract" and I remember seeing that Spec# is supposed to do that, but that seems to be an experimental research project at the moment.

So I wonder: Is there anything that can give a clean enforcing of Constraints (at least the simple and often recurring ones like string.IsNullOrEmpty) for input parameters for .net 3.5 SP1 and ideally .net 3.0 already?

+6  A: 

Well, you could do something with AOP, look at PostSharp.

This could be used to just inject the necessary code, but it adds some overhead, both to the compilation step and to the compiled code.

Code Contracts are also slated to be included in .NET 4.0, read more about this here.

Lasse V. Karlsen
Just to clarify, they're not really part of C# 4.0 - they're in .NET 4.0. There's nothing language-specific about them as far as I'm aware. Excellent blog reference though ;)
Jon Skeet
Of course, I'll correct my answer :)
Lasse V. Karlsen
+2  A: 

You could introduce a CheckParameter method so you have only one line of code in your original method.

Something like this:

public string SomeFunction(string param1, int param2)
{
    CheckParameterNotNull(param1);
    CheckParameterRange(param2, 0, 100, 53); 
...
}

Of course you would need some smart CheckParameter method to fit all your cases.

Drejc
+2  A: 

Three words: design by contract

One implementation for C# can be found here: http://www.codeproject.com/KB/cs/designbycontract.aspx

VVS
+1  A: 

Consider "Spec#" by Microsoft Research: http://research.microsoft.com/SpecSharp/

It extends C# to allow you to define contracts and they have put a good amount of work into putting contracts into the BCL and stuff.

JasonRShaver
A: 

You can keep all the parameter-checking code as-is, but then delegate the real work to a private function. The private function will do no parameter checking because it will only ever be called by the public gatekeeper function.

private string InternalSomeFunction(string param1, int param2)
{
  /* implementation goes here */
}

public string SomeFunction(string param1, int param2)
{
  if (string.IsNullOrEmpty(param1)) {
    throw new ArgumentException("bla", "param1");
  }
  if (param2 < 0 || param2 > 100 || param2 == 53) {
    throw new ArgumentOutOfRangeException("eek", "param2");
  }
  return InternalSomeFunction(param1, param2);
}

It's just as verbose as the original, but at least your main function isn't cluttered with stuff that isn't really central to the implementation of the method.

On the other hand, by moving the parameter-checking code away from the rest of the implementation, this also removes some of the self-documenting aspects of the checks. When you're looking at InternalSomeMethod, for instance, there is no longer a reminder that param1 will always be a valid non-empty string, so you or a maintenance programmer may be tempted to add a check for that later in the internal method.

Rob Kennedy
A: 

Modeling after the WebForms type world, you could use a set of ErrorProvider control and attach them to your critical TextBoxes, CheckBoxes, etc. in question. You can fire off checks to these fields whenever the user changes focus, or however frequently you prefer.

You can then create a method called IsFormValid that would check through all the ErrorProviders and return a simple True value if all the ErrorProviders check out.

Then in all your major code, all you have to do is wrap your processing around..

if (IsFormValid)
{
   // Processing Magic Goes here.
}

The nice thing with this is that you could potentially have different "valid" states depending on what a particular method is trying to accomplish. Sure the phone number field may be invalid and showing a little red dot, but that shouldn't prevent the UpdateFirstLastName method from firing off.

Dillie-O
A: 

In the meantime since asking this question, Code Contracts have evolved, which looks like the Silver Bullet.

The current CTP is available here (for .net 3.5), and it is part of .net 4.0.

Michael Stum