实施撤销/重做使用MemberwiseClone [英] Implementing undo/redo using MemberwiseClone

查看:303
本文介绍了实施撤销/重做使用MemberwiseClone的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现我正在一个对象恢复到以前的状态时调用undo,工作的一个C#应用程序的撤销/重做堆栈。我有一个操作类,这基本上是这样的:

I'm trying to implement an Undo/Redo stack in a C# application that I'm working on by restoring an Object to a previous state when undo is called. I have an 'Action' class which looks basically like this:

class Action
{
    object old_state;
    object new_state;

    public Action(object old)
    {
        old_state = old;
    }

    public void finish(object new_obj)
    {
        new_state = new_obj;
    }

    public void reverse()
    {
        new_state = old_state;
    }
}

当一个动作开始可以重做,一创建新的动作。当我们到达新的状态,完成()被调用。当用户想重做的东西,它的反向调用()和恢复对象到其原始状态。

When an action is started that can be redone, a new action is created. When we reach the new state, finish() is called. When the user wants to redo something, it calls reverse() and restores the Object to its original state.

显然,这并不工作,因为这两个对象是通过引用传递和对象只是在新状态结束。

Obviously this doesn't work since both objects are passed by reference and the object just ends up in the new state.

我真正想要做的是能说:

What I really want to do is to be able to say:

public Action(object old)
{
    old_state = old.MemberwiseClone();
}



不幸的是,这并不工作,我也得到了看起来像一个错误

unfortunately, this doesn't work, and I get an error that looks like:

无法通过类型'foo.object

Cannot access protected member 'object.MemberwiseClone()' via a qualifier of type 'foo.object'

我要创建的原始状态(复制所有值的价值领域和所有引用的参考场)的浅表副本,但我可以T弄清楚如何做到这一点使用通用的对象,而不是在每一个类的我可能要恢复状态实施 IClonable

I want to create a shallow copy of the original state (copy all of the value fields by value and all of the reference fields by reference), but I can't figure out how to do this using generic objects, as opposed to implementing IClonable in every class of which I could possibly wish to restore the state.

任何人都可以提供任何见解?

Can anyone offer any insight?

推荐答案

您可以使用克隆对象的这个版本(注:对象必须要使用此功能)可序列化的:

You could use this version of cloning an object (Note: The object must be serializable in order to use this function):

  /// <summary>
  /// Clones Any Object.
  /// </summary>
  /// <param name="objectToClone">The object to clone.</param>
  /// <return>The Clone</returns>
  public static T Clone<T>(T objectToClone)
  {
     T cloned_obj = default(T);
     if ((!Object.ReferenceEquals(objectToClone, null)) && (typeof(T).IsSerializable))
     {
        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bin_formatter = null;
        Byte[] obj_bytes = null;

        using (MemoryStream memory_stream = new MemoryStream(1000))
        {
           bin_formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
           try
           {
              bin_formatter.Serialize(memory_stream, objectToClone);
           }
           catch (Exception) { }
           obj_bytes = memory_stream.ToArray();
        }

        using (MemoryStream memory_stream = new MemoryStream(obj_bytes))
        {
           try
           {
              cloned_obj = (T)bin_formatter.Deserialize(memory_stream);
           }
           catch (Exception) { }
        }
     }
     return cloned_obj;
  }

这篇关于实施撤销/重做使用MemberwiseClone的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆