core
core

Reputation: 33059

C#: Argument validation: null/empty strings

I don't know how many countless times I've had to write code to validate string arguments:

public RoomName(string name)
{
    if (string.IsNullOrEmpty(name))
    {
        throw new ArgumentException("Cannot be empty", "name");
    }
}

Is there anyway to avoid this? Is there some attribute or design-by-contract mechanism to avoid this? Is there no way to say:

public RoomName(NotNullOrEmptyString name)
{

without having to actually create that type?

Upvotes: 18

Views: 9411

Answers (3)

Wim.van.Gool
Wim.van.Gool

Reputation: 1330

Though the question has been answered a while ago, I have been thinking about the same problem lately. Formalized code contracts (with automatic verification or checks) seem to be a good idea, but generally, their verification-capability is quite limited, and for simple checks like null- or empty-string checking, they require just as much code (or more) than the old-fashioned checks.

Ironically, the best answer in my opinion for the string-case is indeed one or two classes that wrap a string that has been checked not to be null, empty or white-space, and pass this instance around:

public class NonEmptyString : IComparable<NonEmptyString>, ...
{
    private readonly string _value;

    public NonEmptyString(string value)
    {
        if (value == null)
        {
            throw new ArgumentNullException("value");
        }
        if (value.Length == 0)
        {                
            throw NewStringIsEmptyException("value");
        }
        _value = value;
    }

    public string Value
    {
        get { return _value; }
    }

    ...
}

public class NonWhiteSpaceString : NonEmptyString
{
    ....
}

Sure, passing around these instances does not prevent you from having to check if they are null themselves, but it's got some big advantages:

  • You don't have to check on empty or white-space strings over and over again, which can be error prone in situations where the string is passed around a lot.
  • As I have done in my implementation, checking for null is something different than checking for an empty value (or whitespace value), because you want to throw a specific ArgumentNullException in the former case, and some ArgumentException in the second.
  • It clearly signals the constraint on the value of the string, just like any wrapping class is supposed to do. In fact, if you have a string that has any constraints and it is passed around a lot, I always recommend to wrap it in a class that encapsulates the check and keeps the rest of the code out of trouble. A good example of this are strings that must satisfy a certain regular expression. However, I'm diverting from the question here...

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564393

You can do that via code injection with attributes.

Another option to save some coding time, but still give you a lot of control, would be to use something like CuttingEdge.Conditions. This provides a fluent interface for argument checking, so you can write:

name.Requires().IsNotNull();

Upvotes: 7

Robert Harvey
Robert Harvey

Reputation: 180787

See also C#: How to Implement and use a NotNull and CanBeNull attribute for more information on Code Contracts, how they can be implemented today in VS2008, and how they will be integrated into VS2010.

Upvotes: 0

Related Questions