Danny Watson
Danny Watson

Reputation: 165

How to serialise generic list?

I have a generic list of employees and supervisors

List<Employee> employees = new List<Employee>();
List<Supervisor> supervisors = new List<Supervisor>(); 

They are both part of a employee class that I have marked as [Serializable]

Could I put both of these lists into another list so that it can be serialised easier?

I have looked at serialisation tutorials but they only specify one generic list or less.

I have provided a template, I want to click a 'Save' button and complete the serialise process, preferably with both lists into one bigger list.

private void btnSave_Click(object sender, EventArgs e)
{
     FileStream outFile;
     BinaryFormatter bFormatter = new BinaryFormatter();
}

Upvotes: 0

Views: 162

Answers (2)

You can actually serialize two lists to one stream:

using (FileStream fs = new FileStream(..., FileMode.OpenOrCreate)) {
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(fs, employees);
    bf.Serialize(fs, supervisors);
}

The BinaryFormatter prefixes the data block with meta data that also apparently allows it to concatenate data to one file. In order to read back supervisors you have to load the other list first. Since the lists aren't fixed length records, the second list could become unusable when you re-write the first and either lose it behind orphaned data or overwrite part of it.

Since there are so many things which can prevent that from working, it is easy enough to create a "holder" or container class for multiples:

[Serializable()]
public class BFHolder
{
    public List<Employee> employees { get; set; }
    public List<Supervisor> supervisors { get; set; }   
    public BFHolder()
    {
    }
}

After you deserialize, you can pull out the lists as needed.

Yet one more -- better -- option is ProtoBuf-Net (scroll down to the read me). In addition to being faster and creating smaller output than the BinaryFormatter, it includes the means to serialize multiple objects to one stream.

using (FileStream fs = new FileStream(..., FileMode.OpenOrCreate)) {
    Serializer.SerializeWithLengthPrefix<List<Employee>>(fs, employees,
                    PrefixStyle.Base128);
    Serializer.SerializeWithLengthPrefix<List<Supervisor>>(fs, supervisors,
                    PrefixStyle.Base128);
}

Upvotes: 1

Valentin
Valentin

Reputation: 5488

You can put this lists in another class container and serialize/deserialize it.

[Serializable]
public class Container 
{
     public List<Employee> employees = new List<Employee>();
     public List<Supervisor> supervisors = new List<Supervisor>();
} 

Upvotes: 0

Related Questions