Циклическая ссылка ISerializable

Я пытался понять, как правильно реализовать циклическую ссылку с использованием интерфейса ISerializable. Но я не смог разобраться даже в простой форме, я прочитал объяснение здесь

Но я не смог это реализовать, я также пытался найти пример безрезультатно. Я проверил документацию в MSDN, но не могу найти ссылку на то, как обрабатывать пользовательскую сериализацию с циклическими ссылками.

Самая простая форма, с которой я пытался работать, — это двусвязный список.


person TigerChan    schedule 02.02.2014    source источник
comment
Я не верю, что это возможно без самостоятельной обработки полного/внешнего объектного графа и ручного разрыва/связывания ссылок. То есть вместо сериализации Node сериализуйте LinkedList (который представляет собой список из таких узлов) и обрабатывайте сериализацию вручную там.   -  person user2864740    schedule 02.02.2014


Ответы (2)


Для сериализации циклической ссылки просто нужна стратегия для сериализации всего графа объектов, не более того. для списка двойных ссылок вы можете начать с первого узла, а затем просто сериализовать следующий (предыдущий уже сериализован, поэтому ничего не нужно делать), затем, когда вы хотите снова построить список, сделайте то же самое, просто установите предыдущий узел для каждого последовательно ( рекурсивно) примерно так

public class LinkList : ISerializable
{
    public Node First { get; set; }

    public Node Tail { get; set; }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Firts", First);
    }
    public LinkList(SerializationInfo info, StreamingContext context)
    {
        First = info.GetValue("First", typeof(Node)) as Node;
        First.PrevNode = null;
        //do one one while set the Tail of this class  and LinkList proeprty for each node
    }
}
public class Node : ISerializable
{
    public LinkList LinkList { get; set; }


    public Node(SerializationInfo info, StreamingContext context)
    {
        Name = info.GetString("Name");
        NextNode = info.GetValue("NextNode", typeof(Node)) as Node;
        if(NextNode != null)
            NextNode.PrevNode = this;

    }
  public  Node PrevNode
    {
        get;
        set;
    }
    public Node NextNode
    {
        get;
        set;
    }
    public string Name
    {
        get;
        set;
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Name", Name);
        info.AddValue("Next", NextNode);

    }
}
person Mojtaba    schedule 02.02.2014
comment
Это именно то, что мне нужно, чтобы разобраться в этом, я предполагаю, что тот же базовый подход для направленного графа также будет работать (пробуя его, когда я публикую)? - person TigerChan; 02.02.2014
comment
@Nuku, если вы храните свой граф в структуре связанного списка, вы можете использовать ту же стратегию, попробуйте рекурсивно сериализовать (что-то вроде раньше), чтобы иметь дело с кругами, у вас может быть один флаг, который показывает, был ли узел сериализован раньше, и если да, то в следующий раз чтобы сериализовать узел, вы можете просто поместить туда один идентификатор, а затем после десериализации вы должны переделать отношения (обратите внимание на производительность, сколько раз вы должны повторять узлы графика), но если вы используете структуру с матрицей смежности en.wikipedia.org/wiki/Adjacency_matrix, тогда вы можете легко сериализовать каждый узел, а затем и саму матрицу. - person Mojtaba; 02.02.2014

Один из вариантов заставить это работать - добавить поле идентификатора в класс. Создайте связанный список целых чисел, который будет привязан к идентификатору поля, и свойство связанного списка только для чтения, которое будет заполнено на основе поиска ссылок на идентификаторы в связанном списке.

Единственным ограничением для этого является то, что каждый объект в списке идентификаторов должен быть доступен при его десериализации.

person Dan Drews    schedule 02.02.2014