我已经在C#中使用拷贝构造函数实现了一个深层克隆方法。为了验证它的工作原理,我通过比较序列化对象和它的克隆的结果来测试它。序列化是按照通用对象T完成的。我也尝试过使用具体对象来获得相同的结果。序列化修改C#中原始对象的内容#
我有序列化对象转换成字节数组
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对象有什么关系?
编辑:
下面是深clone方法看起来像
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;
}
目的是绝不复杂。所有被复制的值都是值类型,所以没有需要担心的引用类型。
请发布DeepClone方法..有可能是这个问题 –
可能与对象的复杂性有关 - 检查了这一点:http://stackoverflow.com/questions/5017274/binaryformatter-and-deserialization-complex -objects – Clay
想想我们也可能需要查看完整的“MyClass”。此外,它没有状态,为什么ObjectToBytes是一个私有实例方法,而不是静态的?我认为这可能会有帮助,如果你可以格式化一个完整的示例代码,可以剪切/粘贴到LinqPad。 –