C# XML serialization of derived classes
[XmlInclude(typeof(Square))]public abstract class Shape {...}
(repeat for all known subtypes)
If the types are only known at runtime, you can supply them to the XmlSerializer
constructor, but: then it is important to cache and reuse that serializer instance; otherwise you will haemorrhage dynamically created assemblies. It does this automatically when you use the constructor that just takes a Type
, but not for the other overloads.
Solution:
class Program { static void Main(string[] args) { Shape[] a = new Shape[2] { new Square(1), new Triangle() }; FileStream fS = new FileStream("C:\\shape.xml",FileMode.OpenOrCreate); //this could be much cleaner Type[] t = { a[1].GetType(), a[0].GetType() }; XmlSerializer xS = new XmlSerializer(a.GetType(),t); Console.WriteLine("writing"); try { xS.Serialize(fS, a); } catch (Exception e) { Console.WriteLine(e.InnerException.ToString()); Console.ReadKey(); } fS.Close(); Console.WriteLine("Fin"); } }namespace XMLInheritTests{ [XmlInclude(typeof(Square))] [XmlInclude(typeof(Triangle))] public abstract class Shape { public Shape() { } public int area; public int edges; }}
Thanks; I no doubt will have another problem very soon :S
You can use XmlArrayItem to get around this:
public class XMLFile{ [XmlArray("MasterFiles")] [XmlArrayItem("Supplier", typeof(Supplier))] [XmlArrayItem("Customer", typeof(Customer))] public List<MasterElement> MasterFiles;}
From the linked MSDN:
The XmlArrayItemAttribute supports polymorphism--in other words, it allows the XmlSerializer to add derived objects to an array.