我有一个简单的“可序列化”类,定义如下:
[Serializable]
public class LayoutDetails
{
public bool IsRefreshEnabled { get; set; }
public string GridSettings { get; set; }
public List<string> GroupByPropertyNames { get; set; }
}
该类已使用以下例程进行序列化:
using (var memoryStream = new MemoryStream())
{
var dc = new DataContractSerializer(obj.GetType());
dc.WriteObject(memoryStream, obj);
memoryStream.Flush();
memoryStream.Position = 0;
StreamReader reader = new StreamReader(memoryStream);
serializedObject = reader.ReadToEnd();
}
我尝试使用以下例程对其进行反序列化:
var bytes = new UTF8Encoding().GetBytes(serializedObject);
using (var stream = new MemoryStream(bytes ))
{
var serializer = new DataContractSerializer(type);
var reader = XmlDictionaryReader.CreateTextReader(stream, XmlDictionaryReaderQuotas.Max);
obj = serializer.ReadObject(reader, true);
}
这非常有效;但是,现在,我想向类添加一个新属性 (public int? Offset { get; set; }
)。当我将此属性添加到类中并尝试反序列化以前序列化的实例(没有该属性)时,出现异常:
Error in line 1 position 148. 'EndElement' 'LayoutDetails' from namespace 'http://schemas.datacontract.org/2004/07/WpfApplication1' is not expected. Expecting element '_x003C_Offset_x003E_k__BackingField'.
我的第一个想法是实现 ISerialized
并使用反序列化构造函数,所以我尝试了类似的方法,但它无法按名称找到任何成员 - 而且我尝试了几种组合。 .
public LayoutDetails(SerializationInfo info, StreamingContext context)
{
this.IsRefreshEnabled = (bool)info.GetValue("_x003C_IsRefreshEnabled_x003E_k__BackingField", typeof(bool));
this.IsRefreshEnabled = (bool)info.GetValue("_x003C_IsRefreshEnabled_x003E_k_", typeof(bool));
this.IsRefreshEnabled = (bool)info.GetValue("_x003C_IsRefreshEnabled_x003E", typeof(bool));
this.IsRefreshEnabled = (bool)info.GetValue("x003C_IsRefreshEnabled_x003E", typeof(bool));
this.IsRefreshEnabled = (bool)info.GetValue("IsRefreshEnabled", typeof(bool));
}
使用 DataContractSerializer,如何在不破坏“旧”实例上的反序列化的情况下向我的类添加新成员?
最佳答案
您可以使用新属性的支持字段,并添加属性OptionalField
:
[Serializable]
public class LayoutDetails
{
[OptionalField]
private int? offset;
public bool IsRefreshEnabled { get; set; }
public string GridSettings { get; set; }
public List<string> GroupByPropertyNames { get; set; }
public int? Offset
{
get { return offset; }
set { offset = value; }
}
}
如果你想设置默认值,你可以使用属性OnDeserializing
向类添加一个方法:
[OnDeserializing]
private void SetOffsetDefault(StreamingContext sc)
{
offset = 123;
}
关于c# - 新添加成员后反序列化类时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35234401/