How will you make it if you never even try?

April 2, 2009

Some more good ideas about parameter validation in C#

Filed under: C# — Tags: , , , , , — charlieflowers @ 6:20 am

As you can tell from several recent posts, I’m very interested in good syntax for parameter validation. The new features in C# 3.0 make so many things possible. I found another excellent post, from John Gilliland. He “amplifies” each plain old argument value into an ArgumentEx<T> instance, and then hangs extension methods such as “NotNull” and “InRange” off of ArgumentEx<T>. He uses an implicit conversion operator to make it easy to treat an ArgumentEx<T> as the plain old argument value.

Very nice, very thorough. Check it out. I’d like to combine elements of his approach with the lambda expression idea that allows you to avoid specifying both the parameter and the parameter name as a string.

April 1, 2009

Elegant, appealing parameter validation syntax in C# 3.0

Filed under: C# — Tags: , , , , — charlieflowers @ 7:21 am

This is a VERY cool trick that leads to much improved syntax for parameter validation in C# 3.0. (Kudos to Jon Fuller).

Often when writing methods, you need to validate that the parameters you’ve received are valid. So you might write some code like this:

public void SomeMethod(string firstName, decimal salary, int ageInYears)
{
   if(firstName == null)
      throw new WhateverException("The 'firstName' parameter cannot be null.");

   if(salary < 0)
      throw new WhateverException("The salary must not be negative.");

   // And so on ... you get the idea.
}
&#91;/sourcecode&#93;

When you write that in several places, it is only natural to start thinking about a <em>helper</em> to get rid of some of the duplication. Millions of ways to go about it, and it might look something like this:


public void SomeMethod(string firstName, decimal salary, int ageInYears)
{
   ValidationHelper.NotNull("firstName", firstName);
   ValidationHelper.NotNegative("salary", salary);
   // And so on ... you get the idea
}

The thing that sucks about this is that you have to provide the parameter name as a string. You want the error message to say, “The ‘salary’ parameter was severely messed up.” Therefore, it needs “salary” as a string. This is not DRY, because you’ve already designated which parameter you mean. Also, it is not friendly for refactoring.

And C# 3.0 lets you get rid of it!!!! Here’s how:

public void SomeMethod(string firstName, decimal salary, int ageInYears)
{
   ValidationHelper.NotNull( ()=> firstName );
}

The NotNull method is defined as follows:

public static void NotNull(Expression<Func> expr)
{
  if ( ! expr.Compile()().Equals(default(T)))
    return;

  var param = (MemberExpression)expr.Body;
  throw new WhateverException("The parameter '" + param.Member.Name + "' cannot be null.");
}

Notice that the exception message does contain the string “firstName”, but that there IS NO SUCH STRING anywhere in the code! How does this work?

The NotNull method takes an Expression. Because of that, our lambda expression will be turned into an expression tree. That expression tree has one node in it, which is a member expression asking for the value of the “firstName” member. (Why is it a member instead of a parameter? Because C# is generating a closure here and capturing the local variable named “firstName” into the closure. Under the hood, this becomes a class with a member named “firstName”. Our lambda expression is then an expression which asks for the value of that field, which means it is a member expression. And then that expression is turned into an expression tree).

The upshot is that we have no strings, but the helper code can obtain and use the string. Very nice!

You can find more about this here.

Blog at WordPress.com.