C# 我需要深度拷贝吗?

C# 我需要深度拷贝吗?,c#,winforms,C#,Winforms,我有一个对象列表,比如list barlist。这些Barorbjects相当复杂,我很乐意继续使用,而不需要深入复制它们 但是,我希望允许用户使用BindingSource、BindingNavigator和DataGridView修改它们。但是,如果我将DataSource设置为my barlist并修改值,则BindingSource会修改我的列表(因为它显然不保存自己的列表,或者只使用浅拷贝) 问题是:如果用户想要放弃他的更改怎么办?如果我给BindingSource一个深度复制的列表,

我有一个对象列表,比如
list barlist
。这些
Bar
orbjects相当复杂,我很乐意继续使用,而不需要深入复制它们

但是,我希望允许用户使用
BindingSource
BindingNavigator
DataGridView
修改它们。但是,如果我将
DataSource
设置为my barlist并修改值,则
BindingSource
会修改我的列表(因为它显然不保存自己的列表,或者只使用浅拷贝)

问题是:如果用户想要放弃他的更改怎么办?如果我给
BindingSource
一个深度复制的列表,我将不得不手动还原它们,或者不将它们应用于原始列表。然而,我希望避免深度复制

有没有别的办法?或者,我别无选择,只能将对象标记为可序列化,并对其进行深度复制?

我建议使用


您基本上需要创建一个单独的对象,该对象可以将每个条的状态恢复到用户开始编辑之前的状态。这通常比深度复制更简单,成本更低。

为了记录,我使用了以下深度克隆功能来解决这个问题。这可能不是最好的解决方案,但它已经足够了,并且工作得很好(即使只适用于可序列化对象)

//创建对象的深度副本
公共静态T深克隆(T obj)
{
使用(var ms=new MemoryStream())
{
var formatter=新的二进制格式化程序();
序列化(ms,obj);
ms.Position=0;
返回(T)格式化程序。反序列化(ms);
}
}

Mementos仍然需要克隆作为初始状态保存的数据,如果它是一个对象而不是不可变的类型。是的,但是一些对象数据可能不相关,或者可以使用其他方法(例如,Bar对象上的方法)还原。在这种情况下,Memento仍然比深度复制好。这可能会奏效,但我仍然必须至少保存一次整个列表。如果不付出很大努力,则无法加载/重建数据。我想我会使用深度拷贝。我不太清楚你的问题,所以不能给出一个真正的答案,但你考虑过单向绑定。如果这不起作用,我会调查外汇管理公司。我认为这也没有帮助。“你很可能被困在深度复制中了。”菲利普斯·科特吉文斯的单向绑定听起来很有趣。我认为这会阻止bindingSource修改我的数据。但是我认为WinForms不允许这样做(因为您可以修改数据,但是我不想直接应用这些更改)。似乎一切都会导致使用深度副本。@Kiquenet我刚刚使用了深度副本。我将把代码作为答案发布。(我不认为这段代码值得称赞,它本质上是不久前发布的代码。而且,它只适用于可序列化对象)
// Creates a deep copy of an Object
public static T DeepClone<T>(T obj)
{
    using (var ms = new MemoryStream())
    {
        var formatter = new BinaryFormatter();
        formatter.Serialize(ms, obj);
        ms.Position = 0;

        return (T)formatter.Deserialize(ms);
    }
}