具有ISerializable的BinaryFormatter OptionalField

时间:2015-07-23 16:47:53

标签: c# serialization deserialization binary-deserialization

我创建了一个测试可序列化对象:

private Calendar twentyFourHoursAgo() {
    Calendar cal = Calendar.getInstance();
    cal.roll(Calendar.DAY_OF_YEAR, false);
    return cal;
}

然后序列化它:

[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);
    }
}

我更改了类以使其具有OptionalFied并尝试反序列化旧的序列化对象:

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);
}

当我更改构造函数以读取新的可选字段时,我得到一个异常抛出" SecondName = info.GetString(" secondName");":

[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);
    }

实现ISerializable时是否真的不支持OptionalFieldAttribute?

1 个答案:

答案 0 :(得分:1)

对于旧的序列化对象,不会有secondname字段,因此它的SerializationEntry将不存在。

在访问该值之前,您需要检查是否存在条目:

    foreach (SerializationEntry entry in info) 
    { 
        switch (entry.Name) 
        { 
            case "firstname": 
                Firstname = (string)entry.Value; 
            break; 
            case "secondname": 
                Secondname = (string)entry.Value;
            break; 
        }
    }