Alex Rivera | Logout

Polymorphic Types and IXmlSerializable

Asked 2009-03-10T19:18:04.677
9

The XML serialization in .NET allows polymorphic objects through the extraTypes[] parameter of the XmlSerializer constructor. It also allows customization of XML serialization for types that implement IXmlSerializable.

However, I’m unable to combine these two features – as demonstrated in this minimal example:

using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace CsFoo
{
    public class CustomSerializable : IXmlSerializable
    {
        public XmlSchema GetSchema() { return null; }
        public void ReadXml(XmlReader xr) { }
        public void WriteXml(XmlWriter xw) { }
    }

    class CsFoo
    {
        static void Main()
        {
            XmlSerializer xs = new XmlSerializer(
                typeof(object),
                new Type[] { typeof(CustomSerializable) });

        xs.Serialize(new StringWriter(), new CustomSerializable());
    }
}

The last line throws System.InvalidOperationException with this message:

The type CsFoo.CustomSerializable may not be used in this context to use CsFoo.CustomSerializable as a parameter, return type, or member of a class or struct, the parameter, return type, or member must be declared as type CsFoo.CustomSerializable (it cannot be object). Objects of type CsFoo.CustomSerializable may not be used in un-typed collections, such as ArrayLists.

Wading through the dynamically generated XML assemblies, we ultimately come back to .NET standard library code by calling:

System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(
     String, String, Object, Boolean) : Void

In turn, this leads to:

protected Exception CreateUnknownTypeException(Type type)
{
    if (typeof(IXmlSerializable).IsAssignableFrom(type))
    {
        return new InvalidOperationExce
Edit
Report

1 Answer

2

I was able to reproduce your problem, when using object:

XmlSerializer xs = new XmlSerializer(
    typeof(object),
    new Type[] { typeof(CustomSerializable) });

However, I then created a derived class of CustomSerializable:

public class CustomSerializableDerived : CustomSerializable
{
}

And tried to serialize it:

XmlSerializer xs = new XmlSerializer(
    typeof(CustomSerializable),
    new Type[] { typeof(CustomSerializableDerived) });

This worked.

So, it would appear that the problem is restricted to the case where you specify "object" as the type to serialize, but not if you specify a concrete base type.

I'll do some more research on this in the morning.

answered 2009-07-28T03:18:59.903

Your Answer