XML Serialize a generic list of serializable objects with an abstract base class

Any good example of how to serialize a list of shared objects with an abstract base class. Samples with a non-abstract base class are listed in XML. Serialize a generic list of serializable objects . My base class is similar to Microsoft.Build.Utilities.Task

+6
source share
2 answers

It is often useful to have abstract classes with several derived types to allow the use of strongly typed lists and such.

For example, you might have a DocumentFragment class that is abstract and two specific classes called TextDocumentFragment and CommentDocumentFragment (this example from Willis).

This allows you to create a List property that can contain objects of only these two types.

If you try to create a WebService that returns this list, you will get an error, but it is easy to get around with the code below ....

[Serializable()] [System.Xml.Serialization.XmlInclude(typeof(TextDocumentFragment))] [System.Xml.Serialization.XmlInclude(typeof(CommentDocumentFragment))] public abstract class DocumentFragment { ...} 

The XmlInclude attributes indicate to the class that it can be serialized for these two derived classes.

This generates an attribute in the DocumentFragment element that defines the actual type, as shown below.

 <DocumentFragment xsi:type="TextDocumentFragment"> 

Any additional properties specific to the derived class will also be included using this method.

+4
source

Another alternative is to use XmlElementAttribute to move the list of known types to the generic list itself ...

 using System; using System.Xml; using System.Xml.Serialization; using System.Collections.Generic; public abstract class Animal { public int Weight { get; set; } } public class Cat : Animal { public int FurLength { get; set; } } public class Fish : Animal { public int ScalesCount { get; set; } } public class AnimalFarm { [XmlElement(typeof(Cat))] [XmlElement(typeof(Fish))] public List<Animal> Animals { get; set; } public AnimalFarm() { Animals = new List<Animal>(); } } public class Program { public static void Main() { AnimalFarm animalFarm = new AnimalFarm(); animalFarm.Animals.Add(new Cat() { Weight = 4000, FurLength = 3 }); animalFarm.Animals.Add(new Fish() { Weight = 200, ScalesCount = 99 }); XmlSerializer serializer = new XmlSerializer(typeof(AnimalFarm)); serializer.Serialize(Console.Out, animalFarm); } } 

..., which will also lead to more convenient XML output (without the ugly xsi:type attribute) ...

 <?xml version="1.0" encoding="ibm850"?> <AnimalFarm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Cat> <Weight>4000</Weight> <FurLength>3</FurLength> </Cat> <Fish> <Weight>200</Weight> <ScalesCount>99</ScalesCount> </Fish> </AnimalFarm> 
+11
source

Source: https://habr.com/ru/post/908244/


All Articles