Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serialize the base class with derived classes

.

Hello,

I have this sample code :

public class Vehicule
{
    public string Name { get; set; }
    public Brand Brand { get; set; }
}
public class Car : Vehicule
{
    public string Matriculation { get; set; }
}



public class Brand
{
    public string Name { get; set; }
}
public class Renault : Brand
{
    public string Information { get; set; }
}

If I create this instance :

var car = new Car { Name = "Clio", Matriculation = "XXX-XXX", Brand = new Renault { Name = "Renault", Information = "Contact Infos" } };

When I serialize this object like that :

var serializer = new XmlSerializer(typeof(Car), new Type[] { typeof(Renault)});
serializer.Serialize(wr, car);

I obtain this :

<?xml version="1.0" encoding="utf-8"?>
<Car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Clio</Name>
  <Brand xsi:type="Renault">
    <Name>Renault</Name>
    <Information>Contact Infos</Information>
  </Brand>
  <Matriculation>XXX-XXX</Matriculation>
</Car>

But, in my project, I don't have to have informations on derived classes, I would like only elements of base classes from this instance like this :

var serializer = new XmlSerializer(typeof(Vehicule));
serializer.Serialize(wr, car);

The Xml :

<?xml version="1.0" encoding="utf-8"?>
<Vehicule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Clio</Name>
  <Brand>
    <Name>Renault</Name>
  </Brand>
</Vehicule>

Can you please, help me to obtain the good Xml (only with base type Vehicule and Brand) ?

Many thanks

like image 592
Bob Avatar asked Aug 26 '14 17:08

Bob


People also ask

Can a class be both a base class and a derived class?

A derived class can have only one direct base class.

What is the relationship between a base class and a derived class called?

The Base class members and member functions are inherited to Object of the derived class. A base class is also called parent class or superclass. Derived Class: A class that is created from an existing class.

Can serializable class inherited?

You must explicitly mark each derived class as [Serializable] . If, however, you mean the ISerializable interface, then yes: interface implementations are inherited, but you need to be careful - for example by using a virtual method so that derived classes can contribute their data to the serialization.

Can base class access derived class properties?

No, you cannot access any derived class members using base class pointer even pointing to a derived class instance. However you can access those values though methods of derived class.


Video Answer


1 Answers

You can't magically serialize a derived class as it's base because

"...Serialization checks type of instance by calling Object.getType() method. This method always returns the exact type of object."

http://bytes.com/topic/net/answers/809946-how-force-serialize-base-type

The solution here, if you really need to only serialize the base class is to implement the IXmlSerializable interface and create your own custom serializer.

IXmlSerializable: http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable(v=vs.110).aspx

One more thought. If you can work around the limitation of outputting the extra XML elements, you are able to serialize the derived class using only the base object by either 1) using XmlIncludeAttributes on the base class to tell it which types to expect or 2) using the XmlSerializer constructor overload that takes a list of types.

Edit: After thinking about this a little more, a workaround would be that you would add a Clone() method onto your base object, then serialize the clone of the base.

LinqPad code:

public class Vehicule
{
    public string Name { get; set; }
    public Brand Brand { get; set; }

    public Vehicule Clone()
    {
        return new Vehicule { Name = this.Name, Brand = new Brand { Name = this.Brand.Name } };
    }
}
public class Car : Vehicule
{
    public string Matriculation { get; set; }
}



public class Brand
{
    public string Name { get; set; }
}
public class Renault : Brand
{
    public string Information { get; set; }
}

void Main()
{   
    var car = new Car { Name = "Clio", Matriculation = "XXX-XXX", Brand = new Renault { Name = "Renault", Information = "Contact Infos" } };
    var vehicle = car as Vehicule;

    var serializer = new System.Xml.Serialization.XmlSerializer(typeof(Vehicule));

    XmlWriterSettings settings = new XmlWriterSettings
    {
        Encoding = new UnicodeEncoding(false, false),
        Indent = false,
        OmitXmlDeclaration = false
    };

    using(StringWriter textWriter = new StringWriter())
    using(XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings)) {
        serializer.Serialize(xmlWriter, vehicle.Clone());
        textWriter.ToString().Dump();
    }
}
like image 87
Wyatt Earp Avatar answered Oct 21 '22 03:10

Wyatt Earp