vbICloneable deepcopy of an object in .net



我正在尝试使用 ICloneable 将深拷贝方法添加到使用 xsd.exe 从 xsd 自动生成的类中。我可以让它在一个简单的层面上工作,但是一旦对象嵌套,克隆方法就不起作用。

我很确定我在 DirectorReturnType 类上的克隆方法有误,但我无法弄清楚如何解决它。

任何人都可以提供任何帮助吗?我附上了下面的子和类:

        Dim oDirRetType As New DirectorReturnType
        Dim oDirPerType As New DirectorPersonType
        Dim DirPerTypeT1 As New DirectorPersonType
        Dim DirPerTypeT2 As New DirectorPersonType
        Dim DirRetTypeT1 As New DirectorReturnType
        Dim DirRetTypeT2 As New DirectorReturnType
        Dim AROT1 As New AnnualReturnOfficer
        Dim AROT2 As New AnnualReturnOfficer

这按预期工作,并发送消息"test1",然后发送"test2":

        'Works
        oDirPerType.Occupation = "test1"
        DirRetTypeT1.Item = oDirPerType.Clone
        oDirPerType.Occupation = "test2"
        DirRetTypeT2.Item = oDirPerType.Clone
        DirPerTypeT1 = DirRetTypeT1.Item
        DirPerTypeT2 = DirRetTypeT2.Item
        MsgBox(DirPerTypeT1.Occupation)
        MsgBox(DirPerTypeT2.Occupation)

如果我随后添加一个类型的额外对象 AROTx,则它会发送"Test2"然后是"Test2"。

        'Doesnt Work
        oDirPerType.Occupation = "test1"
        oDirRetType.Item = oDirPerType
        AROT1.Item = oDirRetType.Clone
        oDirPerType.Occupation = "test2"
        DirRetTypeT2.Item = oDirPerType
        AROT2.Item = oDirRetType.Clone
        DirRetTypeT1 = AROT1.Item
        DirPerTypeT1 = DirRetTypeT1.Item
        DirRetTypeT2 = AROT2.Item
        DirPerTypeT2 = DirRetTypeT2.Item
        MsgBox(DirPerTypeT1.Occupation)
        MsgBox(DirPerTypeT2.Occupation)

董事类型:

Partial Public Class DirectorPersonType
Inherits PersonBaseType
Implements ICloneable
Private serviceAddressField As ServiceAddressType
Private dOBField As Date
Private nationalityField As String
Private occupationField As String
Private countryOfResidenceField As String
Private previousNamesField() As PreviousNameType
'''<remarks/>
Public Property ServiceAddress() As ServiceAddressType
    Get
        Return Me.serviceAddressField
    End Get
    Set(value As ServiceAddressType)
        Me.serviceAddressField = value
    End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlElementAttribute(DataType:="date")> _
Public Property DOB() As Date
    Get
        Return Me.dOBField
    End Get
    Set(value As Date)
        Me.dOBField = value
    End Set
End Property
'''<remarks/>
Public Property Nationality() As String
    Get
        Return Me.nationalityField
    End Get
    Set(value As String)
        Me.nationalityField = value
    End Set
End Property
'''<remarks/>
Public Property Occupation() As String
    Get
        Return Me.occupationField
    End Get
    Set(value As String)
        Me.occupationField = value
    End Set
End Property
'''<remarks/>
Public Property CountryOfResidence() As String
    Get
        Return Me.countryOfResidenceField
    End Get
    Set(value As String)
        Me.countryOfResidenceField = value
    End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlElementAttribute("PreviousNames")> _
Public Property PreviousNames() As PreviousNameType()
    Get
        Return Me.previousNamesField
    End Get
    Set(value As PreviousNameType())
        Me.previousNamesField = value
    End Set
End Property
Public Function Clone() As Object Implements System.ICloneable.Clone
    Return New DirectorPersonType With {.CountryOfResidence = CountryOfResidence, .DOB = DOB, .Forename = Forename, .Nationality = Nationality, .Occupation = Occupation, .OtherForenames = OtherForenames, .PreviousNames = PreviousNames, .ServiceAddress = ServiceAddress, .Surname = Surname, .Title = Title}
End Function
End Class

导演返回类型:

Partial Public Class DirectorReturnType
Implements ICloneable
Private itemField As Object
'''<remarks/>
<System.Xml.Serialization.XmlElementAttribute("Corporate",
GetType(CorporateOfficerType)), _
System.Xml.Serialization.XmlElementAttribute("Person", 
GetType(DirectorPersonType))> _
Public Property Item() As Object
    Get
        Return Me.itemField
    End Get
    Set(value As Object)
        Me.itemField = Value
    End Set
End Property
Public Function Clone() As Object Implements System.ICloneable.Clone
    Return New DirectorReturnType With {.Item = Item}
End Function

您的克隆实际上并没有创建一些变量的新副本,而是指向存储在原始类中的现有值。

即这两个变量:

Private serviceAddressField As ServiceAddressType
Private previousNamesField() As PreviousNameType

在克隆功能中需要特别注意。

调用ME.MemberwiseClone以获取实例的新浅副本是整洁的(可能不是完全标准的)。 然后,您必须单独处理非标准类型(数组,类)并创建它们的新副本。

类似的东西(请纠正任何错误,但这是一般的想法)

Public Function Clone() As Object Implements ICloneable.Clone
   Dim typClone As DirectorPersonType = Me.MemberwiseClone ' Shallow clone taken and new object created
   Try
      typClone.serviceAddressField = Me.serviceAddressField.Clone ' create a new copy with same value
      typClone.previousNamesField.AddRange(Me.previousNamesField) ' create a new copy with the same values
      ' PreviousNamesField will need some work generating a new array
      ' let me know if you need more detail or a working example
      ' However, I have been corrected and will share that this method is 
      ' definitely superior to AddRange, using LINQ to
      ' create a new list with a copy of the items
       typClone.ListName = Me.ListName.Select(Function(x) x.Clone()).Cast(Of ClassName).ToList
   Catch ex As Exception
         ' catch errors and handle here!
   End Try
   Return typClone
End Function

相关内容

  • 没有找到相关文章

最新更新