Last week I discovered a rather wonderful construct for objects with long constructors, e.g. immutable value types:
public class UserProfile
{
public string City { get; protected set; }
public string Country { get; protected set; }
public Uri Url { get; protected set; }
public string Email { get; protected set; }
public string Tagline { get; protected set; }
public UserProfile(string city, string country, Uri url, string email,
string tagline)
{
...
}
}
This constructor has bad Connascence of Position (CoP); to construct a UserProfile instance, users have to know the position of each parameter. Otherwise they might mix up the city with the country for example:
// Spot the bug!
var profile = new UserProfile("NZ", "Wellington",
new Uri("http://richarddingwall.name"), "rdingwall@gmail.com", ".NET guy");
This won’t be a problem with named parameters in C# 4.0, but until then, a nice alternative is a fluent builder class as described here:
UserProfile profile = new UserProfileBuilder()
.WithCity("Wellington")
.WithCountry("NZ")
.WithUrl(new Uri("http://richarddingwall.name"))
.WithEmail("rdingwall@gmail.com")
.WithTagline(".NET guy");
Builders are very easy to implement. Each With method records its value and returns the current builder instance. Then we provide an implicit cast operator that finally constructs a UserProfile with all the parameters in the right places.
public class UserProfileBuilder
{
internal string City { get; set; }
internal string Country { get; set; }
// ... etc
public UserProfileBuilder WithCity(string city)
{
this.City = city;
return this;
}
// ... etc
public static implicit operator UserProfile(UserProfileBuilder builder)
{
return new UserProfile(builder.City, builder.Country, builder.Url,
builder.Email, builder.Tagline);
}
}
I really like this!
June 1st, 2009 | 5 Comments



June 1st, 2009 at 4:25 pm
Be aware that in your “With” example, the var will get confused and you will have a UserProfileBuilder instead of a UserProfile. You need to use an explicit type declaration.
June 1st, 2009 at 4:32 pm
@John whoops! Good spotting… fixed.
June 1st, 2009 at 5:08 pm
I only know this because I saw someone else post this pattern and I thought it was amazingly badass so I happened to remember that pitfall.
June 3rd, 2009 at 11:15 pm
You could still use var, if you have a:
public UserProfile Build() member.
Your public static implicit operator UserProfile member could implement Build() to keep it nice and DRY?
June 4th, 2009 at 7:45 am
@Ed: after a couple of weeks using this I’m inclined to agree. We’ve discovered the static operators aren’t much good for subclassed builders (e.g. AdminUserBuilder) because they cannot be inherited/overriden.