【问题标题】:Where best store temporary deserialization data?哪里最好存储临时反序列化数据?
【发布时间】:2012-09-02 00:45:55
【问题描述】:

我可以避免向类添加额外的字段来存储仅用于反序列化/序列化的数据吗?

假设我有一些课程:

[Serializable]
class MyClass {
      [NonSerialized]
      NonSerializableDataType myField;

      SomeOtherDataType serializableTemporaryData;

      [OnSerializing]
      OnSerializing (StreamingContext context) {
          // build serializableTemporaryData from myField
      }

      [OnDeserialized]
      void OnDeserialized (StreamingContext context) {
         // build myField from serializableTemporaryData
      }
}

有什么方法可以避免MyClass 的每个对象中都有serializableTemporaryData 字段?例如,我可以将其设为静态(可能通过更改我的 On... 方法)吗?

约束:我无法更改NonSerializableDataType 的实现。

示例:假设 myField 包含一个资源句柄。然后,在序列化时,我必须存储一些反序列化后如何获取资源的信息,但我不能存储句柄本身。如果我将句柄包装到另一个类中,那么我只是将问题转移到了包装类——然后我会为包装类提出同样的问题。

【问题讨论】:

  • 在这里制作静态是个坏主意。考虑两个线程作用于同一类的两个对象,进行序列化。
  • 您使用的是哪个序列化程序? xml还是二进制?还有,NonSerializableDataType不能改,但是可以继承吗?
  • 为什么每次都需要存储又不能生产?
  • 如果有帮助,我可以将字段设为 ThreadStatic。不,我不能对 NonSerializableDataType 做 任何事情,除非使用它。这是二进制序列化。我需要存储它,因为我无法在没有任何信息的情况下生成它,即我需要存储一些关于如何生成实际对象的信息。

标签: c# serialization deserialization binaryformatter


【解决方案1】:

如果你需要控制序列化过程,你应该实现ISerialization接口。

[Serializable]
public class MyClass: ISerializable
{
    // As you are in control of serialization process now
    // [Serialized] and [NonSerialized] attributes are no longer required
    private NonSerializableDataType myField;

    public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        // Create and populate your SomeOtherDataType local variable here, then push it into info variable
        // Or even better, dont create SomeOtherDataType, just put additional serialization data into info variable, for example:
        info.AddValue("URL", "http://this.way.com");
    }

    protected MyClass(SerializationInfo info, StreamingContext context)
    {
        // Dont forget to define constructor for deserialization purpose

        this.myField = new NonSerializableDataType(loadFromURL: (string)info.GetValue("URL", typeof(string)));
    }
}

没有额外的类只用于序列化数据,没有字段污染。唯一的潜在问题是观察从此类派生的任何可序列化数据(如果需要,覆盖 GetObjectData(...))。

更多信息:MSDN ISerializable

【讨论】:

  • 谢谢。这似乎是我需要的。
【解决方案2】:

serialization surrogates 的概念可能会帮助您克服SomeNonSerializableType 的困难,因为它正是为此而设计的。但是,这要求您可以配置序列化代理,当格式化程序被创建。否则,您将需要通过实现ISerializable 来自定义序列化过程。

【讨论】:

  • 感谢您提供链接和代理提示。我会解决这个问题的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
  • 2012-02-24
  • 1970-01-01
  • 2012-11-14
  • 2015-07-23
  • 1970-01-01
相关资源
最近更新 更多