更改类的反序列化

时间:2011-11-10 08:25:09

标签: c# c#-4.0 deserialization

我正在开发一个程序,通过序列化Project类来保存它的项目文件。 因为我还在研究它,所以属于Project类的一些类会不时地改变(例如,类获得了新属性)。它使“简单”的反序列化变得不可能。

有什么办法可以解决吗?我的意思是,没有自定义序列化器? (现在可能高于我的水平)

以防万一,我正在使用BinaryFormatter。


正如我在下面写的那样,我找到了对我有用的解决方案。 但我无法将我的答案视为正确的答案;) 感谢您的每一个答案和评论,这有助于我找到解决反序列化问题的其他方法,我可以在其他项目中使用。

3 个答案:

答案 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会在此过程中失败。

要在我使用的数据类型中克服这个问题,我必须编写自己的序列化程序,这实际上并不是一项重大任务。您可以使用BinaryReaderBinaryWriter类来读取和写入数据类型。这样,您可以通过添加默认值,完全跳过属性或抛出某种形式的Exception来表示损坏的数据来控制您期望的数据并处理任何丢失的数据。有关详细信息,请参阅上面的MSDN文章链接。

答案 2 :(得分:1)

在Merlyn Morgan-Graham的评论的帮助下,我找到了解决方案,这对我有用。

Version Tolerant Serialization中描述的版本控制非常好,但当我只使用[Serializable]属性时。

我忘了写(我的错误),我正在使用ISerializable接口。 我发现,在反序列化构造函数中,SerializationInfo对象具有MemberCount属性,如果我不时添加新属性/成员,它就解决了我的问题。有了这些信息,无法从旧文件反序列化的新成员/属性可以设置为默认值,或者我可以使用一些提示形式。

这里的其他方式是在反序列化中使用类似汇编版本的东西,作为第一个反序列化的成员。这可以通过更复杂的类更改来解决反序列化问题。

无论哪种方式,我同意Merylin的说法 - “如果你不能编写某些东西,你就不应该构建它”。 ;)