最聰明的方法是使用不可變的持久對象。不要對對象進行更改,只會使新對象與舊版本稍有變化。這可以通過在熱路徑上克隆部分樹來有效地完成。
我用最少的代碼編寫的撤消堆棧的例子
[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