使用BinaryFormatter序列化和反序列化List<List<object>>

3
假设我有:
List<object> mainList = new List<object>();

它包含以下内容:

List<string> stringList = new List<string();
List<CustomClass> custList = new List<CustomClass>();
mainList.Add(stringList);
mainList.Add(custList);

将数据序列化

Stream stream;
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, mainList);

反序列化

Stream stream = (Stream)o;
BinaryFormatter formatter = new BinaryFormatter();
List<object> retrievedList = (List<object>)formatter.Deserialize(stream);

目前,我收到一个错误,即流读取(反序列化)已经到达了流的末尾,但没有检索到任何值。

除了...,我需要指定其他内容吗?

[Serializable]
public class CustomClass { .... }

在自定义类中如何使其工作?我能否每次反序列化包含不同类型对象的List>?

我尝试过了。

IList list = (IList)Activator.CreateInstance(typeof(custClassList[0]))

我尝试发送和接收信息,但遇到了相同的问题。

然而我可以序列化和反序列化指定类型或列表,但我真的需要它是动态的。


如果没有Serializable属性或实现ISerializable接口,则无法使用BinaryFormatter序列化类型。 - Sriram Sakthivel
这行代码只是一个打字错误吗?List<object> retrievedList = formatter.Serialize(stream); 还是来自你的代码?;) - olydis
应该将 List<object> retrievedList = formatter.Serialize(stream); 更正为 List<object> retrievedList = (List<object>)formatter.Deserialize(stream); 才能编译通过。我认为这是一个笔误,请进行更正。 - Sriram Sakthivel
Sriram Sakthivel建议的是;)但是如果您按照问题中发布的方式编写代码,它甚至无法编译,因此我认为您的意思是Deserialize(当然要进行转换) - olydis
你仍然在调用 Serialize... - olydis
@SriramSakthivel 好的,问题已解决。现在呢? - Glimpse
2个回答

3

基本上,BinaryFormatter 是个笑话。它在某些情况下可以工作,但在几乎相同的场景中由于未知原因而失败。

最好且更优秀的替代 BinaryFormatter 的是第三方库 protobuf-nethttps://github.com/mgravell/protobuf-net),由 Marc Gravel 开发。

这个美妙的库一次解决了我遇到的所有问题。它更容易设置,并对复杂的自定义类作出更完美的反应。

同时,我还应该提到它在序列化/反序列化方面更快。


1
通常来说会更快。我发现如果你有大量的基元数组(例如int []),那么BinaryFormatter比Protobuf.Net更快。 - mcmillab
1
Protobuf-net(至少是.NET端口)是由Marc Gravell创建的,而不是谷歌。它只是恰巧托管在Google Code上。 - Phil Cooper

1
为了解决导致错误“流读取(反序列化)已到达流的末尾”的问题,需要将流位置重置为0,如下所示...
stream.Position = 0;

除了...

[Serializable] public class CustomClass { .... }

不需要,对于你正在做的事情,这应该足够了。

在自定义类中还需要指定其他内容才能使其工作吗?每次我都可以反序列化包含不同类型对象的List>吗?

您应该能够序列化任何对象。


我已经尝试过了。我正在从已被NamedPipeClientStream写入的NamedPipeServerStream中读取数据,但会出现错误提示说它“无法寻址”。 - Glimpse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接