我们有类A,它被视为版本1。 类A的一个实例已经序列化到磁盘上。 现在我们有了类B,它被认为是类A的第2个版本(类A有很多问题,我们不得不为下一个版本创建类B)。 类A仍然存在于代码中,但仅供遗留目的。
我想将版本1数据(存储在磁盘上)反序列化为类B实例,并使用逻辑例程将数据从先前的类A实例转换为新的类B实例。类B的实例将在操作期间序列化到磁盘上。
应用程序应该能够反序列化类A和B的实例。
数据契约代理和DataContractSerializer的概念浮现在脑海中。目标是将版本1数据转换为新的类B结构。
例如:
[DataContract]
public class A {
public A(){}
[DataMember]
public bool IsActive {get;set;]
[DataMember]
public int VersionNumber {
get { return 1; }
set { }
}
[DataMember]
public int TimeInSeconds {get;set;}
[DataMember]
public string Name {get;set;}
[DataMember]
public CustomObject CustomObj {get;set;} //Also a DataContract
[DataMember]
public List<ComplexThing> ComplexThings {get;set;} //Also a DataContract
...
}
[DataContract]
public class B {
public B(A a) {
this.Enabled = a.IsActive; //Property now has a different name
this.TimeInMilliseconds = a.TimeInSeconds * 1000; //Property requires math for correctness
this.Name = a.Name;
this.CustomObject2 = new CustomObject2(a.CustomObj); //Reference objects change, too
this.ComplexThings = new List<ComplexThings>();
this.ComplexThings.AddRange(a.ComplexThings);
...
}
public B(){}
[DataMember]
public bool Enabled {get;set;]
[DataMember]
public int Version {
get { return 2; }
set { }
}
[DataMember]
public double TimeInMilliseconds {get;set;}
[DataMember]
public string Name {get;set;}
[DataMember]
public CustomObject2 CustomObject {get;set;} //Also a DataContract
[DataMember]
public List<ComplexThing> ComplexThings {get;set;} //Also a DataContract
...
}
Class A 是我们对象的第一次迭代,目前仍在使用。数据以 v1 格式存在,使用 class A 进行序列化。
意识到问题后,我们创建了一个新结构,叫做 class B。A 和 B 之间有很多变化,所以我们认为创建 B 更好,而不是改编原来的 class A。
但是我们的应用程序已经存在,并且正在使用 class A 进行数据序列化。我们准备推出我们的更改,但是我们必须首先对版本 1(使用 class A)创建的数据进行反序列化,并将其实例化为 class B。数据足够重要,我们不能仅仅通过在 class B 中添加默认值来处理缺失的数据,而是必须将数据从 class A 实例转换到 class B。一旦我们有了 class B 实例,应用程序就会再次以 class B 格式(版本 2)进行数据序列化。
我们假设将来会对 class B 进行修改,并希望能够迭代到版本 3,可能在一个新类“C”中。我们有两个目标:处理已经存在的数据,并准备好对象进行未来的迁移。
现有的“过渡”属性(OnSerializing/OnSerialized、OnDeserializing/OnDeserialized 等)没有提供访问先前数据的方法。
在这种情况下,使用 protobuf-net 的期望做法是什么?