我有一个自定义设置文件,我使用 XmlSerializer
对其进行序列化/反序列化。我的对象定义中没有定义模式和序列化标签,只是直接对象序列化(尽管我会在需要时添加它们)。
我的问题是我需要向对象添加数据成员。如果我这样做,我知道旧的设置文件将不会反序列化。
有没有一种方法可以为添加的成员指定默认值,或者如果 XML 中缺少它们,可以通过一些简单的方法忽略它们?
最佳答案
来自 MSDN
Best Practices To ensure proper versioning behavior, follow these rules when modifying a type from version to version:
When adding a new serialized field, apply the OptionalFieldAttribute attribute.
When removing a NonSerializedAttribute attribute from a field (that was not serializable in a previous version), apply the OptionalFieldAttribute attribute.
For all optional fields, set meaningful defaults using the serialization callbacks unless 0 or null as defaults are acceptable.
我已经尝试模拟您的情况,在新版本的类中有一个名为 Element2 的新成员。将我的新成员初始化为“这是新成员”这里是完整的证明
Test1 假定您使用 Root 类的旧定义与 Just one Element1 进行序列化
Test2 当你使用根类的新定义序列化和反序列化时
要以任何方式回答您的问题以提供默认值,您应该使用“OptionalField”
using System;
using System.Runtime.Serialization;
using System.IO;
public class Test
{
[Serializable]
public class Root
{
[OptionalField(VersionAdded = 2)] // As recommended by Microsoft
private string mElement2 = "This is new member";
public String Element1 { get; set; }
public String Element2 { get { return mElement2; } set { mElement2 = value; } }
}
public static void Main(string[] s)
{
Console.WriteLine("Testing serialized with old definition of Root ");
Console.WriteLine(" ");
Test_When_Original_Object_Was_Serialized_With_One_Element();
Console.WriteLine(" ");
Console.WriteLine("Testing serialized with new definition of Root ");
Console.WriteLine(" ");
Test_When_Original_Object_Was_Serialized_With_Two_Element();
Console.ReadLine();
}
private static void TestReadingObjects(string xml)
{
System.Xml.Serialization.XmlSerializer xmlSerializer =
new System.Xml.Serialization.XmlSerializer(typeof(Root));
System.IO.Stream stream = new MemoryStream();
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(xml);
stream.Write(bytes, 0, bytes.Length);
stream.Position = 0;
Root r = (Root)xmlSerializer.Deserialize(stream);
Console.WriteLine(string.Format("Element 1 = {0}", r.Element1));
Console.WriteLine(string.Format("Element 2 = {0}", r.Element2 == null ? "Null" : r.Element2));
}
private static void Test_When_Original_Object_Was_Serialized_With_One_Element()
{
TestReadingObjects(@"<Root> <Element1>1</Element1> </Root>");
}
private static void Test_When_Original_Object_Was_Serialized_With_Two_Element()
{
TestReadingObjects(@"<Root> <Element1>1</Element1> <Element2>2</Element2> </Root>");
}
}
//这里是输出
关于c# - 在 C# 中,如何将旧对象中的 XML 反序列化为更新后的对象并忽略丢失的 xml 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8174927/