Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net Net复制一个列表来存储原始值,以便以后使用_Vb.net_List_Collections - Fatal编程技术网

Vb.net Net复制一个列表来存储原始值,以便以后使用

Vb.net Net复制一个列表来存储原始值,以便以后使用,vb.net,list,collections,Vb.net,List,Collections,我有一个WPF表单,它获取具有位置和大小的对象列表,并在画布上打印它们。我目前正在尝试实现一个撤销按钮,该按钮将抛出对对象位置所做的所有更改,并恢复到加载表单时检索到的原始集合 现在,在加载表单时,我转到数据库,获取需要显示的所有对象,然后将返回的列表分配给两个不同的集合。出现的问题是,这两个集合实际上是指向原始集合的指针,每当其中一个集合发生更改时,更改都会反映在第二个集合中 是否可以复制对象列表,以便对一个集合所做的更改不会影响辅助集合 到目前为止,我只尝试使用赋值运算符,将源集合传递到函数

我有一个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的深度副本为我解决了这个问题。