如何获取备份列表?

问题描述

我想为撤消/重做制作备份列表, 但是我修改了原List中的对象后,BackUp List中的对象就会发生变化。 我该如何处理这个问题? “const”、“in”似乎不起作用。

private List<geminiFileStruct> BackUpForUndoRedo(List<geminiFileStruct> gfl,ToolStripMenuItem tm)
        {
            var li =
                (from i in gfl
                select i).ToList();
            tm.Enabled = true;
            return li;
        }

抱歉,以前是结构体。引起一些问题,我换班。 struct 可以有 Get/Set 吗??? C# 的新手。

解决方法

您需要的是列表的所谓深拷贝

备份列表中的项目将是原始项目的克隆 列表。具有相同属性的全新项目实例。

不是浅拷贝

“仅”引用原始列表中项目的备份列表。这会导致 将备份列表中的A项更改为备份列表中的A项 原始列表,因为它们引用了相同的项目?。

查看 this SO post 或以下任何网页:tutorial 1tutorial 2

深度复制不是一种简单的编程技术,正如您会发现的那样。但在正确的上下文中,在正确的假设下,它可以安全地完成。

注意

正如@Llama 指出的那样,在执行 new List<TStruct>(originalListWithStructs) 时,自动 获得了具有结构的列表的深层副本。 Struct 是一种值类型,与引用类型相比表现不同。

,

虽然 Bernoulli IT 描述了使用浅拷贝的实际问题,但我想为撤消/重做提供更多背景知识。撤销/重做有两种主要方法

  1. Memento pattern。在对对象进行更改之前,会创建一个备忘录,可用于恢复所述对象的状态。这可以应用于整个应用程序,即在任何更改之前,应用程序状态被序列化,就像用户保存到文件一样。然后可以恢复此序列化状态,就像加载文件时一样。假设有一个函数可以保存到文件,并且这表示应用程序状态。请注意,序列化/反序列化会隐式地创建一个深拷贝。

  2. Command pattern。每个更改都应该由一个命令完成,该命令知道如何撤消更改。这样做的一个缺点是,确保所有操作都正确生成这些对象可能会很复杂。