BinaryFormatter OptionalField 与 ISerializable
BinaryFormatter OptionalField with ISerializable
我创建了一个测试可序列化对象:
[Serializable]
public class TestObject : ISerializable
{
public string FirstName;
public TestObject()
{
}
public TestObject(SerializationInfo info, StreamingContext context)
{
FirstName = info.GetString("firstName");
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("firstName", FirstName);
}
}
然后序列化:
var test = new TestObject { FirstName = "John" };
using (var stream = new FileStream(@"c:\temp\test.dat", FileMode.Create, FileAccess.Write))
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, test);
}
我更改 class 使其具有 OptionalFied 并尝试反序列化旧的序列化对象:
[Serializable]
public class TestObject : ISerializable
{
public string FirstName;
[OptionalField]
public string SecondName;
public TestObject()
{
}
public TestObject(SerializationInfo info, StreamingContext context)
{
FirstName = info.GetString("firstName");
SecondName = info.GetString("secondName");
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("firstName", FirstName);
}
当我更改构造函数以读取新的可选字段时,我在 "SecondName = info.GetString("secondName");":
处抛出异常
using (var stream = new FileStream(@"c:\temp\test1.dat", FileMode.Open, FileAccess.Read))
{
var formatter = new BinaryFormatter();
var myInstance = (TestObject)formatter.Deserialize(stream);
}
是不是在实现ISerializable时不支持OptionalFieldAttribute?
对于旧的序列化对象,不会有 secondname 字段,因此它的 SerializationEntry 不会存在。
您需要在访问值之前检查是否存在条目:
foreach (SerializationEntry entry in info)
{
switch (entry.Name)
{
case "firstname":
Firstname = (string)entry.Value;
break;
case "secondname":
Secondname = (string)entry.Value;
break;
}
}
我创建了一个测试可序列化对象:
[Serializable]
public class TestObject : ISerializable
{
public string FirstName;
public TestObject()
{
}
public TestObject(SerializationInfo info, StreamingContext context)
{
FirstName = info.GetString("firstName");
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("firstName", FirstName);
}
}
然后序列化:
var test = new TestObject { FirstName = "John" };
using (var stream = new FileStream(@"c:\temp\test.dat", FileMode.Create, FileAccess.Write))
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, test);
}
我更改 class 使其具有 OptionalFied 并尝试反序列化旧的序列化对象:
[Serializable]
public class TestObject : ISerializable
{
public string FirstName;
[OptionalField]
public string SecondName;
public TestObject()
{
}
public TestObject(SerializationInfo info, StreamingContext context)
{
FirstName = info.GetString("firstName");
SecondName = info.GetString("secondName");
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("firstName", FirstName);
}
当我更改构造函数以读取新的可选字段时,我在 "SecondName = info.GetString("secondName");":
处抛出异常 using (var stream = new FileStream(@"c:\temp\test1.dat", FileMode.Open, FileAccess.Read))
{
var formatter = new BinaryFormatter();
var myInstance = (TestObject)formatter.Deserialize(stream);
}
是不是在实现ISerializable时不支持OptionalFieldAttribute?
对于旧的序列化对象,不会有 secondname 字段,因此它的 SerializationEntry 不会存在。
您需要在访问值之前检查是否存在条目:
foreach (SerializationEntry entry in info)
{
switch (entry.Name)
{
case "firstname":
Firstname = (string)entry.Value;
break;
case "secondname":
Secondname = (string)entry.Value;
break;
}
}