在C#中排除二进制序列化的父对象

时间:2010-01-12 21:25:54

标签: c# serialization deep-copy

我对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类没有标记为Serializable感到呻吟。

但我不想序列化A,我想序列化B和它的子对象C.

我猜它也试图序列化父对象A,因为它在对象图中全部互连。但有什么方法可以将它排除在此之前被序列化?

5 个答案:

答案 0 :(得分: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);
    }

}

每条评论编辑:

请将以下内容添加到event

中的B
[field:NonSerialized]

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

答案 1 :(得分:1)

如果B没有对A的任何引用,即使A引用了B,序列化B也不要求A可序列化。

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

答案 2 :(得分:0)

我不确定,但是如果你把它标记为不可序列化怎么办?我测试一下:P

答案 3 :(得分:0)

此处必须有其他内容 - 您的代码编译并执行时没有问题(因为它应该 - 类型A不是B's对象图的一部分)。

objB实际上是A类型的实例吗?

答案 4 :(得分:0)

好的感谢所有回复,我确实找到了问题......

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

我没有发布整个代码情况的错误,抱歉:(