Ruud Poutsma Ruud Poutsma - 28 days ago 20
C# Question

C# Immutable & Mutable types without duplication

Given the following implementation of mutable and immutable types, is there a way to avoid duplicate code (mainly the duplicate properties)?

I'd like to work with immutable type by default unless a mutable type is required (e.g. when binding to UI elements).

We're using .NET framework 4.0, but plan switching to 4.5 soon.

public class Person {
public string Name { get; private set; }
public List<string> Jobs { get; private set; } // Change to ReadOnlyList<T>
public Person() {}
public Person(Mutable m) {
Name = m.Name;
}
public class Mutable : INotifyPropertyChanged {
public string Name { get; set; }
public List<string> Jobs { get; set; }
public Mutable() {
Jobs = new List<string>();
}
public Mutable(Person p) {
Name = p.Name;
Jobs = new List<string>(p.Jobs);
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName) {
// TODO: implement
}
}
}

public class Consumer {
public Consumer() {
// We can use object initializers :)
Person.Mutable m = new Person.Mutable {
Name = "M. Utable"
};
// Consumers can happily mutate away....
m.Name = "M. Utated";
m.Jobs.Add("Herper");
m.Jobs.Add("Derper");

// But the core of our app only deals with "realio-trulio" immutable types.

// Yey! Have constructor with arity of one as opposed to
// new Person(firstName, lastName, email, address, im, phone)
Person im = new Person(m);
}
}

Answer

No, there's no easy way to avoid duplicate code.

What you've implemented is effectivly the builder pattern. The .NET StringBuilder class follows the same approach.

The support for immutable types in C# is a bit lacking, and could do with some language specific features to make it easier. Having to create a builder is a real pain, as you've discovred. An alternative is to have a constructor that takes all the values, but you tend to end up with the mother of all constructors, which makes the code unreadable.

Comments