What tools/libraries exist that will take a struct and automatically generate an immutable wrapper and also a "builder" class for incrementally building new instances?
Example input:
struct Foo
{
    public int apples;
    public int oranges;
    public Foo Clone() {return (Foo) base.MemberwiseClone();}
}
Example output:
public class ImmutableFoo // could probably be a struct
{
    private Foo snapshot;
    internal ImmutableFoo(Foo value) { this.snapshot = value; }
    public FooBuilder Builder() { return new FooBuilder(snapshot); }
    public int Apples { get { return snapshot.apples; } }
    public int Oranges { get { return snapshot.oranges; } }
}
public class FooBuilder
{
    private Foo state;
    public int Apples { get { return state.apples; } set { state.apples = value; } }
    public int Oranges { get { return state.oranges; } set { state.oranges = value; } }
    public FooBuilder() { }
    internal FooBuilder(Foo toCopy) { state = toCopy.Clone(); }
    public ImmutableFoo Build()
    {
        ImmutableFoo result = new ImmutableFoo(state);
        state = state.Clone();
        return result;
    }
}
Such a "tool" could be an IDE plugin or could generate the new class at run-time using reflection.
The example is in C# but I would be interested in a solution for any statically-typed OO language (Java, Scala, C++ etc.)
Desirable features:
- Re-creates methods from the struct in the builder class
- Re-creates nondestructive methods from the struct in the immutable class (esp. Equals()andGetHashCode()and any interface methods)
- Also generates a IFooReaderinterface containing read-only properties for each struct member, implemented by both the immutable and the builder.
- If a field's class has an immutable equivalent, uses the immutable version in the immutable class (see also How do I create a builder in C# for an object that has properties that are referenc types?) e.g. List->ReadOnlyCollectionor similar.
- Alternatively take the builder class as input (where the builder uses automatic properties instead of delegating to a struct.)
- Does not require the Clonemethod to be predefined
"You should not use a tool like this because..." answers are also welcome.
 
     
     
    