What exactly do you want the output to look like? You can write it manually (see Lirik's answer), or if you want runtime support, perhaps something like protobuf-net.
This would be trivial to do if you were using classes (which I expect you actually should be), but additionally protobuf-net v2 (only available as source at the moment) should work with that "as is".
For info, here is how I would do it as classes:
public class Company
{
private readonly List<Employee> employees = new List<Employee>();
public List<Employee> Employees { get { return employees;}}
}
public class Employee
{
public string EmployeeName {get;set;}
public string Designation {get;set;}
}
This could be decorated with serialization attributes, or (again, using protobuf-net v2) something like this test (which passes):
[Test]
public void CanSerializeCompany()
{
var model = TypeModel.Create();
model.Add(typeof(Company), false).Add("Employees");
model.Add(typeof(Employee), false).Add("EmployeeName", "Designation");
model.CompileInPlace();
Company comp = new Company {
Employees = {
new Employee { Designation = "Boss", EmployeeName = "Fred"},
new Employee { Designation = "Grunt", EmployeeName = "Jo"},
new Employee { Designation = "Scapegoat", EmployeeName = "Alex"}}
}, clone;
using(var ms = new MemoryStream()) {
model.Serialize(ms, comp);
ms.Position = 0;
Console.WriteLine("Bytes: " + ms.Length);
clone = (Company) model.Deserialize(ms, null, typeof(Company));
}
Assert.AreEqual(3, clone.Employees.Count);
Assert.AreEqual("Boss", clone.Employees[0].Designation);
Assert.AreEqual("Alex", clone.Employees[2].EmployeeName);
}
(and writes 46 bytes)
It should work with private fields, structs, etc - I'd have to take a look...
If you are able to add attributes, then you don't need to set up the model manually (the first 4 lines). The rest of the code is just showing full round-trip usage.
struct, and I expect this is going to bite you in interesting ways. I would use aclasshere...