Исключить родительский объект при двоичной сериализации в C # - PullRequest
2 голосов
/ 13 января 2010

У меня есть вопрос о двоичной сериализации в 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, потому что он все взаимосвязан в графе объектов. Но можно ли как-то исключить его из сериализации на этом этапе?

Ответы [ 5 ]

2 голосов
/ 13 января 2010

Этот код быстрого макета работает отлично, ваша проблема в другом месте, возможно 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 голос
/ 13 января 2010

Если B не содержит ссылки на A, для сериализации B не требуется, чтобы A была сериализуемой, даже если A имеет ссылку на B.

Из вашего примера кода B не содержит никакой ссылки на A, поэтому он должен работать. Вы уверены, что приведенный вами пример кода действительно соответствует вашему реальному сценарию?

0 голосов
/ 13 января 2010

Хорошо, спасибо за все ответы, я нашел проблему ...

Класс B содержит открытое поле события, и обработчик событий в классе A подписан на него. Если я отписываюсь от обработчика событий, сериализация работает.

Моя ошибка в том, что я не опубликовал весь код, извините: (

0 голосов
/ 13 января 2010

Здесь должно быть что-то еще - ваш код компилируется и выполняется без проблем (как и должно быть - тип A не является частью типа B's object graph).

Возможно ли, что objB на самом деле является экземпляром типа A?

0 голосов
/ 13 января 2010

Я не уверен, но что если вы отметите его как несериализуемый? Я бы проверил это: P

...