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 = )]
public string Name { get; set; } /// <summary>
/// 年龄
/// </summary>
[XmlAttribute("MyAge")]
public int Age { get; set; } /// <summary>
/// 住址
/// </summary>
[XmlElement("Residence", Order = )]
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 = "", Age = ,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
}
}
}
05-22 17:21