How will you make it if you never even try?

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.

Advertisements

4 Comments »

  1. […] 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 …. […]

    Pingback by Some more good ideas about parameter validation in C# « Blog of Charlie Flowers in Atlanta — April 2, 2009 @ 6:20 am

  2. Wow, this was a really quality post. In theory I’ d like to write like this too – taking time and actual effort to make a great article… but what can I say… I procrastinate alot and in no way appear to get something done.

    Comment by blue dolphin pools — August 19, 2010 @ 11:34 pm

    • Dude … I had no idea how thrilled I would be to receive a complement about one of my blog entries. Thanks.

      Comment by charlieflowers — August 20, 2010 @ 3:55 am

  3. Hi, this is a very interesting blog page and ive enjoyed reading many of the articles and posts contained on the website, keep up the good work and hope to read some more interesting content in the future.

    Comment by Telefony — October 6, 2010 @ 4:20 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: