views:

190

answers:

2

Trying to do TDD against FluentValidation and Looking for the proper way to represent a list of US States.

For example, I have an "Address" object.

I would like to write a test (and a FluentValidation rule) that declares the address invalid if it's not in a list of US States.

This is a finite list, only to include the 50 US States, so I think it should be something constant and not represented in a database.

What I'm wondering is, what is the most efficient way to store and validate/test against this? An enum, an array, a list object, what?

+1  A: 

I'd go with keeping them in a constant string array...

//Define the constant array
const String[] TheStates = new String[] { "Alabama", "Arizona", ... };

//fluentvalidation rule
RuleFor(address => address.State).Must(theState => TheStates.Contains(theState));

Keeping them in an Enum would require some association between the state name and an integer value - it just doesn't sound as efficient. Or you'd have to use ToString() a lot or build some custom attribute for each item in your enum (I've seen a few examples of this - but then you're dealing with reflection, which isn't as performant).

I would consider a List only if you need some additional data with each state (e.g. Full Name, Abbreviation, Date Admitted, etc.).

Go with the simplest format that you can.

Hope this helps.

David Hoerster
The first line of the example won't work in c#. You'll get this error: **A const field of a reference type other than string can only be initialized with null.**
code4life
+1  A: 

Use a static readonly array or HashSet.

A state can be represented by it's full name or it's abbreviation. Do you want to check for both? Also, a state can be validated by a zip code (I'm not sure if you want to do that though).

You could possibly have a static readonly single-array or a hashset containing both the full name and abbreviation, like this:

public static readonly string[] listOfStates = new string[]
    {
        "New York",
        "NY",
        // rest of states & abbreviations here...
    };

or

public static readonly HashSet<string> listOfStates = new HashSet<string>
    {
        "New York",
        "NY",
        // rest of states & abbreviations here...
    };

Both support the Contains syntax:

// Queryable like this:
bool stateMatch = listOfStates.Contains(stringValue);
code4life