代码之家  ›  专栏  ›  技术社区  ›  Fredou

如何正确复制/克隆结构?我应该用课堂来代替吗?

  •  1
  • Fredou  · 技术社区  · 15 年前

    假设我有那个

    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())
    

    还有一个问题,如果使用这个结构,比如说,10000次,我应该创建一个类来代替它吗?

    4 回复  |  直到 15 年前
        1
  •  2
  •   BC.    15 年前

    您将看到每个结构有12个字节,因此将其作为一个结构传递比在堆上创建一个字大小的引用(换句话说,使用一个类)要便宜得多。

    如果需要一次访问全部10000个,那么即使它们是结构,也会在堆上创建它们的数组。

    复制结构与创建声明同一类型的另一个结构并将第一个结构分配给第二个结构一样容易。

        2
  •  2
  •   Guffa    15 年前

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

    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
    
        3
  •  0
  •   Mark Micallef    11 年前

    要复制结构,请 必须声明新实例 其中。我通常通过在结构中实现自己的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
    
        4
  •  0
  •   ADeveloper    6 年前

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