序列化接口

Sha*_*har 11 c# xml-serialization

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

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    [Serializable]
    [XmlInclude(typeof(List<Class2>))]
    public class Class1
    {
        private IList<Class2> myArray;

        public IList<Class2> 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<Class2>) });
            FileStream stream = File.OpenWrite("Data.xml");
            ser.Serialize(stream, new List<Class1>());
            stream.Close();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我得到一个:

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

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

Joh*_*ers 15

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

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

它将如何反序列化?

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

  • @JohnSaunders,当你说"你做不到"时,你的第一段是对的.你所说的其他一切都试图证明为什么会出现这种情况.这些理由是虚假的.获取一个接口,并将其替换为没有成员的抽象类.这并不会改变代码的工作方式.突然你可以序列化了! (20认同)
  • @Shahar:是的.不要_do_那个.使用具体类型,而不是界面. (3认同)
  • 另外,你在上面的评论中说过"不要那样做". (3认同)
  • 它将如何反序列化?作为被序列化的类的实例,和List&lt;object&gt;一样。什么类将用于反序列化另一端的接口?见第一个答案。 (2认同)

H.B*_*.B. 14

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

private IList<Class2> myArray;
[XmlIgnore]
public IList<Class2> MyArray
{
    get { return myArray; }
    set { myArray = value; }
}

[XmlElement("MyArray")]
public object MyArraySerializable
{
    get { return MyArray; }
    set { MyArray = value as IList<Class2>; }
}
Run Code Online (Sandbox Code Playgroud)

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


我认为没有理由为什么任何序列化程序都无法序列化这些属性.它不像你真正尝试序列化的界面,你尝试序列,它实现某个接口(这是不是从抽象的子类大不相同,一些编程语言甚至仅仅在接口上运行)的对象.

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

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

  • 阿门.在这方面,序列化器是愚蠢的!谢谢你的解决方案.使用接口要好得多,因为继承仅限于一个基类. (2认同)