I have implemented a deep clone method using a copy constructor in C#. To verify that it works, I am testing it by comparing the results of serializing an object and it's clone. The serialization is done in terms of a generic object T. I have also tried it in terms of a concrete object and get the same results.
I have a method for serializing the objects into byte arrays
private byte[] ObjectToBytes(T obj)
{
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, obj);
stream.Seek(0, SeekOrigin.Begin);
return stream.ToArray();
}
}
The following code works fine.
T original = this.GetNewThing();
T clone = original.DeepClone();
// serialize after cloning
byte[] originalBytes = ObjectToBytes(original);
byte[] cloneBytes = ObjectToBytes(clone);
bool equal = true;
for (int i = 0; i < originalBytes.Length; i++)
{
if(originalBytes[i] != cloneBytes[i]
{
equal = false;
break;
}
}
equal == true; // True!
However, when I switch the order of when the objects are serialized, the byte arrays are no longer equal.
// serialize before cloning
T original = this.GetNewThing();
byte[] originalBytes = ObjectToBytes(original);
T clone = original.DeepClone();
byte[] cloneBytes = ObjectToBytes(clone);
bool equal = true;
for (int i = 0; i < originalBytes.Length; i++)
{
if(originalBytes[i] != cloneBytes[i]
{
equal = false;
break;
}
}
equal == true; // False!
Why does the order of serialization affect this? Does it have something to do with the BinaryFormatter or MemoryStream objects?
EDIT:
Here's what the deep clone method looks like
public MyClass DeepClone()
{
return new MyClass(this);
}
and the constructor it uses looks like this
protected MyClass(MyClass myClass)
{
if (myClass == null)
throw new ArguementNullException("myclass");
this.number = myClass.Number;
this.number2 = myClass.Number2;
this.number3 = myClass.Number3;
}
The object is by no means complex. All the values being copied are values types, so there are no reference types that need to be worried about.
Serialization is the process of converting an object into a stream of bytes to store the object or transmit it to memory, a database, or a file. Its main purpose is to save the state of an object in order to be able to recreate it when needed. The reverse process is called deserialization.
This attribute is used in the class definition to indicate that a class can be serialized. By default, all fields in the class are serialized except for the fields that are marked with a NonSerializedAttribute . It is not necessary to use this attribute if a given type implements the System.
DeepClone, or something it calls in turn, seems to be changing the state of your source object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With