Vb.net Net复制一个列表来存储原始值,以便以后使用
我有一个WPF表单,它获取具有位置和大小的对象列表,并在画布上打印它们。我目前正在尝试实现一个撤销按钮,该按钮将抛出对对象位置所做的所有更改,并恢复到加载表单时检索到的原始集合 现在,在加载表单时,我转到数据库,获取需要显示的所有对象,然后将返回的列表分配给两个不同的集合。出现的问题是,这两个集合实际上是指向原始集合的指针,每当其中一个集合发生更改时,更改都会反映在第二个集合中 是否可以复制对象列表,以便对一个集合所做的更改不会影响辅助集合 到目前为止,我只尝试使用赋值运算符,将源集合传递到函数Vb.net Net复制一个列表来存储原始值,以便以后使用,vb.net,list,collections,Vb.net,List,Collections,我有一个WPF表单,它获取具有位置和大小的对象列表,并在画布上打印它们。我目前正在尝试实现一个撤销按钮,该按钮将抛出对对象位置所做的所有更改,并恢复到加载表单时检索到的原始集合 现在,在加载表单时,我转到数据库,获取需要显示的所有对象,然后将返回的列表分配给两个不同的集合。出现的问题是,这两个集合实际上是指向原始集合的指针,每当其中一个集合发生更改时,更改都会反映在第二个集合中 是否可以复制对象列表,以便对一个集合所做的更改不会影响辅助集合 到目前为止,我只尝试使用赋值运算符,将源集合传递到函数
byval
中,滚动列表中的每个元素,手动将其添加到第二个集合中,并使用linq从原始列表中获取所有对象,将结果推送到单独的临时列表中,并将第二个集合分配给临时列表
我觉得我把这个问题复杂化了,但我在谷歌搜索时遇到的几乎所有地方都说这种行为是出于设计,我理解,但这似乎是一个相当普遍的想法。另一个被删除的答案是使用
var copy=list.ToList()
获取列表的副本。这将适用于以下警告:两个列表仍将引用相同的对象,因此对这些对象的任何更改都将反映在两个列表中。只要您只更改列表中对象的顺序,此解决方案是完全可行的。您必须创建一个新列表,并向其中添加列表1中项目的副本。您可以使用对象初始化来完成此操作,例如
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的任何属性都是引用,则还需要复制这些对象。(这称为a)我以前使用过一个函数来制作对象的“深度”副本:
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
与其他一些答案相比,这是一种低级方法,但允许您深入复制任何对象。我已经成功地在类似于您的情况下使用了它,我需要一个数组的深度副本。只需使用此代码将listA的所有项分配给listB即可
For Each elm In ListA
ListB.Add(elm)
Next
主要问题是某些值正在更改(本例中的位置),因此这种方法不起作用。我尝试了类似的方法,但我要复制的对象相当大,并且有额外的对象作为数据成员,因此从速度的角度来看,它很快就会产生反效果(递归函数调用和100多个starter对象实例之类的东西)。另外,谢谢你的链接,我熟悉它提到的原则,但从未听说过它们的名称,能够使用正确的术语总是很好。在尝试实现此函数时,我注意到,为了使其尽可能通用,我创建的所有自定义类都必须标记为
serializable
在您使用此函数的时候,您是否看到过将类标记为serializable是不明智的原因?我不记得在自定义类上使用过它,因此我无法对此做出具体评论。但是,如果该类标记为serializable,我认为您不会遇到任何问题。在ad之后对我所有受影响的类定义,这个函数工作起来很有魅力,比我发现的第三方控件做大致相同的工作要快得多。通过测试,我发现ListB
将包含对ListA
中项目的引用,因此对ListA
的任何更改都将反映在<代码>列表b。Casey Wilkins的深度副本为我解决了这个问题。