我想知道是否有一种方法可以创建序列化对象图的树/视图,以及是否有人有任何指针? 编辑我们的目标是,由于某些原因我们是否应该遇到反序列化问题,我们实际上可以查看/生成序列化数据的报告,以帮助我们在调试之前找出问题的原因代码。此外,我希望将来扩展它以采用两个流(版本1,版本2)并突出显示它们之间的差异,以帮助确保我们在代码更改期间不会意外删除有趣的信息。的 /修改
传统上我们使用过Soap或XML序列化,但是这些对于我们的需求变得太受限制了,而二进制序列化通常会做我们需要的所有事情。之所以没有采用,是因为查看序列化内容以帮助修复升级问题等更加困难。
所以我开始考虑尝试创建序列化信息的视图。我可以在一定程度上从ISerializable构造函数中执行此操作:
public A(SerializationInfo info, StreamingContext context)
{}
鉴于序列化信息,我可以反映m_data成员并查看实际的序列化内容。这种方法的问题是
我见过ObjectManager类,但这适用于现有的对象图,而我需要能够从数据流中工作。我查看了BinaryFormatted,它使用了ObjectReader和__BinaryParser,挂钩到ObjectManager(我认为它将拥有整个内容,可能只是在一个平面列表中),但要复制它或通过反射调用它(2)这三个类是内部的)似乎做了很多工作,所以我想知道是否有更好的方法。
答案 0 :(得分: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;}
Serialzer将失败,因为它会尝试将字符串实例(首先被序列化)分配给指向A的指针。您可以尝试对二进制序列化的工作方式进行逆向工程,然后您可以创建一个序列化的动态树对象。但这需要付出相当大的努力。
为此,我将创建类似于此的类:
class Node
{
public string NodeType;
public List<Node> Children;
public object NodeValue;
}
然后,当您将从流中读取时,您可以创建这些节点,并重新创建整个序列化树并进行分析。