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:
Equals()
and GetHashCode()
and any interface methods)IFooReader
interface containing read-only properties for each struct member, implemented by both the immutable and the builder.List
-> ReadOnlyCollection
or similar.Clone
method to be predefined"You should not use a tool like this because..." answers are also welcome.
Here are four possible solutions.
1) Use CodeDOM to generate C# or VB code. This would also allow you to use visual studio extensions to generate your code in designer files. Similar to some of the built in tools that visual studio already offers - like the ones that generate wrappers for web service calls etc. Unfortunately I don't know much about extending Visual Studio.
2) Use the Mono.Cecil library to analyze your assembly post-build. You can then re-write the assembly with the new types included.
3) Use PostSharp. I don't know as much about this library so you might not be able to add new types to your assembly but I know you can inject IL into methods. It also has a lot of nice stuff that makes it easy to do this with attributes. So you could do this -
[GenerateImmutable]
struct Foo
{
public int apples;
public int oranges;
public Foo Clone() {return (Foo) base.MemberwiseClone();}
}
4) Use built in Reflection.Emit libraries to generate a new assembly with your immutable types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With