XML Serialize / Deserialize Abstract Types

xtopher.brandt_at_gmail.com
Date: 02/24/05


Date: 24 Feb 2005 10:45:58 -0800

I'm sure this problem has come up, but I haven't been able to find a
good discussion of it.

I have a type Animal which is an abstract base class. From that type I
derive Horse and Dog which are concrete classes. I include an Animal in
my BarnYardStall type. Now I want to serialize BarnYardStall to XML,
ship the XML somewhere and deserialize it back to a BarnYardStall.

The only way I can find to make this work is to add an XmlElement
attribute for each derived type of Animal to the Animal property in
BarnYardStall. The obvious problem with this approach is that I may
need to use Animal in other types, such as Stock, History,.... And I
may add new types of derived Animals such as Cat and Cow. When I add
these new Animal derivations, I have to also add an associated
XmlElement attribute to EVERY class that needs to serialize an Animal.
That's a huge problem.

My expectation is that I should be able to add the XmlInclude attribute
to the abstract Animal class. But this doesn't work, and I suspect,
based on the documentation, that it was intended for SOAP methods.

Here is the code:

public abstract class Animal
{
   private String name;
   public String Name
   {
     get{ return this.name }
     set{ this.name = value }
   }
}

public class Horse : Animal
{
}

public class Dog : Animal
{
}

[XmlRoot]
public class BarnYardStall
{
   private Animal occupant;

   [XmlElement ( ElementName="Horse", Type=typeof(Horse) )]
   [XmlElement ( ElementName="Dog", Type=typeof(Dog) )]
   public Animal Occupant
   {
       get { return this.occupant }
       set { this.occupant = value }
   }
}

[XmlRoot]
public class Stock
{
   private Animal[] animalList;

   [XmlArray( "Animals" )]
   [XmlArrayItem( "Dog", typeof(Dog) )]
   [XmlArrayItem( "Horse", typeof(Horse) )]
   public Animal[] AnimalList
   {
       get { return this.animalList}
       set { this.animalList= value }
   }
}



Relevant Pages

  • compile error problems
    ... public class Chicken: Animal ... public override void MakeANoise() ... public class SuperCow: Cow ... foreach (T animal in animals) ...
    (microsoft.public.dotnet.languages.csharp)
  • cant call super from method but I need to??
    ... how can I call animals growl while within a method of my ... public void growl() { ... public class dog extends animal { ... IDefaultCall default = new IDefaultCall { ...
    (comp.lang.java.programmer)
  • Re: Generic inheritance
    ... public class Chicken: Animal ... The fact that the Animal class is abstract doesn't disqualify it from being used as T in the Farm class. ... If you create some Cow instances and some Chicken instances and put in the Farm, and then loop through the contents of the farm, you will get Animal references: ... In the Farmclass you can do anything to the animals that is defined in the Animal class. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Implementing an interface with qualified templates
    ... public class Fish: Animal ... public interface IZoowhere T: ... ListAnimals ...
    (microsoft.public.dotnet.languages.csharp)