简体   繁体   中英

Why can XmlSerializer serialize abstract classes but not interfaces?

Edit This code should illustrate the whole problem:

[XmlInclude(typeof(AThing1))]
public abstract class AThing
{
    public abstract string Name { get; set; }
}

[XmlInclude(typeof(IThing1))]
public interface IThing
{
    string Name { get; set; }
}

public class AThing1 : AThing
{
    public override string Name { get; set; }
}

public class IThing1 : IThing
{
    public string Name { get; set; }
}

List<AThing> aThings = new List<AThing>(new AThing[] { new AThing1() { Name = "Bob" } });
List<IThing> iThings = new List<IThing>(new IThing[] { new IThing1() { Name = "Bob" } });

public void Test()
{
    using (StringWriter sw = new StringWriter())
    {
        XmlSerializer aSerializer = new XmlSerializer(typeof(List<AThing>));
        aSerializer.Serialize(sw, aThings);
        string text = sw.ToString();
    }

    using (StringWriter sw = new StringWriter())
    {
        // This line will throw "Cannot serialize interface IThing.":
        XmlSerializer iSerializer = new XmlSerializer(typeof(List<IThing>));    
        iSerializer.Serialize(sw, iThings);
        string text = sw.ToString();
    }
}

The first text generated by aSerializer will be:

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfAThing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <AThing xsi:type="AThing1">
    <Name>Bob</Name>
  </AThing>
</ArrayOfAThing>

I don't see why can't iSerializer do this:

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfIThing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <IThing xsi:type="IThing1">
    <Name>Bob</Name>
  </IThing>
</ArrayOfIThing>

instead of throwing an exception.

you can serialize interface, but not as simple as classes:

http://ventspace.wordpress.com/2010/02/20/how-to-serialize-interfaces-in-net/

but to answer your question I have 2 guesses on this:

The first reason is from the practical side; The semantics of serializing an interface are a little bit blurry. What do you you think the serializer should serialize when you pass in an interface reference ? If you only serialize the interface properties your deserialize then could wind up with a half-way uninitialized object. There's no telling what that would do to your application.

If you serialize the full object together with the type information then serializing the interface really did not buy you anything. You could type the reference as a class type in the first place if your application really cares what object is there.

The second one goes with the stated purpose of the XmlSerializer. Despite the misleading name XML Serialization in the .NET Framework really is a data binding technology with the primary intention to map MXL data types defined in XSD schemas to .NET types. The XSD definition knows about abstract base classes, but since it's data centric, does not know anything about interfaces. With that in mind there is little motivation to support interfaces in the XmlSerializer.

The XmlSerializer is not serializing abstract classes. It is serializing one of several concrete classes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM