【问题标题】:A simple undo/redo system for C# POCOs [closed]C# POCO 的简单撤消/重做系统 [关闭]
【发布时间】:2014-01-20 07:56:47
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 您不应该为 POCO 本身考虑撤消/重做;您应该考虑为它们所代表的状态撤消/重做。你到底想达到什么目的?
  • 您可能正在寻找 Memento 模式,请看这里:stackoverflow.com/questions/8994433/…
  • @Ant P - 我将 POCO 用于应用程序内的主要数据。如果我可以撤消/重做对 POCO 所做的更改,那么之后我可以相当轻松地更新 GUI。
  • 我仍然说你的做法是错误的 - 应用程序功能的跟踪更改属于in你的POCO,而不是存档您的 POCO。再说一次,你想达到什么目的?你的问题太抽象了。
  • CSLA.NET Framework 具有一个 UndoableBase 类,可以处理撤消,并且可以轻松修改以进行重做,即使您不使用它也值得一试。

标签: c# poco history undo-redo


【解决方案1】:

一个可能的高级方法:

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

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

【讨论】:

  • 这个代码项目库做了类似的事情,减去代码生成/IL。您基本上将每个属性包装在 UndoRedo<> 标记中,并且系统会基于每个属性记录更改。 codeproject.com/Articles/19550/…
猜你喜欢
  • 1970-01-01
  • 2011-04-02
  • 1970-01-01
  • 2014-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-17
相关资源
最近更新 更多