C# 序列化与反序列化之DataContract与xml对子类进行序列化的解决方案

C# 序列化与反序列化之DataContract与xml对子类进行序列化的解决方案

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($"测试序列化结果:
{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($"测试序列化结果:
{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($"测试序列化结果:
{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
        }
} }