Thursday, February 02, 2006

A good way to create a custom Value-Type object in C#?

Have you ever written code like this?

State state = new State("AZ");
Money money = new Money(299.95);
 
State state = State.Parse("AZ");
Money money = Money.Parse(299.95);

How many domain-specific Value Type classes (you care about equality but not identities) have you been creating every project? The question of should I use the "new" keyword or a static .Parse() method to create them is always a coding consistency problem.

What if I tell you that you can do this in C#:

State state = "AZ";
Money money = 299.95;

Simple and clean. Here's how:

public class State
{
    private readonly string _state;
 
    private State(string state)
    {
        _state = state;
    }
 
    public static implicit operator State(string state)
    {
        return new State(state);
    }
}

5 comments:

Bil Simser said...

Great post! This is a much more readable way for me to create value objects, and provides that code consistency that is always good.

Anonymous said...

Hi, nice post, although when i checked my source for value-types where i could implement this feature, i couldn't find many places, as most of my value-types have more than one property: my Money has Value and Currency for example.
Of course you could make one currency the "default", but i think that would not do any good to the clarity of the code. But still, thanks for posting this trick, i'm sure it'll come in handy one day.

Anonymous said...

How can i retrieve the value even if have only one property.

The member varibale should be accesses using fully qualified name right.

Like state.state.

Stephen Chu said...

Sure. I can think of a value object like Address may have something like:
+ Address1
+ Address2
+ State
+ City
+ ZipCode

Because of the fact that they are value objects, you should also override their Equals() and GetHashCode(), cos we care about their equalities and not identities.

However, you truly have to think about why you need to look at the value of your State object. There is a big difference between doing:
if (aState.Value == texasState.Value)
versus
if (aState.IsSouthernState)
The difference being encapsulation, making your objects truly smart objects who knows the most about their states. Otherwise, a simple ToString() will do just fine.

Nguyen Manh said...
This comment has been removed by a blog administrator.