You can not technically. The problem isn't serialization as much as it deserialization.
Since an interface is an abstraction the deserializer can not simply create an instance
of the interface. The same problem occurs with abstract classes as well.
Given the following code serialization will work properly.
public interface IItem
{
string Name { get; set; }
}
[Serializable]
public class Item : IItem
{
private string m_strName;
public string Name
{
get { return m_strName; }
set { m_strName = value; }
}
}
[Serializable]
public class Book : Item
{ }
class Program
{
static void Main ( string[] args )
{
Item item = new Book(); // #1
item.Name = "Hello";
using (StreamWriter sw = new StreamWriter(@"c:\temp\test.xml"))
{
XmlSerializer serializer = new XmlSerializer(typeof(Item));
// #2
serializer.Serialize(sw, item);
};
}
}
If line 2 is changed to IItem then serialization will fail with an error
saying that the interface can not be serialized. As it does not have an implementation
there is nothing meaningful that can be generated for it. You might think
that the serializer could simply use the type information from the object being
serialized but remember that the serialization "schema" is determined by the type
that you pass to the constructor.
If Item is changed to abstract then serialization will fail because the serializer
can not determine how to serialize the class. This time we get a general error.
Since we used Item for the type in the XmlSerializer constructor
that is the type that it tried to serialize. If we had used item.GetType
instead it would have worked.
Remember that the type used in the constructor is the type that is used for serialization.
If we were to add a new property/field to Book then that data would not
be serialized because we were using the Item base type. You must
be careful when serializing data using base types.
So how do you serialize an interface? The only real solution is to serialize
the actual underlying object. This pretty much mandates that you override
ISerializable and/or IXmlSerializable. You
could expose a public property/field that holds the real type but then you are messing
up the design of your class.