Quantcast
Channel: Dotnet/C# – Xinyustudio
Viewing all articles
Browse latest Browse all 204

Serialize & Deserialize derived class insances in generic List: Problems & Solutions

$
0
0

There have been numerous discussions on serialize & deserialize derived class insances to and from generic List<T> and XML files. The problem is when you declare the collection as List<BaseClass>, there is no problem in serialization, but you will have a hard time in retrieving data from XML files. Simply reasonable, the List<BaseClass> does not serialize the derived instances’ type information, and it is ignorant which subclass instances to convert to, when deserializtion takes place.

Numerous discussions can be found on the web, and to list a few:

Although there have been many solutions to tackle the problems, however there seems to be no generic implementation that make save/read XML to and from list or collections. What is expected is not a wrapper in the form that:

class Wrapper { public Collection<Item> Items { get; set; } public string Name { get; set; } }

As this will introduce a new hierarchy in the XML.

A perferable data structure would be: XList<T> that support to serialize and deserialize the derived types, and here comes the solution, and similar approaches can be found on the web, and I just encapsulate them into a single class XList<T>.

Usage:

AA D1=new AA(); //Derived type BB D2=new BB(); //Derived type CC D3=new CC(); //Derived type X D4=new X(); //Base Class XList<X> AllData=new XList<X>(); AllData.Add(D1); AllData.Add(D2); AllData.Add(D3); AllData.Add(D4); // ----------------------------------- AllData.Save(@"C:\Temp\Demo.xml"); // ----------------------------------- // Retrieve data from XML file // ----------------------------------- XList<X> AllData=new XList<X>(); AllData.Open(@"C:\Temp\Demo.xml"); // -----------------------------------


For those who wish to know the technical details, the below highlights some interesting points:

  1. The use of XmlInclude attributes is cumbersome to maintain the code
  2. The proposed implementation derives from:
    public class XList<T> : Collection<T>, IXmlSerializable

    Impementing IXmlSerializable enables custom serialization to be controlled at a better granuar level.

  3. The reason why it does not derive from List<T> is that the List<T> does not expose “Items” property, which is highly expected.
  4. The trick to achieve the aforementioned functionality to convert the internal IList<T> Items to/from List<T> during the serialization and deserialization, as IList<T> does not provide functionalities for serialization/deserialization. You will encounter the exception “Cannot serialize interface System.Collections.Generic.IList`1[ … ]” if you directly use IList<T> Items offered by Collection<T>.

A test project is developed to demonstrated the use of this handy class.

SerializeDerivedClass

Download the demo project source here or click this link.

Comments and ranking of this post are strongly welcome. Let me know your feedback!


Filed under: Dotnet/C#

Viewing all articles
Browse latest Browse all 204

Trending Articles