代码之家  ›  专栏  ›  技术社区  ›  Jean-Bernard Pellerin

如何重写C中的反序列化#

  •  5
  • Jean-Bernard Pellerin  · 技术社区  · 14 年前

    我有一个类,随着时间的推移,它会经历某些版本的变化。 这个类中的数据在启动应用程序时被序列化和反序列化。我的问题是,如果我通过添加更多属性来更新类,然后启动应用程序,则旧数据无法正确加载。
    我要做的是重写反序列化步骤,我不介意从xml手动重建对象,因为我存储了一个版本号,可以使用它递归地更新对象的版本。

    有没有一个我可以实现的接口,或者一个我可以在某处设置的属性,可以做到这一点?

    如果你想不出一个办法来做我想做的事,还有别的办法吗?例如,为我正在加载的xml版本中可能不存在的属性设置默认值。

    4 回复  |  直到 14 年前
        1
  •  2
  •   Punit Vora    14 年前

    通常对于版本控制,可以使用 OptionalField 属性指定可能导致兼容性问题的新添加成员。在序列化过程中,如果成员未序列化,则会将成员值保留为null,而不是引发异常。

    另外,看看 IDeserializationCallback.OnDeserialization 接口,允许您自定义反序列化。

        2
  •  5
  •   SLaks    14 年前
        3
  •  1
  •   Patrik Hägne    14 年前
        4
  •  0
  •   theburningmonk    14 年前

    您可以实现 ISerializable SerializationInfo 和一个 StreamingContext 对象以获得序列化/反序列化过程的精细控制。

    例如:

    [Serializable]
    public struct MyStruct: ISerializable
    {
        private readonly int _x;
        private readonly int _y;
    
        // normal constructor
        public MyStruct(int x, int y) : this()
        {
            _x = x;
            _y = y;
        }
    
        // this constructor is used for deserialization
        public MyStruct(SerializationInfo info, StreamingContext text) : this()
        {
            _x = info.GetInt32("X");
            _y = info.GetInt32("Y");
        }
    
        public int X { get { return _x; } }
        public int Y { get { return _y; } }
    
        // this method is called during serialization
        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("X", X);
            info.AddValue("Z", Y);
        }
    }