I'm having real problems implementing Deep Copy on my custom data objects. I've tried various approaches I've found through StackOverflow, but having problems with all of them. I've tried various serialise/deserialise approaches (but not json, as I figure the problems I have would also occur in this) plus reflection methods. All have their issues. Here's my most recent code:
<Serializable>
Public Class Element
<NonSerialized>
Public AssociatedComponent As WinFormsDesigner.Component = Nothing
<Browsable(False)>
Public Property IsRigControl As Boolean = False
Public Property ID As ObjectId = ObjectId.NewObjectId
<GridSort("General", 10), Description("Order of element in layout with 0 being bottommost. Set via the Element Selector."), [ReadOnly](True)>
Public Property ZIndex As Integer = 0
<GridSort("General", 10)>
Public Property Size As Size = New Size(120, 60)
' Various Properties - all of standard value types: string, integer, Enums, List(of standard value types)
End Class
<TypeConverter(GetType(CustomClassDropDownConverter))>
<Serializable>
Public Class TextElement
Inherits Element
Public ObjectName As String = "Text Element"
<IgnoreDataMember>
Public ObjectIcon As Image = My.Resources.TextStyles
' Operational
Public LastCycled As Date
<GridSort("General", 10)>
Public Property Name As String = "{New Text}"
' Various Properties - all of standard value types: string, integer, Enums, List(of standard value types)
Public Overrides Function ToString() As String
Return Name & ControlChars.NullChar & "(" & ID.ToString & ")"
End Function
End Class
Module DeepClone
<Extension>
Public Function DeepClone(Of T)(ByVal obj As T) As T
Using ms = New MemoryStream()
Dim formatter = New BinaryFormatter()
formatter.Serialize(ms, obj)
ms.Position = 0
Return CType(formatter.Deserialize(ms), T)
End Using
End Function
End Module
This results in:
System.Runtime.Serialization.SerializationException: 'Type 'LiteDB.ObjectId' in Assembly 'LiteDB, Version=4.1.4.0, Culture=neutral, PublicKeyToken=4ee40123013c9f27' is not marked as serializable.'
I do want to be able to copy the ID too, however, changed the ID fields to this to enable putting NonSerilizable
on the private member:
<NonSerialized>
Private _id As ObjectId = ObjectId.NewObjectId
<Browsable(False)>
<GridSort("General", 10), [ReadOnly](True)>
Public Property ID() As ObjectId
Get
Return _id
End Get
Set(ByVal value As ObjectId)
_id = value
End Set
End Property
However, now get:
System.Runtime.Serialization.SerializationException: 'Unable to find assembly 'Infoz, Version=0.8.0.0, Culture=neutral, PublicKeyToken=null'.'
Infoz
is my main assembly.
Another unchangeable restricting factor is that I'm developing on Framework 3.5.
I've also tried the various reflection approaches suggested on SO, but again, no joy. I'm afraid I've lost track on what I've tried and the resulting errors, so am hoping my scenario will be enough for someone to know how to help.
I did try a very popular SO solution here but got a runtime exception in the GetHashCode
Override:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
I'm not fussy about how I achieve it (a specific library, reflection, serialisation etc) as it's not a heavy iterative operation, I just need to achieve it! It's interesting how something so fundamental as copying data objects can be so tricky!