【问题标题】:How Serialization Works in .Net序列化如何在 .Net 中工作
【发布时间】:2009-01-21 19:26:04
【问题描述】:

我感觉这是一个转帖,但我似乎找不到任何关于它的好信息。我只是想知道序列化实际上是如何工作的(实际上是反序列化)。我想知道的是,如果说我有一个实际上不受私有字段支持的属性;即:

public string SomeProp {
   get {
      return GetValue("SomePropKey");
   }
   set{
      SetValue("SomePropKey", value);
   }
}

当我反序列化时,setter 会被调用吗? getter 在序列化时被调用,因为当我序列化对象时,正确的值被写入输出流。我知道这似乎是一个奇怪的情况,但到底发生了什么?或者我只是把这个复杂化了......

【问题讨论】:

    标签: .net serialization properties


    【解决方案1】:

    这完全取决于您用于序列化的机制。

    如果您使用的是 XmlSerialization,那么是的,setter 会被调用。

    如果您使用数据协定序列化(DataContractSerialization),那么如果您将 DataMember 属性应用于属性(而不是其支持字段),则将调用 getter/setter。

    如果您使用 .NET 中的原始序列化机制(IFormatter 实现),那么这种情况是不可能的,因为它只会序列化存储在字段中的值。

    【讨论】:

    • 谢谢,我们正在使用 XmlSerialization。对不起,我没有包括那个。再次感谢您!
    • XmlSerializer 序列化公共成员并调用零参数构造函数,这很烦人,因为它假定您在构建时要由业务逻辑执行的内容与反序列化时想要的内容相同。这可能适用于 99% 的课程,但这还不够好。 BinaryFormatter.Serialize(可能还有 SoapFormatter.Serialize)证明这个约束是不必要和可以避免的,而且它们也不需要你增加风险,因为私有成员是可序列化的。不幸的是 BinaryFormatter 和 SoapFormatter 已经过时了。
    • BinaryFormatter 被认为存在安全风险。 DataContractSerializer 在我看来比 XmlSerializer 更好。零参数构造函数没有限制,因此可以根据需要对其进行编码。风险较低,因为数据可以是私有的;人们无法忍受查看序列化的 XML 文件。 DataContract / DataMember 属性令人讨厌但可以接受。
    • DataMember 在 set/get 字段上的修饰意味着访问器将在序列化/反序列化时运行。我更喜欢将 DataMember 装饰放在后备存储上,因为我不认为 set/get 业务逻辑总是与序列化/反序列化相关,并且决定它是相关的似乎使约束永久化。无需将 DataMember 属性同时放在后备存储和属性上,这些属性可能因为很明显而未记录,或者由于文档未完善而可能未记录。
    • XmlSerializer 的更多问题:它无法序列化字典。如果您的类实现了 IEnumerable,那么 XmlSerializer 会将对象视为只是一个可枚举的对象,并且它将忽略其他成员数据并且不对其进行序列化。
    【解决方案2】:

    您是在谈论 XML 序列化还是“常规”序列化(soap / 二进制),因为 -afaik- 这两种序列化技术不同。

    AFAIK,如果您使用 BinaryFormatter 或 SoapFormatter,则字段将被序列化/反序列化,而不是属性。
    在反序列化方面,我相信使用了具有 SerializationInfo 和 StreamingContext 参数的特殊 2-arg 构造函数。

    但是,没有什么能阻止您通过实现 ISerializable 接口来控制序列化过程。 然后,如果您希望使用您的属性设置您的值,我认为您可以完美地做到这一点。

    【讨论】:

      【解决方案3】:

      我知道这不是您问题的直接答案,您已经得到了您正在寻找的答案。但我不想隐瞒这一点。您可以使用Reflector 查看基类库源代码。这是了解更多 .net 框架内部结构和拓宽知识面的绝佳方式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-24
        • 1970-01-01
        • 2018-09-11
        • 2023-02-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多