序列化修改C#中原始对象的内容

时间:2016-05-13 20:20:59

标签: c# .net serialization

我在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;
}

对象绝不复杂。所有被复制的值都是值类型,因此没有需要担心的引用类型。

2 个答案:

答案 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();
       }
    }

希望有所帮助