Last week I discovered a rather wonderful construct for objects with long constructors, e.g. immutable value types:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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:
|
1
2
3
|
// Spot the bug!var profile = new UserProfile("NZ", "Wellington", |
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:
|
1
2
3
4
5
6
|
UserProfile profile = new UserProfileBuilder() .WithCity("Wellington") .WithCountry("NZ") .WithUrl(new Uri("https://richarddingwall.name")) .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.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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!
