听起来很奇怪,但这正是我想要的,因为我使用的是名为“ Project”的数据结构,该数据结构被序列化为保存文件。我希望能够反序列化保存的旧版本的保存文件,但仅使用当前使用的字段重新序列化它。问题是,我在重新序列化结构时要摆脱那些不赞成使用的字段,以最大程度地减小文件大小。是否可以将字段标记为“只能反序列化”?

编辑:

感谢您的想法!我决定主要根据NickLarsen的建议进行构建,并创建一个旧版本的项目结构,并在单独的命名空间中使用所有折旧的字段。区别在于我决定在反序列化时执行升级。这很棒,因为我可以在一行中完成所有操作(希望您能得到我在这里所做的要旨):

Project myProject = new Project((Depreciated.Project)myFormatter.Deserialize(myStream));


构造函数只是基于旧的blo肿数据返回一个新的最小数据结构的新实例。

第二次编辑:

我决定遵循bebop的建议,并为每个项目版本创建新类,其中最旧的版本包括所有折旧和新字段。然后,每个项目的构造函数都将升级到下一个版本,从而消除沿途折旧的字段。这是从版本1.0.0-> 1.0.5->当前版本转换的说明性示例。

Project myProject = new Project(new Project105((Project100)myFormatter.Deserialize(myStream)));


解决此问题的一个关键是使用SerializationBinder将反序列化的文件以及所有字段强制放入类的较早版本中。

最佳答案

您是否不能在每次结构更改时都创建新版本的数据结构类,并让新类的构造函数采用上一个类的实例,然后从那里填充自身。要加载最新的类,请尝试从序列化文件中创建最早的类,直到成功,然后将其重复传递到链中下一个类的构造函数中,直到获得最新版本的数据结构,然后再保存该类。 。

格式的每次更改都有一个新的类,可以避免在数据结构更改时不必更改任何现有代码,并且您的应用程序可能不知道保存文件是某个较旧的版本。它可以让您从任何以前的版本加载,而不仅仅是最后一个。

chain of responsibility实现的这种事情可以轻松地以新格式插入,而对现有代码的更改却很少。

虽然没有教科书责任链,但您可以通过以下方式实现:

(注意:未经测试的代码)

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的通用性纳入基类,但它可以使想法完整。

关于c# - 有没有办法将一个类字段标记为仅反序列化而不序列化?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2208637/

10-12 12:37
查看更多