Сериализация - просмотр графа объектов из потока - PullRequest
6 голосов
/ 10 ноября 2011

Мне интересно, есть ли способ, которым я могу создать дерево / представление сериализованного графа объектов, и есть ли у кого-нибудь указатели? РЕДАКТИРОВАТЬ Цель состоит в том, чтобы по какой-то причине мы столкнулись с проблемой десериализации, чтобы мы могли на самом деле просмотреть / создать отчет по сериализованным данным, чтобы помочь нам определить причину проблемы, прежде чем отлаживатькод.Кроме того, я хочу расширить это в будущем, чтобы взять два потока (версия 1, версия 2) и выделить различия между ними, чтобы избежать случайного удаления интересной информации во время изменений кода. / EDIT

Традиционно мы использовали сериализацию Soap или XML, но они становятся слишком ограниченными для наших нужд, и двоичная сериализация обычно делает все, что нам нужно.Причина, по которой это не было принято, состоит в том, что намного труднее просматривать сериализованное содержимое, чтобы помочь решить проблемы обновления и т. Д.

Так что я начал пытаться создать представление для сериализованной информации.Я могу сделать это из конструктора ISerializable в определенной степени:

public A(SerializationInfo info, StreamingContext context)
{}

Учитывая информацию о сериализации, я могу отразить член m_data и увидеть фактическое сериализованное содержимое.Проблема с этим подходом заключается в том, что

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

Я видел класс ObjectManager, но он работает насуществующий граф объектов, тогда как мне нужно уметь работать с потоком данных.Я просмотрел BinaryFormatted, который использует ObjectReader и __BinaryParser, подключая ObjectManager (который, я думаю, будет иметь все содержимое, возможно, в виде плоского списка), но для репликации этого или вызова всего через отражение (2из этих 3 классов являются внутренними) кажется довольно большой работой, поэтому мне интересно, есть ли лучший подход.

Ответы [ 2 ]

1 голос
/ 03 января 2012

Вы можете поместить List<Child class> в каждый родительский класс (даже если там то же самое)

, и когда вы создаете ребенка, вы немедленно помещаете его в этот список или, что еще лучше, объявляете его, добавляя его в список.

Например,

ListName.Add(new Child(Constructer args));

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

Если родительский и дочерний классыно нет причин, по которым у вас не может быть динамической и многоуровневой иерархии.

0 голосов
/ 10 ноября 2011

Чтобы достичь того, что вы описываете, вам придется десериализовать весь граф объектов из потока, не зная типа, из которого он был сериализован.Но это невозможно, потому что сериализатор не хранит такую ​​информацию.AFAIK это работает следующим образом.Предположим, у вас есть пара типов:

class A { bool p1 }
class B { string p1; string p2; A p3}
// instantiate them:
var b = new B { p1 = "ppp1", p2 = "ppp2", p3 = new A { p1 = true} };

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

[B:[string:ppp1][string:ppp2][A:[bool:true]]]

Видите ли, здесь есть только значения и их типы.Но порядок неявный - как написано.Таким образом, если вы измените ваш объект B, предположим, что

class B { A p1; string p3; string p3;}

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

Для этой цели я бы создал класс, подобный следующему:

class Node
{
    public string NodeType;
    public List<Node> Children;
    public object NodeValue;
}

Затем, пока вы будете читать из потока, вы можете создать эти узлы и воссоздатьвсе сериализованное дерево и проанализировать его.

...