VB.Net 复制列表以存储稍后使用的原始值



我有一个 WPF 窗体,它采用具有位置和大小的对象列表,并将它们绘制在画布上。我目前正在尝试实现一个撤消按钮,该按钮将抛弃对对象位置所做的所有更改,并恢复到加载表单时检索到的原始集合。

就目前而言,我在表单加载时转到数据库并获取需要显示的所有对象,然后将返回的列表分配给两个单独的集合。出现的问题是,这两个集合实际上是指向原始集合的指针,每当一个集合发生更改时,更改都会反映在第二个集合中。

是否可以复制对象列表,以便对一个集合所做的更改不会影响辅助集合?

到目前为止,我已经尝试简单地使用 assignment 运算符,将源集合传递到函数byval中,然后滚动列表的每个元素,手动将其添加到第二个集合,并使用 linq 从原始列表中获取所有对象并将结果推送到单独的临时列表并将第二个集合分配给临时列表。

我觉得我把

这个问题过于复杂化了,但我在谷歌搜索时遇到的几乎所有地方都说这种行为是设计使然,我理解这一点,但这似乎是一个相当普遍的想法。

这是我之前用来制作对象的"深度"副本的函数:

Public Function DeepCopy(ByVal ObjectToCopy As Object) As Object
    Using mem as New MemoryStream
        Dim bf As New BinaryFormatter
        bf.Serialize(mem, ObjectToCopy)
        mem.Seek(0, SeekOrigin.Begin)
        Return bf.Deserialize(mem)
    End Using
End Function

与其他一些答案相比,这是一种低级方法,但允许您深度复制任何对象。 我已经在类似于您的情况中成功地使用了它,我需要数组的深层副本。

只需使用此代码将列表 A 的所有项目分配给列表 B

For Each elm In ListA
   ListB.Add(elm) 
Next

删除了另一个答案,说使用var copy = list.ToList();来获取列表的副本。 这将适用于以下警告:两个列表仍将引用相同的对象,因此对这些对象所做的任何更改都将反映在两个列表中。 只要您只更改列表中对象的顺序,此解决方案就完全可行。

您必须创建一个新列表,并将 list1 中项目的副本添加到其中。 您可以使用对象初始化来执行此操作,例如

Dim list2 = (From item in list1
             Select New ItemType With {.Property1 = item.Property1, .Property2 = item.Property2}.ToList()

另一种方法是将复制构造函数添加到 ItemType

Public Sub New(item as ItemType)
    Me.Property1 = item.Property1
    Me.Property2 = item.Property2
End Sub

您的列表副本可以简化为

Dim list2 = (From item in list1
             Select New ItemType(item)}.ToList()

请注意,如果 ItemType 的任何属性是引用,则还需要复制这些对象。 (这称为深拷贝)

相关内容

最新更新