序列化接口

我正在尝试运行与此类似的代码:

using System; using System.Collections.Generic; using System.IO; using System.Xml.Serialization; namespace ConsoleApplication1 { [Serializable] [XmlInclude(typeof(List))] public class Class1 { private IList myArray; public IList MyArray { get { return myArray; } set { myArray = value; } } } public class Class2 { private int myVar; public int MyProperty { get { return myVar; } set { myVar = value; } } } class Program { static void Main(string[] args) { XmlSerializer ser = new XmlSerializer(typeof(Class1), new Type[] { typeof(List) }); FileStream stream = File.OpenWrite("Data.xml"); ser.Serialize(stream, new List()); stream.Close(); } } } 

有人可以向我解释我做错了什么吗?

我得到一个:

无法序列化成员.. MyArray …因为它是一个接口。

XmlInclude不应该解决这个问题吗?

不可以。您无法序列化界面。 永远。 它只是告诉你。

界面只不过是对一组行为的描述。 它没有说明实例的内容。 特别是,虽然实现接口的类的实例必须实现其所有成员,但它肯定具有自己需要序列化的属性。

如何反序列化?

将使用哪个类来反序列化另一端的接口?

这是一个未经测试的阴暗解决方案,我倾向于原则​​上使用:

 private IList myArray; [XmlIgnore] public IList MyArray { get { return myArray; } set { myArray = value; } } [XmlElement("MyArray")] public object MyArraySerializable { get { return MyArray; } set { MyArray = value as IList; } } 

这将序列化您可能使用的任何列表作为具有type属性的通用对象,该属性将告诉反序列化器对象的实际类型,因此当该对象被反序列化时,它应该再次转换为IList 。 请记住提供界面可能采用的任何类型。


我认为没有理由为什么任何序列化程序都无法序列化这些属性。 它不像你实际上尝试序列化一个接口,你试图序列化一个实现某个接口的对象(这与抽象子类化差别不大,一些编程语言甚至只能在接口上运行)。

当序列化程序应序列化该对象时, 它知道该对象实现了该接口,它真正需要做的就是序列化它并附加type属性(就像你通常序列化抽象类或只是超类一样)。

现在,反序列化器查看类型并可以检查该对象是否实际上实现了所需的接口,然后将其反序列化为相应的属性。

或者使用DataContractSerializer 。

你包括了typeof(List <...>),但MyArray属于IList <...>类型,它本身没有明显的数据结构,但更多的是占位符来获取一些数据结构。

将MyArray的类型更改为特定类型(例如List),它应该可以工作。

  private List myArray; public List MyArray { get { return myArray; } set { myArray = value; } }