views:

169

answers:

8

Hi,

We use the .NET 2.0 framework with C# 3.0 (I think it's the last version of C# which can run on the 2.0 version of the framework, correct me if I am wrong).

Is there something built into C# which can make this type of parameter validation more convenient?

public ConnectionSettings(string url, string username, string password,
                          bool checkPermissions)
{
    if (username == null) {
        throw new ArgumentNullException("username");
    }

    if (password == null) {
        throw new ArgumentNullException("password");
    }

    if (String.IsNullOrEmpty(url)) {
        throw new ArgumentException("Must not be null or empty, it was " +
            (url == null ? url : "empty"), "url");
    }

    this.url = url;
    this.username = username;
    this.password = password;
    this.checkPermissions = checkPermissions;
}

That sort of parameter validation becomes a common pattern and results in a lot of "almost boilerplate" code to wade through in our public methods.

If there is nothing built in. Are there any great free libraries which we could use?

+2  A: 

You can do it using contracts but it is the same concept.

This should be good practise anyhow, because it clearly shows what are mandatory fields on a public method.

Datoon
+2  A: 

It's not build into the .Net Framework but you can use Fluent Argument Validation

Giorgi
A: 

You can use OOP concepts to help yourselves and organize those parameters into a single class which could also contain a method (or several) which would perform the validation. Your code would be less boilerplate-ish and more organized that way.

Your public methods could then look something like:

public ConnectionSettings(ConnectionInfo connInfo)
{
    connInfo.Validate();

....

Where ConnectionInfo contains all those parameters as members and a method like:

public void Validate()
{
    if (this.username == null) {
        throw new ArgumentNullException("username");
    }

    if (this.password == null) {
        throw new ArgumentNullException("password");
    }

    if (String.IsNullOrEmpty(this.url)) {
        throw new ArgumentException("Must not be null or empty, it was " +
            (this.url == null ? this.url : "empty"), "url");
    }
}
Paul Sasik
The cure is worse than the problem.
Ben Voigt
@Ben: Would mind explaining how? I fail to see how organizing the code into a single class is actually worse than passing and validating the same set of arguments within a bunch of public methods?
Paul Sasik
(1) It makes the caller's code longer. (2) It makes the implementer's code longer. (3) The parameter validation code is just as long as before, especially you still have parameter names in strings.
Ben Voigt
+3  A: 

Here's a nice fluent way of doing this.

http://stackoverflow.com/questions/271398/what-are-your-favorite-extension-methods-for-c-codeplex-com-extensionoverflow/271409#271409

public static class Extensions
{
        public static void ThrowIfArgumentIsNull<T>(this T obj, string parameterName) where T : class
        {
                if (obj == null) throw new ArgumentNullException(parameterName + " not allowed to be null");
        }
}

internal class Test
{
        public Test(string input1)
        {
                input1.ThrowIfArgumentIsNull("input1");
        }
}
this. __curious_geek
Giorgi already mentioned this method. Also... you still have that ugly string with the parameter name in it.
Ben Voigt
+4  A: 

I normally create static helper methods...

E.g.

public static void CheckNotNull(object value, string parameterName)
{
   if(value == null) { throw new ArgumentNullException(parameterName); }
}

Means you can condense your code down to something similar to below and just makes it a little tidier.

CheckNotNull(username, "username");
CheckNotNull(password, "password"); 

Or you can wrap it up as an extension method:

public static void CheckNotNull<T>(this T value, string parameterName)
{
   if(value == null) { throw new ArgumentNullException(parameterName); }
}

And use like:

username.CheckNotNull("username");
password.CheckNotNull("password");

And if you're feeling really fancy, you could probably interrogate the parameter names by using reflection. Reflection's kinda slow, so you'd only do this if you were going to throw an exception, but it saves you typing the literal parameter name all the time.

Ian
Still requires putting the parameter name in a string (which you've conveniently left out).
Ben Voigt
Ben, indeed that was a mistake but fixed before the downvote.
Ian
And I undid the downvote now that I see you've fixed it.
Ben Voigt
Thanks Ben. I've also added a comment about reflection, I'm not sure how to implement it off the top of my head, but should provide a neat solution if it's dooable and solve the whole nasty string problem.
Ian
You can't, with that syntax. You need an expression tree. For example http://stackoverflow.com/questions/1608714/how-to-avoid-argument-validation
Ben Voigt
Oops, wrong URL on my clipboard. I meant to link http://charlieflowers.wordpress.com/2009/04/01/elegant-appealing-parameter-validation-syntax-in-c-30/
Ben Voigt
I like that link, thanks for that (it's probably something I'll use in my own code). You can get part of the way using Reflection, but I think you might be right, can't quite get all the way. If you get the last frame on the stack you can grab a method info. From that you can get a set of ParameterInfo's which include names. It's just figuring out which one was passed to you :/
Ian
+2  A: 

Similar idea to fluent parameter validation as mentioned by Giorgi, but this one avoids redundantly naming the parameter, and the strings that can't be automatically updated by code refactoring tools.

http://charlieflowers.wordpress.com/tag/parameter-validation/

Ben Voigt
+4  A: 

You could use an il weaver like Post Sharp, keep in mind that compiler as a service in C# 5 will make this kind of stuff built in.

Personally I would not recommend this approach unless the problem is huge and must be tackled. Usually a few asserts and checking preconditions as you described above is a best practice.

EG:

public ConnectionSettings(
   [NotNullOrEmpty] string url, 
   [NotNull] string username, 
   [NotNull] string password,
   bool checkPermissions)
{
    this.url = url;
    this.username = username;
    this.password = password;
    this.checkPermissions = checkPermissions;
}

You could also integrate this kind of stuff with code contracts which would allow you to perform some rich static analysis.

Sam Saffron
+1  A: 

Just to add to Sam's answer above, here's a link which tells you how you can go about implementing such attributes with PostSharp:

http://dpatrickcaldwell.blogspot.com/2009/03/validate-parameters-using-attributes.html

theburningmonk