【问题标题】:XML serialization of interfaces接口的 XML 序列化
【发布时间】:2012-02-27 19:46:48
【问题描述】:

我需要序列化项目中的复杂对象并将它们放入数据库中。我想使用 XML 对它们进行序列化,以便更轻松地调试我的应用程序。

我的情况和本文描述的很相似:http://geekswithblogs.net/SoftwareDoneRight/archive/2008/01/16/how-to-serialize-an-interface-using-the-xmlserializer.aspx

所以我有一个包含属性的对象,该属性的类型由接口定义。然后我有不同的具体类型来实现它。

按照文章的方法,使用XmlInclude 属性,我获得了强耦合解决方案,但我的应用程序被构造为使用插件方法,所以我可以有很多我想要的接口实现。

有没有办法使用 xml 序列化来解决我的问题,或者我必须使用二进制序列化?

【问题讨论】:

    标签: c# .net xml serialization interface


    【解决方案1】:

    如果你想使用 XmlSerializer,你需要一个基类,而不是一个接口。

    XmlInclude 只是告诉序列化程序可能实现的一种方式。 另一种方法是将包含的类型实际传递给序列化程序。

    只需枚举应用程序中从基类派生的所有类型(使用反射),并将它们作为已知类型数组传递给序列化器:

    var serializer = new XmlSerializer(myBaseType, arrayOfConcreteImplementations);
    

    与 DataContractSerializer 完全相同:第二个参数是您可以使用反射找到的已知类型的集合),但使用它您可能能够支持接口...

    【讨论】:

    • 我认为您的解决方案不能完全解决我的问题...我可以递归地拥有包含“抽象类型属性”的对象:一个对象包含一个抽象属性,该抽象属性包含一个抽象属性...和等等……
    【解决方案2】:

    从 geekswithblogs.net 阅读您的帖子。我会建议你做二进制序列化。它很容易实现和维护(除非并且直到您更改类的限定名称)。 Binary Serializer 也对私有成员进行序列化。

    如何使用二进制序列化器

    /// <summary>
    /// Serializes the given object to byte stream
    /// </summary>
    public sealed class Serializer {
        /// <summary>
        /// Serializes the given object to byte stream
        /// </summary>
        /// <param name="objectToSeralize">Object to be serialized</param>
        /// <returns>byte array of searialize object</returns>
        public static byte[] Serialize(object objectToSeralize) {
            byte[] objectBytes;
            using (MemoryStream stream = new MemoryStream()) {
                //Creating binary formatter to serialize object.
                BinaryFormatter formatter = new BinaryFormatter();
    
                //Serializing objectToSeralize. 
                formatter.Serialize(stream, objectToSeralize);
                objectBytes = stream.ToArray();
            }
            return objectBytes;
        }
        /// <summary>
        /// De-Serialize the byte array to object
        /// </summary>
        /// <param name="arrayToDeSerialize">Byte array of Serialize object</param>
        /// <returns>De-Serialize object</returns>
        public static object DeSerialize(byte[] arrayToDeSerialize) {
            object serializedObject;
            using (MemoryStream stream = new MemoryStream(arrayToDeSerialize)) {
                //Creating binary formatter to De-Serialize string.
                BinaryFormatter formatter = new BinaryFormatter();
    
                //De-Serializing.
                serializedObject = formatter.Deserialize(stream);
            }
            return serializedObject;
        }
    }
    

    【讨论】:

    • 我想我会按照你的建议使用二进制序列化。你能告诉我我必须使用哪些类吗? (我从来没有使用过 .NET...)
    • 完美!非常非常感谢你! :) +1
    【解决方案3】:

    XmlSerializer 不支持接口的序列化。但是,如果您使用 KnownType 属性装饰您的属性,则可以使用 Data Contract Serializer。

    【讨论】:

    • 我从未使用过KnownType 属性,但阅读文档似乎是解决我的问题的另一个高耦合解决方案...
    • 你的接口也能实现 IXmlSerializable 吗?您必须在每种类型中实现 ReadXml 和 WriteXml,但可以使用 XmlSerializer 在第二个类中实现。
    【解决方案4】:

    我解决了这个问题,包括在接口中名为 SerializeMyself 的方法。我不知道这是否是最优雅的解决方案......但它对我有用。

    【讨论】:

    • 这是一种解决方法。您正在按照 geekswithblogs 博客中的建议自行序列化对象。如果它对你有用。
    猜你喜欢
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多