6

我想知道是否有一种方法可以创建序列化对象图的树/视图,以及是否有人有任何指针?编辑的目的是如果我们由于某种原因遇到反序列化问题,我们实际上可以查看/生成关于序列化数据的报告,以帮助我们在必须调试代码之前确定问题的原因。此外,我想在将来扩展它以获取两个流(版本 1、版本 2)并突出显示它们之间的差异,以帮助确保我们不会在代码更改期间意外删除有趣的信息。/编辑

传统上我们使用的是 Soap 或 XML 序列化,但是这些对于我们的需求来说变得过于受限,而二进制序列化通常可以满足我们的所有需求。之所以没有采用,是因为查看序列化内容以帮助修复升级问题等要困难得多。

所以我开始考虑尝试创建一个关于序列化信息的视图。我可以在一定程度上从 ISerializable 构造函数执行此操作:

public A(SerializationInfo info, StreamingContext context)
{}

给定序列化信息,我可以反映 m_data 成员并查看实际的序列化内容。这种方法的问题是

  1. 它只会显示树的一个分支,我想从根显示整个树,从这个位置实际上不可能做到。
  2. 这不是一个查询信息的方便地方,我想将流传递给一个班级并在那里完成工作。

我见过 ObjectManager 类,但这适用于现有的对象图,而我需要能够从数据流中工作。我已经查看了使用 ObjectReader 和 __BinaryParser 的 BinaryFormatted,它连接到 ObjectManager(我认为它将拥有全部内容,只是可能在一个平面列表中),但是要复制它或通过反射调用它(2这 3 个类是内部的)似乎需要做很多工作,所以我想知道是否有更好的方法。

4

2 回答 2

1

你可以List<Child class>在每个父类中放一个(即使有相同的)

当您创建一个孩子时,您会立即将其放在该列表中,或者更好的是在将其添加到列表时声明它

例如

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

使用它,您可以将它们序列化为一个文件,其中包含对象的层次结构和对象本身。

如果父类和子类相同,则没有理由不能拥有动态和多层次的层次结构。

于 2012-01-03T16:27:38.940 回答
0

为了实现您所描述的内容,您必须在不知道序列化的类型的情况下从流中反序列化整个对象图。但这是不可能的,因为序列化程序不存储此类信息。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;}

序列化器将失败,因为它会尝试将字符串实例(首先被序列化)指向指向 A 的指针。您可以尝试逆向工程二进制序列化的工作原理,然后您可以创建序列化对象的动态树。但这需要相当大的努力。

为此,我将创建类似于此的类:

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

然后,当您将从流中读取时,您可以创建这些节点,并重新创建整个序列化树并对其进行分析。

于 2011-11-10T13:49:35.070 回答