blah blah blah is here! blah blah » Close

up0down
link

I have no trouble serializing the object's and their data - even if i don't know the object's type. the problem is with the deserialization of that data. because i don't know the types of objects, aside from the most primitive custom type "Entity", I am unable to deserialize the objects back into a list of Entity.
What I do to serialize the data:

static void Serialize(List<Entity> list)
{
using (FileStream stream = new FileStream("save.bin", FileMode.Create))
{
for (int i = 0; i < list.Count; i++)
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, list[i]);
}
}
}

This works well enough, but how would I load that back? Those objects could be anything; all I know is that they are all of the base type Entity.

last answered 2 years ago

1 answers

up0down
link

Generic lists can in fact be serialized and deserialized directly.
There's no problem if some of the elements are of types derived from the type parameter as long as all such types are marked with the Serializable attribute which is not inherited automatically.
Here's a simple example to illustrate these points:
using System;
using System.IO;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
class Test
{
static void Main()
{
List<Entity> list = new List<Entity>();
Entity e = new Entity();
e.Id = 1;
ChildEntity ce = new ChildEntity();
ce.Id = 2;
ce.Name = "Fred";
list.Add(e);
list.Add(ce);
Serialize(list);
List<Entity> list2 = Deserialize();
Console.WriteLine(list2[0].Id);
ChildEntity ce2 = (ChildEntity)list2[1];
Console.WriteLine(ce2.Id);
Console.WriteLine(ce2.Name);
Console.ReadKey();
}
static void Serialize(List<Entity> list)
{
using (FileStream stream = new FileStream("save.bin", FileMode.Create))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, list);
}
}

static List<Entity> Deserialize()
{
List<Entity> list = null;
using (FileStream stream = new FileStream("save.bin", FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
list = (List<Entity>)formatter.Deserialize(stream);
}
return list;
}
}
[Serializable]
class Entity
{
public int Id;
}
[Serializable]
class ChildEntity : Entity
{
public string Name;
}

up0down
link

what's the difference between:
[Serializable]
class MyClass
[Serializable()]
class MyClass
class MyClass : ISerializable

up0down
link

There's no difference between the first two - when an attribute constructor doesn't require any arguments, the following () is optional.
The Serializable attribute provides default (de)serialization behaviour which is sufficient for most purposes.
If you need complete control over how a type is serialized or deserialized, then your type should implement the ISerializable interface as well. This interface has one method, GetObjectData, which the serializable type must implement.
Typically, you'd implement ISerializable to control serialization behaviour at runtime (as opposed to compile time).
It's also used by library writers to make serializable types easier to inherit from by consumers of the library. You can do this by making the GetObjectData method virtual so that it can be overridden by derived classes which can thereby extend the serialization behaviour of the base class without the need to reimplement the interface.

This post was imported from csharpfriends, if you have a similiar question please ask it again.

All previous members have been migrated, hope you enjoy the new platform!

Feedback