我在C#中使用了复制构造函数实现了深度克隆方法。为了验证它是否有效,我通过比较序列化对象及其克隆的结果来测试它。序列化是根据通用对象T完成的。我也根据具体对象尝试了它并获得相同的结果。
我有一个将对象序列化为字节数组的方法
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();
}
}
以下代码可以正常使用。
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!
但是,当我切换对象序列化的顺序时,字节数组不再相等。
// 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!
为什么序列化的顺序会影响这个?它与BinaryFormatter或MemoryStream对象有关吗?
编辑:
这是深度克隆方法的样子
public MyClass DeepClone()
{
return new MyClass(this);
}
它使用的构造函数如下所示
protected MyClass(MyClass myClass)
{
if (myClass == null)
throw new ArguementNullException("myclass");
this.number = myClass.Number;
this.number2 = myClass.Number2;
this.number3 = myClass.Number3;
}
对象绝不复杂。所有被复制的值都是值类型,因此没有需要担心的引用类型。
答案 0 :(得分:4)
DeepClone或其依次调用的东西似乎正在改变源对象的状态。
答案 1 :(得分:1)
您必须修改ObjectToBytes方法,如下所示:
private byte[] ObjectToBytes(Object obj)
{
if(obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
using(MemoryStream ms = new MemoryStream()) {
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
希望有所帮助