473,396 Members | 2,147 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Serializing instances of derived classes


Imagine one writing a class library CL1 for data storage.
He defines classes ‘DataItem’ and ‘DataRecord’ so that the latter contains
a collection of the former.
And he derives class ‘IntItem’ from ‘DataItem’

[XmlRoot ("DataItem")]
[XmlInclude (typeof (IntItem))]
public class DataItem
{
public DataItem() {}
public DataItem (string name)
{
_name = name;
}

private string _name;

[XmlAttribute]
public string Name
{
get { return _name; }
set { _name = value; }
}
}

[XmlRoot ("IntItem")]
public class IntItem : SerializeDerivedClass.DataItem
{
public IntItem(){}
public IntItem (string name, int intValue) : base (name)
{
_intValue = intValue;
}

private int _intValue;

[XmlAttribute ("IntValue")]
public int IntValue
{
get { return _intValue; }
set { _intValue = value; }
}
}

[XmlRoot ("DataRecord")]
public class DataRecord
{
public DataRecord() {}

private DataItem [] _data;

[XmlElement ("DataItem", typeof (DataItem))]
[XmlElement ("IntItem", typeof (IntItem))]
public DataItem [] Data
{
get { return _data; }
set { _data = value; }
}
}

Now the following code works fine.

DataRecord rec = new DataRecord ();
rec.Data = new DataItem [3];
rec.Data [0] = new DataItem ("DI-1");
rec.Data [1] = new IntItem ("II-1", 3);

XmlSerializer xser = new XmlSerializer (typeof (DataRecord));

xser.Serialize (Console.Out, rec);

Its output is

<DataRecord>
<DataItem Name="DI-1" />
<IntItem Name="II-1" IntValue="3" />
</DataRecord>

Now another developer creates another class library CL2 containing class
‘DoubleItem’
derived from ‘DataItem’. Of course, the second developer wishes the code
above
including the following line to work too

Rec.Data [2] = new DoubleItem (“DblI-1”, Math.PI);

[XmlRoot ("DoubleItem")]
public class DoubleItem : SerializeDerivedClass.DataItem
{
public DoubleItem(){}
public DoubleItem (string name, double doubleValue) : base (name)
{
_doubleValue = doubleValue;
}

private double _doubleValue;

[XmlAttribute ("DoubleValue")]
public double DoubleValue
{
get { return _doubleValue; }
set { _doubleValue = value; }
}
}

This should produce

<DataRecord>
<DataItem Name="DI-1" />
<IntItem Name="II-1" IntValue="3" />
<DoubleItem Name=”DblI-1” DoubleValue=”3.1415..”/>
</DataRecord>

Can this behavior be achieved without rebuilding the first class library
CL1?
Why 'DoubleItem' is "not expected" while every instance
of 'DoubleItem' is 'DataItem'?

Aleksei Guzev
Nov 12 '05 #1
2 3264
Aleksei,

Are you instantiating the XmlSerializer in CL1 or CL2?

If you are instantiating in CL1, then there is indeed no way to make
this work without rebuilding. Otherwise you could pass the Type
DoubleItem to the constructor of the XmlSerializer:

XmlSerializer xser = new XmlSerializer (typeof (DataRecord), new Type[]
{typeof(DoubleItem)});

However, this will probably not produce the XML format you're looking
for:

<?xml version="1.0" encoding="IBM437"?>
<DataRecord xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w
3.org/2001/XMLSchema-instance">
<DataItem Name="DI-1" />
<IntItem Name="II-1" IntValue="3" />
<DataItem xsi:type="DoubleItem" Name="DblI-1"
DoubleValue="3.1415926535897931"
/>
</DataRecord>

The DoubleItem is serialized as a <DataItem> element.

If you need to customize the format, then you can override the
serialization attributes on the Data property in the DataRecord class.
The code goes like this:

XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes dataAttributes = new XmlAttributes();
dataAttributes.XmlElements.Add( new XmlElementAttribute( "DoubleItem",
typeof(DoubleItem) ) );
dataAttributes.XmlElements.Add( new XmlElementAttribute( "DataItem",
typeof(DataItem) ) );
dataAttributes.XmlElements.Add( new XmlElementAttribute( "IntItem",
typeof(IntItem) ) );
overrides.Add( typeof( DataRecord ), "Data", dataAttributes );

XmlSerializer xser = new XmlSerializer (typeof (DataRecord), overrides,
new Type[0], null, "" );

xser.Serialize (Console.Out, rec);

and you get the format you were looking for:

<?xml version="1.0" encoding="IBM437"?>
<DataRecord xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w
3.org/2001/XMLSchema-instance">
<DataItem Name="DI-1" />
<IntItem Name="II-1" IntValue="3" />
<DoubleItem Name="DblI-1" DoubleValue="3.1415926535897931" />
</DataRecord>

Notice here the attributes in the XmlAttributeOverrides collection
override all attributes in the original class. They are not added, to
the existing ones. You have to add the attributes for the DataItem and
IntItem types again, too.

HTH,
Christoph Schittko
MS MVP XML
http://weblogs.asp.net/cschittko
-----Original Message-----
From: Aleksei Guzev [mailto:al***********@bigfoot.com]
Posted At: Thursday, November 25, 2004 4:13 AM
Posted To: microsoft.public.dotnet.xml
Conversation: Serializing instances of derived classes
Subject: Serializing instances of derived classes
Imagine one writing a class library CL1 for data storage.
He defines classes 'DataItem' and 'DataRecord' so that the latter contains a collection of the former.
And he derives class 'IntItem' from 'DataItem'

[XmlRoot ("DataItem")]
[XmlInclude (typeof (IntItem))]
public class DataItem
{
public DataItem() {}
public DataItem (string name)
{
_name = name;
}

private string _name;

[XmlAttribute]
public string Name
{
get { return _name; }
set { _name = value; }
}
}

[XmlRoot ("IntItem")]
public class IntItem : SerializeDerivedClass.DataItem
{
public IntItem(){}
public IntItem (string name, int intValue) : base (name)
{
_intValue = intValue;
}

private int _intValue;

[XmlAttribute ("IntValue")]
public int IntValue
{
get { return _intValue; }
set { _intValue = value; }
}
}

[XmlRoot ("DataRecord")]
public class DataRecord
{
public DataRecord() {}

private DataItem [] _data;

[XmlElement ("DataItem", typeof (DataItem))]
[XmlElement ("IntItem", typeof (IntItem))]
public DataItem [] Data
{
get { return _data; }
set { _data = value; }
}
}

Now the following code works fine.

DataRecord rec = new DataRecord ();
rec.Data = new DataItem [3];
rec.Data [0] = new DataItem ("DI-1");
rec.Data [1] = new IntItem ("II-1", 3);

XmlSerializer xser = new XmlSerializer (typeof (DataRecord));

xser.Serialize (Console.Out, rec);

Its output is

<DataRecord>
<DataItem Name="DI-1" />
<IntItem Name="II-1" IntValue="3" />
</DataRecord>

Now another developer creates another class library CL2 containing class 'DoubleItem'
derived from 'DataItem'. Of course, the second developer wishes the code above
including the following line to work too

Rec.Data [2] = new DoubleItem ("DblI-1", Math.PI);

[XmlRoot ("DoubleItem")]
public class DoubleItem : SerializeDerivedClass.DataItem
{
public DoubleItem(){}
public DoubleItem (string name, double doubleValue) : base (name)
{
_doubleValue = doubleValue;
}

private double _doubleValue;

[XmlAttribute ("DoubleValue")]
public double DoubleValue
{
get { return _doubleValue; }
set { _doubleValue = value; }
}
}

This should produce

<DataRecord>
<DataItem Name="DI-1" />
<IntItem Name="II-1" IntValue="3" />
<DoubleItem Name="DblI-1" DoubleValue="3.1415.."/>
</DataRecord>

Can this behavior be achieved without rebuilding the first class library CL1?
Why 'DoubleItem' is "not expected" while every instance
of 'DoubleItem' is 'DataItem'?

Aleksei Guzev


Nov 12 '05 #2
Thanks. This is just what I was looking for.

On Fri, 26 Nov 2004 20:30:42 -0600, Christoph Schittko [MVP]
<IN**********@austin.rr.com> wrote:
Are you instantiating the XmlSerializer in CL1 or CL2?

I am instantiating the serializer in the third module,
which is using both libraries. It knows DoubleItem unlike CL1.
XmlSerializer xser = new XmlSerializer (typeof (DataRecord), overrides,
new Type[0], null, "" );

If a class is referred in the overrides then it does not need to be
specified
in extraTypes to the serializer constructor.
At first, I've thought "new Type [0]" was an error in Your code ;)
Notice here the attributes in the XmlAttributeOverrides collection
override all attributes in the original class. They are not added, to
the existing ones. You have to add the attributes for the DataItem and
IntItem types again, too.


But attributes applied to the fields of DataItem etc remain.

Thank You very much.

Aleksei Guzev
Nov 12 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Gonçalo Rodrigues | last post by:
Hi all, I have a template class (call it Object) whose instances have a variable size part - an array of of T objects. But this variable size part is fixed at creation time so instead of...
5
by: StuartM | last post by:
Can anybody point me towards a sample of serializing/deserializing specific classes that are derived from a generic class? Is it necessary to use a switch statement or can it be done in a more...
6
by: John Glover | last post by:
I'm having a very strange problem with XML serialization. I'm writing web services which pass instances of various classes back and forth as parameters and return values of web methods. The...
0
by: Redowl | last post by:
Apologies if this has been covered in an early question, but I am having difficulty serializing a derived class. The base class has a property which is marked as MustOverride, but when I serialize...
8
by: Manuel | last post by:
Hi! If I've a vector filled with abstract classes, can I push in it the derived classes too? Even if derived classes have new methods? I've done some experiments, and it seem I can push the...
6
by: ivan.leben | last post by:
I want to write a Mesh class using half-edges. This class uses three other classes: Vertex, HalfEdge and Face. These classes should be linked properly in the process of building up the mesh by...
26
by: nyathancha | last post by:
Hi, How Do I create an instance of a derived class from an instance of a base class, essentially wrapping up an existing base class with some additional functionality. The reason I need this is...
15
by: Bob Johnson | last post by:
I have a base class that must have a member variable populated by, and only by, derived classes. It appears that if I declare the variable as "internal protected" then the base class *can*...
0
by: Shaul | last post by:
Hi, My goal is to serialize a collection of type IList<AbstractClass> which contains derived objects instances. My domain object model is a bit complex so I've created a demmi one: public...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.