我目前无法尝试创建类更新程序。
有一个可序列化的 ClassA ,其中包含 Integer - 和 String - 变量。 ClassA 会转换为对象,序列化然后保存到二进制文件。 之后会有一个程序更新,它会改变 ClassA 以包含两个 Integer - 和 String - 变量。旧的 ClassA 重命名为 ClassA_0 。 从Binary-File加载数据时,反序列化的对象作为参数传递给updater方法。
问题是:如何将对象与 ClassA_0 和 ClassA 进行比较,以确定将其保存为“版本”?
编辑:
[Serializable]
public class ClassA
{
int VarA;
int VarB;
string VarC;
public ClassA()
{
//[...]
}
public void MethodX()
{
//[...]
}
}
[Serializable]
public class ClassA_0
{
int VarA;
string VarB;
public ClassA()
{
//[...]
}
public void MethodX()
{
//[...]
}
}
这些是虚拟类,所以我没有在构造函数或方法中指定任何代码。
答案 0 :(得分:1)
如果这是我,我会看一下像protobuf-net这样的工具(偏见:我是作者,但是:所有免费等),它可以让你更好地控制这些东西。然后我会做类似的事情:
[ProtoContract]
public class ClassA
{
[ProtoMember(1)
int Version { get { return 1; } set {} }
[ProtoMember(2)]
int VarA;
[ProtoMember(3)]
int VarB;
[ProtoMember(4)]
string VarC;
public ClassA()
{
//[...]
}
public void MethodX()
{
//[...]
}
}
[ProtoContract]
public class ClassA_0
{
[ProtoMember(1)
int Version { get { return 2; } set {} }
[ProtoMember(2)] // this is the same - compatible, keep tag
int VarA;
[ProtoMember(5)] // not the same: new tag
string VarB;
public ClassA()
{
//[...]
}
public void MethodX()
{
//[...]
}
}
请注意,标记1
中有一个虚拟属性,它只有get
并忽略值 - 这可以确保我们使用数据序列化一个版本以供以后查找(因为您需要)。我们可以还添加一个set
,它会引发有关该版本的错误,但我更愿意让它尽可能兼容。
VarA
存在并兼容两者 - 我们可以使用标记2。其他数据不兼容,因此使用了新的不同标签(5);现在,如果您愿意,我们可以使用Serializer.Deserialize<ClassA>(...)
或Serializer.NonGeneric
等效项,并且数据应该反序列化。但我们可能还想检查版本 - 我们可以这样做:
[ProtoContract]
public class VersionInfo {
[ProtoMember(1)]
public int Version {get;set;}
}
现在我们可以在同一数据上使用Serializer.Deserialize<VersionInfo>
,它只会反序列化版本标记并丢弃其他所有内容。一旦我们知道了版本,我们就可以进行分支等。这也可以通过某种形式的继承来完成 ,但这似乎有点过分了。
答案 1 :(得分:0)
BinaryFormatter二进制流的规范是here。您可以直接读取流(不使用反序列化器)并从中找出类型