Skip to content

Instantly share code, notes, and snippets.

@yreynhout
Last active December 17, 2015 10:59
Show Gist options
  • Save yreynhout/5598805 to your computer and use it in GitHub Desktop.
Save yreynhout/5598805 to your computer and use it in GitHub Desktop.
public class ImmutableXYZ {
public ImmutableXYZ() {
abc = "";
def = 0;
haha = -1;
}
ImmutableXYZ(string abc, int def, int haha) {
this.abc = abc;
this.def = def;
this.haha = haha;
}
public ImmutableXYZ WithABC(string value) {
return new ImmutableXYZ(value, DEF, haha);
}
public ImmutableXYZ WithDEF(int value) {
return new ImmutableXYZ(ABC, value, haha);
}
public ImmutableXYZ WithHaha(int value) {
return new ImmutableXYZ(ABC, DEF, value);
}
public string ABC {
get { return abc; }
}
public int DEF {
get { return def; }
}
readonly int haha;
readonly string abc;
readonly int def;
}
public class ImmutableXYZ {
public ImmutableXYZ() {
ABC = "";
DEF = 0;
haha = -1;
}
ImmutableXYZ Clone() {
return new ImmutableXYZ {
//DeepCopy or ShallowCopy here
};
}
ImmutableXYZ Clone(Action<ImmutableXYZ> configure) {
var clone = Clone();
configure(clone);
return clone;
}
public ImmutableXYZ WithABC(string value) {
return Clone(_ => _.ABC = value);
}
public ImmutableXYZ WithDEF(int value) {
return Clone(_ => _.DEF = value);
}
public ImmutableXYZ WithHaha(int value) {
return Clone(_ => _.haha = value);
}
public string ABC { get; private set; }
public int DEF { get; private set; }
private int haha;
}
@ploeh
Copy link

ploeh commented May 17, 2013

That's not immutable - it only looks that way :)

This is immutable, shorter, and simpler :p

@yreynhout
Copy link
Author

Yeah, I know that, which is why I added the classical way as well.

@yreynhout
Copy link
Author

Upon reflection the question becomes: immutable for whom? The caller or the class maintainer? Yes, the convenience approach (or more generally speaking the "my fields are still mutable" approach) requires more discipline from the class maintainer (i.e. added cognitive load of the 'don't mutate fields beyond the "construction"' phase). I agree that what I initially suggested is not immutable from a C# language perspective. But frankly the thing we are afraid of at that point is the next, less savvy developer. Yes, readonly fields communicate their intent better and maybe the runtime caters for them in a special way. But unless I look into the class's code I'm not gonna notice any difference. So ... what am I trying to say? I donnow, maybe that I'm wrong from the perspective of what is generally considered immutable. Since the number of fields in value objects (not talking about value types) is usually limited, the technique I've shown could be perceived as overengineering. Maybe it is. I was getting tired of repeating each field on the way to the copy ctor. That was my motivation for this approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment