atl*_*teh 3 c# properties binaryformatter backing-field deserialization
我使用BinaryFormatter将以下类序列化到一个文件中:
[Serializable]
public class TestClass
{
public String ItemTwo { get; set; }
public String ItemOne { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用此代码:
FileStream fs = new FileStream("DataFile.dat", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, new TestClass{ItemOne = "ItemOne", ItemTwo = "ItemTwo"});
fs.Close();
Run Code Online (Sandbox Code Playgroud)
使用此代码反序列化时:
FileStream fs = new FileStream("DataFile.dat", FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
TestClass addresses = (TestClass)formatter.Deserialize(fs);
fs.Close();
Run Code Online (Sandbox Code Playgroud)
我得到一切正常.但是,现在我需要这个类有一些支持字段,如下所示:
[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; }
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,现在,由于某种原因,从以前的版本反序列化不再起作用.我得到了类,但属性保持为null.
我不能影响序列化过程,或前一类状态.
如何将文件反序列化到当前类?
如果您尝试序列化,则第二版TestClass的后场将由二进制格式化程序自动序列化.自动属性只是语法糖,编译器使用支持字段将它们转换为普通属性.例如,如果您使用ILSpy反编译原始控制台应用程序(或类库),您将看到您的私有字段被声明为:
.field private string '<ItemOne>k__BackingField'
Run Code Online (Sandbox Code Playgroud)
这与你的第二个声明不同,后面的字段产生于:
.field private string _itemOne
Run Code Online (Sandbox Code Playgroud)
一种方法是声明ISerializable您的接口TestClass并使用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
}
}
Run Code Online (Sandbox Code Playgroud)
所以你告诉BinaryFormatter你在反序列化过程中如何初始化你的支持字段.