C# 反序列化时猜测对象类型

C# 反序列化时猜测对象类型,c#,C#,我用这种方式序列化了一些对象[编辑:使用BinaryFormatter] 在B之前有多少个A对象由用户在运行时决定 在反序列化时,我无法猜测何时从反序列化的Obj_A切换到Obj_B 我欢迎任何相关的见解 编辑:序列化发生在流上,A和B的编号事先不知道 回答 Marc Gravell提出了一些我不知道的建议: 为什么要麻烦呢?只需让格式化程序完成工作,然后测试类型即可。 (我很惊讶我没有被这里的人大量询问,如此明显……) 另一个不太优雅的解决方案是强制对象进入列表: LIST Obj_A

我用这种方式序列化了一些对象[编辑:使用BinaryFormatter]

在B之前有多少个A对象由用户在运行时决定

在反序列化时,我无法猜测何时从反序列化的Obj_A切换到Obj_B

我欢迎任何相关的见解

编辑:序列化发生在流上,A和B的编号事先不知道

回答
Marc Gravell提出了一些我不知道的建议:
为什么要麻烦呢?只需让格式化程序完成工作,然后测试类型即可。
(我很惊讶我没有被这里的人大量询问,如此明显……)

另一个不太优雅的解决方案是强制对象进入列表:

LIST Obj_A
    Obj_A 1    
    Obj_A 2
    Obj_A 3

LIST Obj_B
    Obj_B 1
    Obj_B 2
    Obj_B 3
    Obj_B 4

您使用的是什么序列化?各种选择

  • 使用serialiser为您处理此问题
  • 在每一个之前使用一些东西,告诉您下面的类型(可以是完整类型,也可以是一些标记代码,或者可以是元素名(XML)、成员名(JSON)等等)
  • 如果A在As之前,则写下编号,B在Bs之前写下编号等
  • 如果使用诸如BinaryFormatter或NetDataContractSerializer(两者都包含类型元数据)之类的东西,则将其反序列化为正常值,然后使用GetType()查找所提供的内容

序列化的格式是什么?XML?您是否控制序列化?添加一个“count”属性会很有意义,或者,如果您使用的是像Xml这样的分层格式,那么可以为每种类型添加一个父元素。对不起。忘了提了。如果您使用的是BinaryFormatter(编辑),它应该为您执行此操作。或者您正在实现ISerializable?@mika BinaryFormatter包含类型元数据。您应该只需要一个
列表
或类似列表;它应该会起作用的嗨,马克!(很高兴再次见到你)选项1对我来说不是很清楚。选项2是一个聪明的解决方案,但会减慢过程,因为它会强制在每个对象之间重新创建。选项3没有帮助,因为程序在流上序列化,而不是一次序列化。所以这个数字是不知道的beforehand@mika-我想我们以前有过这样的对话,但我仍然不确定BinaryFormatter是否打算以这种方式使用。。。但无论哪种方式,因为它包含类型meta,所以它应该可以正常工作。我的建议是什么?不要为此使用BinaryFormatter。。。有专门为流媒体设计的连续器…@Marc:是的,我确实打算给protobuff一个机会,但我知道我必须处理遗留代码。XML太慢了。对于BinaryFormatter,我还没有看到任何在有效序列化之前尝试强制转换的方法(我有类型meta的事件)。序列化的是序列化的(或者我错过了什么)@Mika为什么不在之后使用GetType()进行转换?@Marc:为了回答“为什么不使用GetType”的问题,我在“无知”和“愚蠢”之间犹豫。你能把这个贴出来并编辑到你的答案中,这样我就可以把它标记为接受了吗?(这可能会帮助像我这样迷失的灵魂寻找这样的答案)
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("X:\\binary.dump", FileMode.Open);
object o = formatter.Deserialize(stream);

if (o.GetType() == typeof(Obj_A))
     ReadTheMSDN(Obj_A);

else if (o.GetType() == typeof(Obj_B))
     KnowObjectsYouHandle(Obj_B);

stream.Close();
LIST Obj_A
    Obj_A 1    
    Obj_A 2
    Obj_A 3

LIST Obj_B
    Obj_B 1
    Obj_B 2
    Obj_B 3
    Obj_B 4