2

我正在使用第三方 dll,我需要在其中序列化 1 个复杂对象以存储在文件中,以便我可以对后者进行反序列化。我试图通过 XML 序列化程序进行序列化,但出现错误“反映属性'通知'的错误”。我在元数据中看到 Notification 类型没有 Serializable 属性,而其他类型的复杂对象具有 Serializable 属性。

我无法控制第三方 dll,如何序列化这个复杂对象以保存在文件中?

提前致谢

4

3 回答 3

1

如果您需要使用 XmlSerializer,一个选项是 XmlAttributeOverrides - 这使用起来非常麻烦,但允许您指定在运行时而不是在编译时如何对其进行序列化。但是,您确实需要缓存并重新使用序列化程序实例 - 否则您将泄漏内存(每个序列化程序实例的整个程序集)。

但是,一个更好的选择可能是(这是我在序列化变得远程棘手通常的指导):创建一组单独的序列化类型 - 如果您愿意,可以创建一个“DTO 层”。这些 DTO 类型应该:

  • 简单(只有数据,没有真正的逻辑)
  • 以序列化程序想要工作的方式构建
  • 包含序列化程序感兴趣的任何元数据等
  • 与您的实际实体类型有某种映射

然后,与其试图让序列化程序使用敌对类型,不如编写简单的代码在 DTO 和域实体之间进行映射 - 序列化程序可以使用它认为方便的类型。

其他优点:

  • 它迫使你从“数据”而不是“实施”的角度思考
  • 它允许你在不影响序列化的情况下重构你的域实体——它只是改变了“它们之间的映射”代码
于 2013-06-27T05:25:48.737 回答
0

通常不会尝试盲目地序列化自定义对象。在不知道它们的内部结构的情况下,您将不会获得反序列化结果的最佳结果。

作为一个类型的示例,您可以轻松地序列化:

public class Foo
{
    public string Bar { get; set; }
    public string Baz { get; set; }
    public string Qux { get; set; }
}

您知道内部结构,因此您可以轻松地读取和写入属性。

但是类似的东西DateTime呢?如果您只是根据它的公共属性进行序列化,那么您将有16 个值要编写!如果我们深入研究内部,我们会发现它DateTime可以用一个 64 位整数表示。但即便如此,您也不太可能将该值用于序列化。相反,我们通常定义一种人类和计算机都可以理解的字符串格式,也许是2013-06-26T01:23:45. 该值是可以序列化的多种方式之一,它不是任何公共属性。

因此,如果您有想要序列化的第三方复杂对象,请考虑以下几点:

  • 完全重建这个对象需要什么数据?
  • 对象直接暴露了哪些数据?
  • 我必须计算或重新格式化哪些部分?
  • 我序列化的格式是否是所有数据使用的最佳格式,包括存储和传输问题?
  • 反序列化时数据是否会被不同地解释,可能是基于文化或语言细节?

然后你可能知道如何为这个自定义对象实现一个序列化器。通常只需查看一个公共属性而不是所有公共属性,并通过在构造函数中使用此值进行反序列化。

于 2013-06-27T05:58:41.460 回答
0

除非您确实需要将对象保存为 XML,否则请查看使用二进制序列化器 - http://www.java2s.com/Code/CSharp/File-Stream/BinarySerializer.htm

任何对象都可以使用它保存和加载,缺点是该文件不是人类可读的,如果您需要将其加载到非 .net 应用程序中,它可能会变得混乱。

于 2013-06-28T10:29:00.817 回答