我正在开发一个程序,通过序列化Project类来保存它的项目文件。 因为我还在研究它,所以属于Project类的一些类会不时地改变(例如,类获得了新属性)。它使“简单”的反序列化变得不可能。
有什么办法可以解决吗?我的意思是,没有自定义序列化器? (现在可能高于我的水平)
以防万一,我正在使用BinaryFormatter。
正如我在下面写的那样,我找到了对我有用的解决方案。 但我无法将我的答案视为正确的答案;) 感谢您的每一个答案和评论,这有助于我找到解决反序列化问题的其他方法,我可以在其他项目中使用。
答案 0 :(得分:3)
我希望我能正确理解你的问题。您正在将类序列化为文件。然后更改内存中的类(例如,添加另一个属性)。不,您想要从文件反序列化此类。只要您只添加新属性,这就没问题了。它们将被解串器忽略。他创建了一个类的新实例(这就是为什么可序列化的类必须有一个默认的构造函数),并尝试将他在流中找到的属性填充到derserialize。如果更改属性的类型或删除属性,则无法对其进行反序列化。
“删除属性”的一种解决方法可能是保留您有意删除的属性,并进一步忽略这些属性。改变其类型的属性的工作单可能是这样的:
[Serializable]
public class MyClass
{
int? newProperty;
[XmlElement("Property")]
public string OldProperty
{
get { return string.Empty; }
set
{
if (!newProperty.HasValue)
{
int temp;
if (int.TryParse(value, out temp))
{
newProperty.Value = temp;
}
}
}
}
public int NewProperty
{
get { return newPropery.HasValue ? newProperty.Value : 0; }
set { newProperty.Value = value;
}
}
答案 1 :(得分:1)
根据我的经验,我发现使用BinaryFormatter
对数据类型进行序列化/反序列化会改变一个非常糟糕的主意。如果您的数据类型发生了变化,我知道BinaryFormatter
会在此过程中失败。
要在我使用的数据类型中克服这个问题,我必须编写自己的序列化程序,这实际上并不是一项重大任务。您可以使用BinaryReader
和BinaryWriter
类来读取和写入数据类型。这样,您可以通过添加默认值,完全跳过属性或抛出某种形式的Exception
来表示损坏的数据来控制您期望的数据并处理任何丢失的数据。有关详细信息,请参阅上面的MSDN文章链接。
答案 2 :(得分:1)
在Merlyn Morgan-Graham的评论的帮助下,我找到了解决方案,这对我有用。
Version Tolerant Serialization中描述的版本控制非常好,但当我只使用[Serializable]属性时。
我忘了写(我的错误),我正在使用ISerializable接口。 我发现,在反序列化构造函数中,SerializationInfo对象具有MemberCount属性,如果我不时添加新属性/成员,它就解决了我的问题。有了这些信息,无法从旧文件反序列化的新成员/属性可以设置为默认值,或者我可以使用一些提示形式。
这里的其他方式是在反序列化中使用类似汇编版本的东西,作为第一个反序列化的成员。这可以通过更复杂的类更改来解决反序列化问题。
无论哪种方式,我同意Merylin的说法 - “如果你不能编写某些东西,你就不应该构建它”。 ;)