二进制格式化程序和具有\无后备字段的属性 [英] Binary Formatter and properties with\without backing fields

查看:147
本文介绍了二进制格式化程序和具有\无后备字段的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用BinaryFormatter将以下类序列化为文件:

I have the following class serialized into a file using BinaryFormatter:

[Serializable]
public class TestClass
{
    public String ItemTwo { get; set; }
    public String ItemOne { get; set; }
}

使用此代码:

FileStream fs = new FileStream("DataFile.dat", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, new TestClass{ItemOne = "ItemOne", ItemTwo = "ItemTwo"});
fs.Close();

使用此代码反序列化时:

When deserializing using this code:

FileStream fs = new FileStream("DataFile.dat", FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
TestClass addresses = (TestClass)formatter.Deserialize(fs);
fs.Close();

我一切正常. 但是,现在我需要该类具有一些支持字段,如下所示:

I get everything normally. However, now I need the class to have some backing fields like so:

[Serializable]
public class TestClass
{
    private string _itemTwo;
    private string _itemOne;

    public String ItemTwo
    {
        get { return _itemTwo; }
        set { _itemTwo = value; }
    }

    public String ItemOne
    {
        get { return _itemOne; }
        set { _itemOne = value; }
    }
}

我的问题是,由于某种原因,以前版本的反序列化现在不再起作用.我得到了该类,但属性"保留为空.
我不能影响序列化过程或以前的类状态.
如何获取反序列化到当前类的文件?

My problem is that now, for some reason, deserialization from previous version doesn't work anymore. I get the class but the Properties are left null.
I cannot affect the serialization process, or the former class state.
How can I get the file to deserialize to the current class?

推荐答案

如果您尝试序列化TestClass的第一个版本,则后备字段将由二进制格式化程序自动序列化.自动属性只是语法糖,编译器使用后备字段将它们转换为常规属性.例如,如果使用 ILSpy 反编译原始控制台应用程序(或类库),则会看到声明了私有字段为:

If you try to serialize the first version of TestClass the backfields will be serialized automatically by the binary formatter. Auto properties are only syntactic sugar, the compiler transform them in normal properties with backing fields. If you decompile your original console application (or class library) with ILSpy for example you'll see that your private fields are declared as:

.field private string '<ItemOne>k__BackingField'

与您的第二个声明具有后备字段的方式有出入:

which is way different from your second declaration with backing fields which yields to:

.field private string _itemOne

一种方法是在TestClass上声明ISerializable接口,并使用类

An approach would be declaring the ISerializable interface on your TestClass and get the value of the original properties using the information contained in the class SerializationInfo

[Serializable]
public class TestClass : ISerializable
{
    private string _itemTwo;
    private string _itemOne;

    public String ItemTwo
    {
        get { return _itemTwo; }
        set { _itemTwo = value; }
    }

    public String ItemOne
    {
        get { return _itemOne; }
        set { _itemOne = value; }
    }

    protected TestClass(SerializationInfo info, StreamingContext context)
    {
        _itemTwo = info.GetString("<ItemTwo>k__BackingField");
        _itemOne = info.GetString("<ItemOne>k__BackingField");
    }

    [SecurityPermissionAttribute(SecurityAction.Demand,
    SerializationFormatter = true)]
    public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        //Add data to your serialization process here
    }
}

所以您告诉BinaryFormatter如何在反序列化期间初始化背景字段.

so you tell the BinaryFormatter how you want your backing fields to be initialized during deserialization.

这篇关于二进制格式化程序和具有\无后备字段的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆