1

我正在尝试将一个类对象(我认为这就是它的名称)添加到我的类的通用列表中。在以下代码中,每当我更改 TempQuoteReturnFromExecuteEstimate 中的值时,它都会更改通用列表的所有行中的这些值。我猜它只是引用对象。如何将值复制到通用列表?谢谢

Dim AllEstimatesReturn As New List(Of QuoteReturnData)
Dim TempQuoteReturnFromExecuteEstimate As New QuoteReturnData
...
AllEstimatesReturn.Add(TempQuoteReturnFromExecuteEstimate)
4

3 回答 3

2

你的假设是正确的。当您创建一个类类型(引用类型)变量时,它只是引用一个对象。您可以有许多不同的变量同时引用同一个对象。

在这种情况下,AllEstimatesReturn列表中的每个项目就像一个单独的QuoteReturnData变量。每个项目只是对对象的引用,而不是副本。因此,理论上,列表中的每个项目都可以引用同一个对象,尽管这通常不是您想要的。

如果要为列表中的每个项目创建单独的对象,则每次都需要使用New关键字创建它们:

'Add the first item
Dim TempQuoteReturnFromExecuteEstimate As New QuoteReturnData
...
AllEstimatesReturn.Add(TempQuoteReturnFromExecuteEstimate)

'Add the second item
TempQuoteReturnFromExecuteEstimate = New QuoteReturnData  ' Use New to create another object
...
AllEstimatesReturn.Add(TempQuoteReturnFromExecuteEstimate)

请注意,在上面的示例中,我重用了相同的变量,只是更改了它的值,以便它引用一个新对象。旧对象仍然存在,因为它被列表对象引用。或者,您可以每次都声明一个新变量,但是,除非您为了清楚起见而这样做,否则没有技术原因需要这样做。

于 2013-02-26T19:00:37.963 回答
1

类类型是引用类型。因此,这会将 3 个对同一对象的引用添加到列表中:

Dim AllEstimatesReturn As New List(Of QuoteReturnData)
Dim TempQuoteReturnFromExecuteEstimate As New QuoteReturnData

AllEstimatesReturn.Add(TempQuoteReturnFromExecuteEstimate)
AllEstimatesReturn.Add(TempQuoteReturnFromExecuteEstimate)
AllEstimatesReturn.Add(TempQuoteReturnFromExecuteEstimate)

每次都创建新对象

Dim AllEstimatesReturn As New List(Of QuoteReturnData)

AllEstimatesReturn.Add(New QuoteReturnData())
AllEstimatesReturn.Add(New QuoteReturnData())
AllEstimatesReturn.Add(New QuoteReturnData())

或者实现一个克隆的方法QuoteReturnData

Class QuoteReturnData

    ' Creates an exact copy of the current QuoteReturnData object.
    Public Function SwallowCopy() As QuoteReturnData
        Return DirectCast(Me.MemberwiseClone(), QuoteReturnData)
    End Function

End Class

MemberwiseClone继承自我们需要的东西,Object并且做我们需要的东西;但是,此方法是受保护的,只能从类中调用。因此,我们将它包装到一个公共函数中。

现在你可以这样做

Dim AllEstimatesReturn As New List(Of QuoteReturnData)
Dim TempQuoteReturnFromExecuteEstimate As New QuoteReturnData

AllEstimatesReturn.Add(TempQuoteReturnFromExecuteEstimate.SwallowCopy())
AllEstimatesReturn.Add(TempQuoteReturnFromExecuteEstimate.SwallowCopy())
AllEstimatesReturn.Add(TempQuoteReturnFromExecuteEstimate.SwallowCopy())

请注意,这只会创建一个浅克隆。如果对象包含对其他对象的引用,则不会自动克隆这些其他对象。由您决定这是否可行,或者您是否需要深度克隆。

于 2013-02-26T19:10:27.230 回答
0

对象存储在引用中。仅复制值类型(即structs)。

为了拥有对象的副本,您需要克隆它。除非您这样做,否则您将始终创建对同一对象的许多引用。你的名单也不例外。

我将开始实现ICloneable.NET Framework 中的接口。

更新

如果您不喜欢该ICloneable接口,因为Clone()返回类型为 的对象object,您可以实现这样的接口:

Public Interface ICloneable(Of T)
{
      Function Clone() As T;
}

您将项目添加到列表中的代码将如下所示(如果QuoteReturnDataimplements ICloneable(Of T),当然):

AllEstimatesReturn.Add(TempQuoteReturnFromExecuteEstimate.Clone());
于 2013-02-26T18:55:58.333 回答