C# 序列化与反序列化之DataContract与xml对子类进行序列化的解决方案
1、DataContract继承对子类进行序列化的解决方案
第一种是在 [DataContract, KnownType(typeof(继承的子类))]添加 KnownType(typeof(继承的子类))即可,
第二种是在序列化的时候,添加类型
DataContractSerializer dcs = new DataContractSerializer(typeof(T),new Type[] { typeof(继承的子类1), typeof(继承的子类1) })
using System.Runtime.Serialization; namespace SupremeConsole { /// <summary> /// 测试类,该类必未标记为可序列化,DataContractJsonSerialize,XmlSerialize可以正常序列化 /// </summary> //继承TestClass的子类SubTestClass的序列化 //[DataContract, KnownType(typeof(继承的子类)), KnownType(typeof(继承的子类1))]//KnownType指明了,继承子类的序列化的类型如 KnownType(typeof(SubTestClass)),或者再序列化的时候添加子类类型DataContractSerializer dcs = new DataContractSerializer(typeof(T),new Type[] { typeof(继承的子类1), typeof(继承的子类1) }),如:typeof(SubTestClass); [DataContract] //如果类型加了DataContract特性标记,而成员字段没有加DataMember特性标记的话,只有类型会序列化,成员不会序列化 public class TestClass { /// <summary> /// 编号 /// </summary> [DataMember] public int Id { get; set; } /// <summary> /// 姓名 /// </summary> [DataMember] public string Name { get; set; } /// <summary> /// 年龄 /// </summary> [DataMember] public int Age { get; set; } /// <summary> /// 地址 /// </summary> [DataMember] public string Address { get; set; } /// <summary> /// 性别 /// </summary> [DataMember] public string Sex { get; set; } public override string ToString() { //return string.Format("编号:{0},姓名:{1},年龄:{2},地址:{3},性别:{4}", Id, Name, Age, Address, Sex); return $"编号:{Id},姓名:{Name},年龄:{Age},地址:{Address},性别:{Sex}"; } } }
继承TestClass的子类
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace SupremeConsole { /// <summary> /// 继承TestClass的子类 /// </summary> [DataContract] public class SubTestClass : TestClass { /// <summary> /// 测试姓名 /// </summary> [DataMember] public string SubTestClassName { get; set; } } }
2、xml对继承子类进行序列化的解决方案
第一种:[XmlInclude(typeof(继承的子类1))],添加 XmlInclude(typeof(继承的子类1))即可,如 XmlInclude(typeof(XmlStudent))
第二种:序列化的时候添加子类类型XmlSerializer xs = new XmlSerializer (typeof (XmlPerson),new Type[] { typeof (继承的子类1), typeof (继承的子类2)} );,如:new Type[] { typeof (XmlStudent), typeof (XmlTeacher)}
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Serialization; namespace SupremeConsole { /// <summary> /// xml序列化测试类 /// </summary> //继承XmlPerson的子类XmlStudent,XmlTeacher的序列化 //[XmlInclude(typeof(继承的子类1))]//XmlInclude指明了,继承子类的序列化的类型,如 XmlInclude(typeof(XmlStudent)),或者再序列化的时候添加子类类型XmlSerializer xs = new XmlSerializer (typeof (XmlPerson),new Type[] { typeof (继承的子类1), typeof (继承的子类2)} );,如:new Type[] { typeof (XmlStudent), typeof (XmlTeacher)}; [XmlRoot("haha")] //[XmlInclude(typeof(XmlStudent))] //[XmlInclude(typeof(XmlTeacher))] public class XmlPerson { /// <summary> /// 姓名 /// </summary> [XmlElement("MyName", Order = 2)] public string Name { get; set; } /// <summary> /// 年龄 /// </summary> [XmlAttribute("MyAge")] public int Age { get; set; } /// <summary> /// 住址 /// </summary> [XmlElement("Residence", Order = 1)] public string Address { get; set; } } [XmlType("SubXmlPersonIsXmlStudent")]//XmlStudent序列化后的名称 public class XmlStudent : XmlPerson { /// <summary> /// 学号 /// </summary> public string StuNumber { get; set; } } [XmlType("SubXmlPersonIsXmlTeacher")]//XmlTeacher序列化后的名称 public class XmlTeacher : XmlPerson { /// <summary> /// 工号 /// </summary> public string TeachNumber { get; set; } }
C# 序列化与反序列化之DataContract与xml对子类进行序列化的解决方案,就是利用特性和序列化的时候指明类型即可
总结:
DataContract子类序列化:特性[DataContract, KnownType(typeof(继承的子类)), KnownType(typeof(继承的子类1))]//KnownType指明了,继承子类的序列化的类型如 KnownType(typeof(SubTestClass)),或者再序列化的时候添加子类类型DataContractSerializer dcs = new DataContractSerializer(typeof(T),new Type[] { typeof(继承的子类1), typeof(继承的子类1) }),如:typeof(SubTestClass);
xml子类序列化:特性[XmlInclude(typeof(继承的子类1))]//XmlInclude指明了,继承子类的序列化的类型,如 XmlInclude(typeof(XmlStudent)),或者再序列化的时候添加子类类型XmlSerializer xs = new XmlSerializer (typeof (XmlPerson),new Type[] { typeof (继承的子类1), typeof (继承的子类2)} );,如:new Type[] { typeof (XmlStudent), typeof (XmlTeacher)};
测试代码:
using log4net; using System; using System.Data; using System.Data.SQLite; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.IO.MemoryMappedFiles; using System.IO.Pipes; using System.Linq; using System.Net; using System.Security.AccessControl; using System.Security.Principal; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml; using System.Xml.Serialization; using System.Reflection; using System.ServiceModel; using System.ServiceModel.Channels; using System.Runtime.Serialization; namespace SupremeConsole { class Program { static void Main(string[] args) { TestSeri(); Console.ReadLine(); } public static void TestSeri() { //Team team = new Team { TName="123",PlayerList = { new Person { Name="1",Age=1},new Person { Name = "2", Age = 2 } } }; #region BinarySerialize 必须添可序列化属性,即要序列化的对象必须添加SerializableAttribute属性,[Serializable] //string s = SerializeManager.Instance.BinarySerialize<Team>(team);//序列化 //Console.ForegroundColor = ConsoleColor.Green; //Console.WriteLine("测试序列化成功。。。"); //Console.WriteLine($"测试序列化结果:\r\n{s}"); //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化11111.bin");//序列化 //SerializeManager.Instance.BinarySerialize<Team>(team, path); //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化11111.bin"); //Team test = SerializeManager.Instance.BinaryDeserialize<Team>(path);//反序列化 //if (test != null) //{ // Console.WriteLine($"测试序列化结果:{test.ToString()}"); //} #endregion #region SoapSerialize 必须添可序列化属性,即要序列化的对象必须添加SerializableAttribute属性,[Serializable] //string s = SerializeManager.Instance.SoapSerialize<Team>(team);//序列化 //Console.ForegroundColor = ConsoleColor.Green; //Console.WriteLine("测试序列化成功。。。"); //Console.WriteLine($"测试序列化结果:\r\n{s}"); //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Soap序列化.xml");//序列化 //SerializeManager.Instance.SoapSerialize<Team>(team, path); //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Soap序列化.xml"); //Team test = SerializeManager.Instance.SoapDeserialize<Team>(path);//反序列化 //if (test != null) //{ // Console.WriteLine($"测试序列化结果:{test.ToString()}"); //} #endregion #region XmlSerialize 要序列化的对象可以不添加SerializableAttribute属性,[Serializable] XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12,Address="住址。。。。" }; //XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12, HomeAddress = new USAddress { Street = "默默大街三号", PostCode = "233664", Neighbor="邻居666" } }; string s = SerializeManager.Instance.XmlSerialize<XmlPerson>(xmlPerson);//序列化 Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("测试序列化成功。。。"); Console.WriteLine($"测试序列化结果:\r\n{s}"); //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化.txt");//序列化 //SerializeManager.Instance.XmlSerialize<TestClass>(testClass, path); //备用 //string json = "{\"Address\":\"中国南京\",\"Age\":10,\"Id\":1,\"Name\":\"张三\",\"Sex\":\"男\"}"; //TestClass test = SerializeManager.Instance.DataContractJsonDeserializeJson<TestClass>(json);//反序列化 //if (test != null) //{ // Console.WriteLine($"测试序列化结果:{test.ToString()}"); //} //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化.txt"); //TestClass test = SerializeManager.Instance.XmlDeserialize<TestClass>(path);//反序列化 //if (test != null) //{ // Console.WriteLine($"测试序列化结果:{test.ToString()}"); //} #endregion }
} }