2

我对 C# 中的二进制序列化有疑问

我需要能够深度克隆 B 类的对象(当然还有它在图中的所有子对象)。我想通过使用二进制序列化来实现这一点。在这个问题的背景下,讨论是否是最好的方法是无关紧要的。

假设我有这个类结构:

public class A 
{
    private B objB;
}

[Serializable]
public class B : ICloneable
{
    private C objC1;
    private C objC2;

    public object Clone()
    {
        B clone = Helper.Clone<B>(this);
        return (B)clone;
    }
}

[Serializable]
public class C
{
    int a;
    int b;
}

使用二进制序列化进行深度克隆的辅助类(我从网上某处得到这个方法代码,不记得在哪里 TBH,但看起来还不错)

public static class Helper
{
    public static T Clone<T>(T OriginalObject)
    {
        using (Stream objectStream = new MemoryStream())
        {
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(objectStream, OriginalObject);
            objectStream.Seek(0, SeekOrigin.Begin);
            return (T)formatter.Deserialize(objectStream);
        }
    }

}

所以在我的应用程序的某个时刻,我点击了以下代码:

B clone = (B)objA.objB.Clone();

问题是调试器抱怨 A 类没有被标记为可序列化。

但我不想序列化 A,我想序列化 B,它是子对象 C。

我猜它也试图序列化父对象 A,因为它在对象图中都是相互关联的。但是有什么办法可以将它排除在序列化之外吗?

4

5 回答 5

2

这个快速模拟代码工作得很好,你的问题在别处,也许C有类变量A

public class A
{
    private B bObj = new B();

    public A()
    {
        B copy = bObj.Clone() as B;
    }
}
[Serializable]
public class B : ICloneable
{
    private int test = 10;

    public object Clone()
    {
        return Helper.Clone(this);
    }

}

编辑每条评论:

请将以下内容添加到您的eventinB

[field:NonSerialized]

这将防止事件的调用列表的序列化,而该列表又引用A

于 2010-01-12T21:32:04.150 回答
1

如果 B 不持有对 A 的任何引用,则序列化 B 将不需要 A 可序列化,即使 A 具有对 B 的引用。

从您的代码示例中,B 没有对 A 的任何引用,因此它应该可以工作。您确定您提供的代码示例确实代表了您的真实场景吗?

于 2010-01-12T21:31:20.253 回答
0

我不确定,但是如果您将其标记为不可序列化怎么办?我会测试一下:P

于 2010-01-12T21:31:38.773 回答
0

这里必须有其他东西在起作用 - 你的代码编译和执行没有问题(因为它应该 - 类型A不是类型B's对象图的一部分)。

是否可能objB实际上是 type 的一个实例A

于 2010-01-12T21:35:12.577 回答
0

好的,谢谢大家的回复,我确实找到了问题...

B 类包含一个公共事件字段,并且 A 类中的事件处理程序订阅了它。如果我取消订阅事件处理程序,序列化工作。

我没有发布整个代码情况的错误,对不起:(

于 2010-01-12T22:23:06.357 回答