VB.net 3.5 assignmet运算符分配指针而不是复制?

时间:2010-12-16 18:55:33

标签: vb.net

我的程序决定分配指针而不是复制对象,我不知道为什么。我有这样的事情:

    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也不会更改。我也试过分配整个对象,我得到了相同的结果。任何想法为什么会发生这种情况以及如何解决它?

2 个答案:

答案 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,它会有自己的列表。

因为我不知道你想要实现什么,我不知道如何修复代码,但正如你所看到的,制作一些支持列表绝不是一个好主意可访问的,即可分配的。

因此,我建议保留列表不可变私有,只提供索引访问。