如何正确复制/克隆结构?我应该使用课程吗?

时间:2009-03-13 22:37:25

标签: .net

让我说有那个

Structure myStruct
    Public myPoint As Point
    Public myBool As Boolean
End Structure

如何制作该结构的副本/克隆?

我现在解决了这个问题, 我正在使用的代码示例:

    Dim myStruct(1) As myStruct 
    myStruct(0).myPoint = New Point(10, 10)
    myStruct(0).myBool = True

    Dim myCopy(1) As myStruct
    myCopy = myStruct
    myCopy(0).myBool = False
    myCopy(0).myPoint = New Point(11, 11)

,两个变量都改变了

我不得不做

    myCopy = CType(myStruct.Clone, myStruct())

另一个问题,如果使用了这种结构,比方说,10,000次,我应该创建一个类吗?

4 个答案:

答案 0 :(得分:2)

你看每个结构12个字节,所以将它作为结构传递比在堆上创建一个字大小的引用(换句话说,使用类)便宜

如果您需要一次访问所有10,000个,那么即使它们是结构体,也会在堆上创建它们的数组。

复制结构就像创建声明另一个相同类型的结构并将第一个结构分配给第二个结构一样简单。

答案 1 :(得分:2)

您必须使用Clone方法的原因是您正在复制Array对象,而不是结构。这适用于复制结构值:

Dim myStructArray(0) As MyStruct
myStructArray(0).MyPoint = New Point(10, 10)
myStructArray(0).MyBool = True

Dim myCopyArray(0) As MyStruct
myCopyArray(0) = myStructArray(0) 'copy structure instead of array
myCopyArray(0).MyBool = False
myCopyArray(0).MyPoint = New Point(11, 11)

在这种情况下,在替换所有值时复制结构当然完全没有意义,但复制确实有效,只留下两个独立的数组而不是对同一个数组的两个引用。

结构通常应该是不可变的,即它的属性是只读的,这可以保护您免受以下情况的影响:

Dim myStructList(Of MyStruct) As New myStructList(Of MyStruct)()
myStructList.Add(New MyStruct())
myStructList(0).MyPoint = New Point(10, 10) 'doesn't work

这不起作用的原因是myStructList(0)返回结构的副本。复制的MyPoint成员已更改,但结构的副本永远不会写回列表。

这是不可变的结构:

Structure MyStruct

   Private _myPoint As Point
   Private _myBool As Boolean

   Public Readonly Property MyPoint As Point
      Get
         Return _myPoint
      End Get
   End Property

   Public Readonly Property MyBool As Boolean
      Get
         Return _myBoolean
      End Get
   End Property

   Public Sub New(ByVal myPoint As Point, ByVal myBool As Boolean)
      _myPoint = myPoint
      _myBool = myBool
   End Sub

End Structure

使用构造函数创建新值:

Dim myStructList(Of MyStruct) As New myStructList(Of MyStruct)()
myStructList.Add(New MyStruct(New Point(10, 10), True))

您仍然可以复制整个结构值:

Dim myStructArray(0) As MyStruct
myStructArray(0) = New MyStruct(New Point(10, 10), True)

Dim myCopyArray(0) As MyStruct
myCopyArray(0) = myStructArray(0) 'copy structure value

答案 2 :(得分:0)

要制作结构的副本,必须声明它的新实例。我通常通过在struct中实现我自己的Clone()方法来实现这一点。例如:

Friend Structure SomeStructure
  Dim ValueA As Integer
  Dim ValueB As Integer
  Dim Values() As Integer
  Public Function Clone() As SomeStructure
    Dim theClone As SomeStructure
    theClone.ValueA = Me.ValueA
    theClone.ValueB = Me.ValueB
    ReDim theClone.Values(Me.Values.GetUpperBound(0))
    Array.Copy(Me.Values, theClone.Values, Me.Values.Length)
    Return theClone
  End Function
End Structure

答案 3 :(得分:0)

Visual Basic 2013注意: 使用estructure2 = estructure1复制结构 不会将estructure1的副本创建到structure2中;相反,它将为structure2分配对structure1的引用。 在这种情况下,访问结构2将提供与结构1相同的字段值。 如果任何structure1字段发生更改,则使用structure2访问的值也将更改,因为它们指向相同的数据。从这个意义上说,它根本不是副本。