最聪明的方法是使用不可变的持久对象。不要对对象进行更改,只会使新对象与旧版本稍有变化。这可以通过在热路径上克隆部分树来有效地完成。
我用最少的代码编写的撤消堆栈的例子
[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
所以,你会做一个文本框的扩展版呢?实现该接口? – Svish 2009-02-28 12:19:47
需要多少级别的撤销才能需要n级或1级?撤消行为是否在对象上或仅在文本框的数据上? – 2009-02-28 13:57:02