我的程序决定分配指针而不是复制对象,我不知道为什么。我有这样的事情:
Public Class Foo
Private myFooData As New List(Of FooData)
Public Sub New(ByVal newFooData As List(Of FooData))
myFooData = newFooData
End Sub
Public Property FooValues() As List(Of FooData)
Get
Return myFooData
End Get
Set(ByVal value As List(Of FooData))
myFooData = value
End Set
End Property
End Class
它的使用方式如下:
Public Sub Dosomething()
Dim mainFoo as new Foo
For x = 1 to 10
mainFoo.FooValues(x) = New FooData
Next
Dim originalFoo as new Foo
originalFoo.FooValues = mainFoo.FooValues.Take(3).ToList
Dim newFoo as new Foo
newFoo.FooValues = originalFoo.FooValues
newFoo.FooValues(1) += 1
End Sub
非常简化,但基本上我正在做的事情。因此,出于某种原因,当我在newFoo.FooValues中更改项目时,originalFoo.FooValues也会更改,而mainFoo也不会更改。我也试过分配整个对象,我得到了相同的结果。任何想法为什么会发生这种情况以及如何解决它?
答案 0 :(得分:2)
这就是.Net中的赋值应该如何工作。
当您在第二个代码段的中间调用.ToList()
时,您的代码将迭代该集并将副本复制到一个全新的列表中。这就是你的mainFoo对象被“保护”的原因 - 你创建了一个新实例。如果要复制的FooData项本身是对象的引用(提示:它们可能是),则只复制引用。唯一的例外是字符串和值类型(基元和结构),或者如果您手动编码。
List属性通常是一个好主意,使属性只读:
Public Property FooValues() As List(Of FooData)
Get
Return myFooData
End Get
End Property
这仍然可以让你操作列表到你内心的内容,但是阻止你完全从类下面切换列表实例。对于从类中作为属性公开的其他复杂类型也是如此。
您不想做的一件事是将其更改为结构而不是类。这可能看起来像你想要的那样,但它会在以后引起其他问题。
答案 1 :(得分:1)
使用Foo.FooValues
时,您可以为List(Of FooData)
s内部使用的Foo
分配引用,而且没有值!
让我们考虑一下步骤
Dim mainFoo as new Foo
mainFoo
现在有自己的支持列表。
originalFoo.FooValues = mainFoo.FooValues.Take(3).ToList
为 originalFoo
分配了一个新的支持列表,其中存储了mainFoo
的一些值。
newFoo.FooValues = originalFoo.FooValues
newFoo
曾经拥有自己的支持列表,但现在,它使用了一个originalFoo
用途。完全相同的(通过指针),没有副本。
因此,更改newFoo
会更改originalFoo
,但不会更改mainFoo
,它会有自己的列表。
因为我不知道你想要实现什么,我不知道如何修复代码,但正如你所看到的,制作一些支持列表绝不是一个好主意可访问的,即可分配的。
因此,我建议保留列表不可变和私有,只提供索引访问。