最聪明的方法是使用不可变的持久对象。永远不要对对象进行更改,只创建与旧版本略有不同的新对象。这可以通过仅克隆热路径上的部分树来稍微有效地完成。
我有一个用最少的代码编写的撤消堆栈示例
[Fact]
public void UndoStackSpec()
{
var stack = new UndoStack<A>(new A(10, null));
stack.Current().B.Should().Be(null);
stack.Set(x => x.B, new B(20, null));
stack.Current().B.Should().NotBe(null);
stack.Current().B.P.Should().Be(20);
stack.Undo();
stack.Current().B.Should().Be(null);
}
其中 A 和 B 作为具有private setters
所有属性的类,即
immutable
class A : Immutable
{
public int P { get; private set; }
public B B { get; private set; }
public A(int p, B b)
{
P = p;
B = b;
}
}
class B : Immutable
{
public int P { get; private set; }
public C C { get; private set; }
public B(int p, C c)
{
P = p;
C = c;
}
}
class C : Immutable
{
public int P { get; private set; }
public C(int p)
{
P = p;
}
}
你可以在这里找到完整的源代码https://gist.github.com/bradphelan/5395652