二进制格式化程序和属性 with\without 支持字段
Binary Formatter and properties with\without backing fields
我使用 BinaryFormatter 将以下 class 序列化到一个文件中:
[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();
使用此代码反序列化时:
FileStream fs = new FileStream("DataFile.dat", FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
TestClass addresses = (TestClass)formatter.Deserialize(fs);
fs.Close();
我一切正常。
但是,现在我需要 class 有一些像这样的支持字段:
[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; }
}
}
我的问题是现在,出于某种原因,以前版本的反序列化不再起作用。我得到 class 但属性为空。
我不能影响序列化进程,或者之前的class状态。
如何让文件反序列化为当前 class?
如果您尝试序列化 TestClass
的第一个版本,二进制格式化程序将自动序列化后场。自动属性只是语法糖,编译器将它们转换为带有支持字段的普通属性。例如,如果您使用 ILSpy 反编译原始控制台应用程序(或 class 库),您将看到您的私有字段声明为:
.field private string '<ItemOne>k__BackingField'
这与您的第二个声明有很大不同,后者的支持字段产生:
.field private string _itemOne
一种方法是在 TestClass
上声明 ISerializable
接口,并使用 class SerializationInfo [=] 中包含的信息获取原始属性的值19=]
[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
您希望在反序列化过程中如何初始化支持字段。
我使用 BinaryFormatter 将以下 class 序列化到一个文件中:
[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();
使用此代码反序列化时:
FileStream fs = new FileStream("DataFile.dat", FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
TestClass addresses = (TestClass)formatter.Deserialize(fs);
fs.Close();
我一切正常。 但是,现在我需要 class 有一些像这样的支持字段:
[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; }
}
}
我的问题是现在,出于某种原因,以前版本的反序列化不再起作用。我得到 class 但属性为空。
我不能影响序列化进程,或者之前的class状态。
如何让文件反序列化为当前 class?
如果您尝试序列化 TestClass
的第一个版本,二进制格式化程序将自动序列化后场。自动属性只是语法糖,编译器将它们转换为带有支持字段的普通属性。例如,如果您使用 ILSpy 反编译原始控制台应用程序(或 class 库),您将看到您的私有字段声明为:
.field private string '<ItemOne>k__BackingField'
这与您的第二个声明有很大不同,后者的支持字段产生:
.field private string _itemOne
一种方法是在 TestClass
上声明 ISerializable
接口,并使用 class SerializationInfo [=] 中包含的信息获取原始属性的值19=]
[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
您希望在反序列化过程中如何初始化支持字段。