Having inherited the Pet class from System.Runtime.Serialization.ISerializable , we now have full control over how the Pet class and its members in this Case Toy are serialized and de-serialized. See System.Runtime.Serialization.ISerializable , for more information on implementing System.Runtime.Serialization.ISerializable .
The example below will serialize and then de-serialize an instance of the Parent class into an array of bytes and vice versa.
The public method, public GetObjectData (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) , is called upon serialization of type Pet; first add an Int32 value indicating the number of items in the Toys list. Then add each Toy from the list.
The protected constructor Pet (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) is called when this type is de-serialized. First we read the number of items that have been saved in the Toys list, then use this to read each instance of Toy from a serialized stream.
Note that for each instance of Toy added to the serialized stream, we give it a different name; in this case, we simply added the index value to the word "Toy"; that is, "Toy1", "Toy2", ... This is because each element in the serialized stream needs a unique name. See: System.Runtime.Serialization.ISerializable .
And by controlling the serialization / de-serialization of the Toys list in Pet, we can fix the problem of the inability to serialize / de-serialize the list based on: NHibernate.Collection.Generic. PersistentGenericBag .
using System; using System.Collections.Generic; using System.Linq; using System.Text; static class Program { static void Main(string[] args) { Parent p = new Parent(); p.child = new Child(); p.child.GrandChildren = new List<GrandChild>(); p.child.GrandChildren.Add(new GrandChild { pet = new Pet() }); p.child.GrandChildren.First().pet.Toys = new List<Toy>(); p.child.GrandChildren.First().pet.Toys.Add(new Toy { ToyName = "Test" }); byte[] result = Serialize(p); Parent backAgain = Deserialize(result); } public static System.Runtime.Serialization.Formatters.Binary.BinaryFormatter BinarySerializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); public static byte[] Serialize(Parent p) { using (var ms = new System.IO.MemoryStream()) { BinarySerializer.Serialize(ms, p); return ms.ToArray(); } } public static Parent Deserialize( byte[] data) { using (var ms = new System.IO.MemoryStream(data)) { return (Parent)BinarySerializer.Deserialize(ms); } } } [Serializable] public class Parent { public virtual Child child { get; set; } } [Serializable] public class Child { public virtual ICollection<GrandChild> GrandChildren { get; set; } } [Serializable] public class GrandChild { public virtual Pet pet { get; set; } } [Serializable] public class Pet : System.Runtime.Serialization.ISerializable { public Pet() { }
source share