c# - 用于 C# POCO 的简单撤消/重做系统

标签 c# poco history undo-redo

<分区>

我在内存中为每种类型的数据使用 POCO(类对象)。我有一组 myraid 函数可以对这些函数进行操作并以不同的方式修改它们。在对代码进行最少更改的情况下实现撤消/重做功能的简单方法是什么?一些想法:

  • 使用 ORM 记录更改 - Property-level logging - 修改 POCO 的方法应该记录他们修改的每个属性,或者通过 ORM 修改属性而不是直接在所述 POCO 上操作。 ORM 将记录更改并能够在需要时恢复。

  • 深度克隆和差异化 - Memento pattern - 在修改对象之前保存对象的深度克隆(浪费内存,速度慢)。修改完成后,调用一个计算对象属性差异的函数(必须遍历所有 props,缓慢、乏味、递归)。差异存储在日志中,以便日后恢复。

  • 每个命令都支持撤消/重做 - Command pattern - 经典方法,但需要对代码添加太多内容。我正在寻找通用的东西,最好是不需要从头开始重写应用程序的东西。

我不知道解决这类问题的典型方法,但考虑到它相当普遍,我确信有很好的模式可以轻松解决这个问题。您是否知道以简单方式处理 POCO 历史记录的任何模式/库?

我目前正在审查以下内容,但仍在寻找更好的方法。

最佳答案

一种可能的高级方法:

  1. virtual 标记您的 POCO 属性
  2. 将对象实例化请求重定向到所述类的自定义工厂(如果您已经在使用依赖注入(inject),这很容易)
  3. 您的自定义工厂第一次收到一个目标类的实例化请求时,使用反射发出一个覆盖目标属性的新类(可能用自定义 [UndoRedo] 属性装饰? )
  4. 重写的 set{} 实现将识别更改,并创建一个更改识别对象(仅识别属性、对象引用和旧值),该对象被推送到您的更改堆栈中。然后调用基类的set方法。可能需要在 IL 中编写一些代码。
  5. 要撤消更改,请将更改标识符从堆栈中弹出,然后使用您喜欢的方法将旧值应用于给定对象引用的给定属性

结果是受支持类的消费者不会注意到任何差异(对象创建除外,请参阅第 2 步)。

关于c# - 用于 C# POCO 的简单撤消/重做系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21228771/

相关文章:

c# - 在分层数据结构中添加对 MVVM 的编辑

c# - 不同语言的总结 C#

c++ - 使用 OpenWRT 工具链为 OpenWRT Linux 环境交叉编译 POCO 库

c# - 使用 Entity Framework 4 对字段进行自定义序列化/反序列化

linux - 为什么我不能用这个循环从 bash 历史记录中删除多个条目

search - 如何搜索 MATLAB 命令历史记录?

c# - 如何通过反射获取成员的类型?

entity-framework - Entity Framework 服务层更新 POCO

c - long 和 int 通常大小相同的历史背景是什么?

c# - Webforms 中是否有一种方法可以在页面加载时判断回发是由 Ajax 请求引起的还是由常规的完整回发引起的?