undo
如何运作?每次任何值更改时,它是否复制所有托管对象?或者它是否仅将实际更改与对象受影响的信息一起复制?是重型还是轻量级?
答案 0 :(得分:2)
几乎任何支持面向对象构造的语言的“撤销”机制都使用Memento Design Pattern来实现它。
答案 1 :(得分:1)
这是一个让你思考的粗略实现。这将处理您的可撤消操作堆栈。 (它不处理重做,但通过用列表替换堆栈并跟踪当前项目,可以很容易地支持重做。)
public class Undoable {
public static void Do(Action do, Action undo) {
do();
sUndoStack.Push(new Undoable(do, undo));
}
public static void Undo() {
sUndoStack.Pop().mUndoCallback();
}
private Undoable(Action doCallback, undoCallback) {
mDoCallback = doCallback;
mUndoCallback = undoCallback;
}
private Action mDoCallback, mUndoCallback;
// note: using a global stack here is lame, but works for demo purposes
private static readonly Stack<Undoable> sUndoStack = new Stack<Undoable>();
}
要使用它,假设用户可以更改某个对象中的值,如下所示:
public class Foo {
public string Bar {
get { return mBar; }
set {
if (mBar != value) {
mBar = value;
}
}
}
private string mBar;
}
要使该操作可撤消,我们只需将setter更改为:
set {
if (mBar != value) {
string oldValue = mBar;
Undoable.Do(() => mBar = value,
() => mBar = oldValue);
}
}
现在,如果您从应用程序的任何位置调用Undoable.Undo(),您的Foo实例将恢复之前的Bar值。如果Foo也在Bar更改时引发事件(此处未显示),则UI也将在撤消时正确刷新。