3

Let's say I have

List<object> mainList = new List<object>();

And it contains

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

To serialize

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

To deserialize

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

At this point, I receive an error that the stream read (deserialization) reached the end of the stream without retrieving a value.

Do I need to specify something besides...

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

in the custom class to make this work? Can I not deserialize a List> that contains different type of object every time?

I tried

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

and tried to send and receive this, but got the same issue.

I can however serialize and deserialize a specified type or List, but I really need it to be dynamic.

Glimpse
  • 462
  • 2
  • 8
  • 25
  • without `Serializable` attribute or implementing `ISerializable` interface you can't serialize a Type with `BinaryFormatter` – Sriram Sakthivel Sep 18 '13 at 15:24
  • is this line just a typo? `List retrievedList = formatter.Serialize(stream);` or is this from your code? ;) – olydis Sep 18 '13 at 15:25
  • `List retrievedList = formatter.Serialize(stream);` should be `List retrievedList = (List)formatter.Deserialize(stream);` in order to compile. I assume it is a typo. Correct it – Sriram Sakthivel Sep 18 '13 at 15:28
  • what Sriram Sakthivel suggested ;) but your code would not even compile if you had it like posted in your question so I think you meant `Deserialize` anyway (with a cast of course) – olydis Sep 18 '13 at 15:30
  • you are **still** calling `Serialize`... – olydis Sep 18 '13 at 15:32
  • @SriramSakthivel Ok, fixed. Now what? – Glimpse Sep 18 '13 at 15:40

2 Answers2

3

Basically, BinaryFormatter is a joke. It works in some cases, but will fail in almost identical scenarios for unknown reasons.

The best and superior alternative to BinaryFormatter is the third-party library protobuf-net (https://github.com/mgravell/protobuf-net), developed by Marc Gravel.

This beauty solved all the problems I was having in one pass. It's much easier to set up and reacts more perfectly to complex, custom classes.

I should also mention that it's faster, in the terms of de/serialization.

Community
  • 1
  • 1
Glimpse
  • 462
  • 2
  • 8
  • 25
  • 1
    "usually" faster. I've found if you've got large arrays of primitives (eg int[]) then BinaryFormatter is faster than Protobuf.Net – mcmillab Nov 11 '13 at 22:08
  • 1
    Protobuf-net (at least the .net port) was created by Marc Gravell, not google. It just happens to be hosted on google.code. – Phil Cooper Dec 22 '14 at 14:31
1

In order to fix the issue that causes the error "stream read (deserialization) reached the end of the stream ", the stream position needs to reset to 0 as follows...

stream.Position = 0;

Do I need to specify something besides...

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

Nope...That should be good for what you are doing.

in the custom class to make this work? Can I not deserialize a List> that contains different type of object every time?

You should be able to serialize any object.

gpmurthy
  • 2,397
  • 19
  • 21
  • I've tried that. I'm reading from a NamedPipeServerStream that's been written to by a NamedPipeClientStream, which will give me an error saying that it "can't seek." – Glimpse Sep 18 '13 at 15:46