我必须工作所使用的BinaryFormatter序列化应用数据转换成一个文件流的旧的应用程序(在一个文件名为“data.oldformat”说) 没有任何optimizazion主类已被标记与属性

<serializable()>public MainClass
....... 
end class

和序列化代码

dim b as new binaryformatter
b.serialize(mystream,mymainclass)

在试图优化序列化/反序列化过程简单地我提出的类实现ISerializable接口和写了一些优化序列化例程

<serializable()>public MainClass
       implements ISerializable
....... 
end class

在优化的作品真的很好,但我必须找到一个方法来reatrive旧文件中的数据的后向兼容性。

如何做到这一点??

皮耶路易吉

有帮助吗?

解决方案

<强> stmax 具有优异的答案,但是我将实施像这样,它使用SerializationEntry.GetEnumerator()代替try/catch。这种方式是清洁器和显著更快。

public MainClass(SerializationInfo info, StreamingContext context) {
    int version = 0;
    foreach (SerializationEntry s in info)
    {
        if (s.Name == "version") 
        {
            version = (int)s.Value;
            break;
        }
    }

    switch (version) {
      case 0:
        // deserialize "old format"
        break;
      case 1:
        // deserialize "new format, version 1"
        break;
      default:
        throw new NotSupportedException("version " + version + " is not supported.");
    }
}

我宁愿使用.FirstOrDefault()LINQ的版本,但SerializationInfo中不实现IEnumerable - 在脸上,古怪的是,它甚至没有实现旧IEnumerable接口

其他提示

既然你已经实现ISerializable接口,你可能也已经添加了必需的构造函数:

public MainClass(SerializationInfo info, StreamingContext context) {}

您可以使用传递给构造函数的信息对象从序列化的文件检索数据。 按缺省(即,当没有ISerializable的实施),字段名称用作序列化过程中的标识符。所以如果你的老班有场“INT X”,你可以反序列化这一点使用:

this.x = info.GetInt32("x");

有关新版本我通常序列化过程中添加一个“版本”项,是这样的:

public void GetObjectData(SerializationInfo info, StreamingContext context) {
  info.AddValue("version", 1);
  info.AddValue("othervalues", ...);
}

在反序列化过程中,您可以检查此版本的条目,并据此反序列化:

public MainClass(SerializationInfo info, StreamingContext context) {
    int version;
    try {
       version = info.GetInt32("version");
    }
    catch {
       version = 0;
    }

    switch (version) {
      case 0:
        // deserialize "old format"
        break;
      case 1:
        // deserialize "new format, version 1"
        break;
      default:
        throw new NotSupportedException("version " + version + " is not supported.");
    }
}

我还没有编译的代码,可能包含输入错误。

希望帮助。

刚刚尝试同样的事情,你到目前为止一直在做的。

BinaryFormatter b = new BinaryFormatter();
MainClass a = b.DeSerialize(mystream) as MainClass;

实施了ISerializable并没有改变原来的类,基本上你刚刚增加了一些方法

当您的序列化对象添加一个额外的版本场(这应该不会增加太多的开销)。然后在您的GetObjectData方法,尝试检索版本字段第一,在此基础上是否存在(被捕捉SerializationException)反序列化老办法还是新途径。旧的方式将刚刚序列化的所有数据,所以你应该只能够调用get ...所有字段。

您以前的代码应该工作。你会得到一个异常? 尝试使用新的构造:

 Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top