听起来很奇怪,但这正是我想要的,因为我正在使用名为“Project”的数据结构,该数据结构被序列化为保存文件。我希望能够使用已弃用的字段对旧版本的保存文件进行反序列化,然后仅使用当前使用的字段对其进行重新序列化。问题是我想在重新序列化结构时删除那些已弃用的字段,以最小化文件大小。是否可以将字段标记为“仅可反序列化”?
Edit:
感谢您的想法!我决定主要根据 NickLarsen 的建议进行构建,并创建一个旧版本的项目结构,其中所有已折旧的字段都位于单独的命名空间中。不同的是,我决定在反序列化时执行升级。这很棒,因为我可以在一行中完成所有操作(希望您能了解我在这里所做的要点):
Project myProject = new Project((Depreciated.Project)myFormatter.Deserialize(myStream));
构造函数只是基于旧的臃肿数据结构返回一个新的最小数据结构的新实例。
第二次编辑:
我决定遵循 bebop 的建议,为每个项目版本创建新的类,其中最旧的版本包括所有折旧的和新的字段。然后,每个项目的构造函数都会升级到下一个版本,并在此过程中删除折旧的字段。下面是从版本 1.0.0 -> 1.0.5 -> current 转换的说明性示例。
Project myProject = new Project(new Project105((Project100)myFormatter.Deserialize(myStream)));
实现这一点的一个关键是通过使用序列化绑定器 http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationbinder.aspx.
您是否可以在每次结构更改时创建数据结构类的新版本,并让新类的构造函数采用前一个类的实例,并从那里填充自身。要加载最新的类,您尝试从序列化文件创建最早的类,直到成功,然后将其重复传递到链中下一个类的构造函数中,直到获得数据结构的最新版本,然后您可以保存该类。
为每次格式更改创建一个新类可以避免在数据结构更改时更改任何现有代码,并且您的应用程序可能不知道保存文件是旧版本这一事实。它允许您从任何以前的版本加载,而不仅仅是最后一个版本。
这种事情是由一个实现的责任链 http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern可以轻松插入新格式,只需对现有代码进行最少的更改。
虽然不是教科书上的责任链,但您可以通过以下方式实现:
(注意:未经测试的代码)
public interface IProductFactory<T> where T : class
{
T CreateProduct(string filename);
T DeserializeInstance(string filename);
}
public abstract class ProductFactoryBase<T> : IProductFactory<T> where T : class
{
public abstract T CreateProduct(string filename);
public T DeserializeInstance(string filename)
{
var myFormatter = new BinaryFormatter();
using (FileStream stream = File.Open(filename, FileMode.Open))
{
return myFormatter.Deserialize(stream) as T;
}
}
}
public class ProductV1Factory : ProductFactoryBase<ProductV1>
{
public override ProductV1 CreateProduct(string filename)
{
return DeserializeInstance(filename);
}
}
public class ProductV2Factory : ProductFactoryBase<ProductV2>
{
ProductV1Factory successor = new ProductV1Factory();
public override ProductV2 CreateProduct(string filename)
{
var product = DeserializeInstance(filename);
if (product==null)
{
product = new ProductV2(successor.CreateProduct(filename));
}
return product;
}
}
public class ProductV2
{
public ProductV2(ProductV1 product)
{
//construct from V1 information
}
}
public class ProductV1
{
}
这样做的优点是,当您想要添加 ProductV3 时,您只需将应用程序中使用的类更改为 ProductV3 类型(无论如何您都需要这样做),然后更改加载代码以使其使用 ProductV3Factory,它与 ProductV2Factory 基本相同,但它使用 ProductV2Factory 作为后继者。您不需要更改任何现有的类。你可能可以稍微重构一下以获得以下共性CreateProduct
进入基类,但它传达了这个想法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)