• XmlSerializer序列化


      XmlSerializer在命名空间using System.Xml.Serialization下。

    序列化和反序列化的代码:

    using System.IO;
    using System.Xml;
    using System.Xml.Serialization;
    namespace ConsoleApplication1
    {
        public class PublicFunction
        {
            //序列化到XmlNode
            public static void Serialize<T>(T t, out XmlNode node)
            {
                XmlDocument doc = new XmlDocument();
                using (MemoryStream ms = new MemoryStream())
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T), typeof(T).Assembly.GetName().Name);
                    serializer.Serialize(ms, t);
                    ms.Position = 0;
                    doc.Load(ms);
                    node = doc.LastChild;
                }
            }
            //反序列化XmlNode中的数据
            public static void DeSerialize<T>(XmlNode node, out T t)
            {
                XmlSerializer serializer = new XmlSerializer(typeof(T), typeof(T).Assembly.GetName().Name);
                XmlNodeReader reader = new XmlNodeReader(node);
                t=(T)serializer.Deserialize(reader);
            }
    
            //序列化到文件
            public static void SerializeFile<T>(T t, string filepath)
            {
               using(XmlWriter writer = new XmlTextWriter(filepath, Encoding.UTF8))
               {
                   XmlSerializer serializer = new XmlSerializer(typeof(T));
                   serializer.Serialize(writer,t);
               }
            }
    
            //将文件中的内容反序列化
            public static void DeSerializeFile<T>(string Filepath,out T t)
            {
                t = default(T);
                using (XmlReader reader = new XmlTextReader(Filepath))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    serializer.Deserialize(reader);
                }
            }
        }
    }
    

      XmlSerializer序列化规则:

       1.只能序列化public成员变量,protected、private、public static 声明的字段都不支持序列化。

       2.对象属性必须是可读可写。

       3.对象必须要有一个无参构造函数,用于反序列化。

       4.序列化的顺序和字段定义的顺序保持一致。

       5.序列化子类,而声明的是基类时,需要在基类中使用XmlInclude声明子类类型,例如下面的listCCAbstract字段。

    using System.Xml;
    using System.Xml.Serialization;
    using System.IO;
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Aa a = new Aa();
                PublicFunction.SerializeFile<Aa>(a, @"D:1.txt");
            }
        }
        [XmlRoot("AaRoot")]
        public class Aa 
        {
            public static string StaticParam;
            [XmlAttribute("Name")]
            public string name;
    
            [XmlIgnore]
            public string Ignore;
            protected string proparam;
            private int age;
            public int pAttribute
            {
                get;
                set;
            }
            [XmlArray("List")]
            [XmlArrayItem("Item")]
            public List<CCAbstract> listCCAbstract { get; set; }
    
            public Aa()
            {
                StaticParam = "StaticParam";
                this.name = "Aa";
                this.proparam = "Praparam";
                this.age = 23;
                pAttribute = 23;
                Ignore = "Ignpore";
                listCCAbstract = new List<CCAbstract> { new Cc("testCcAbstract") };
            }
        }
    
        [XmlInclude(typeof(Cc))]
        public abstract class CCAbstract
        {
        }
    
        public class Cc:CCAbstract
        {
            public string CName;
            public Cc()
            {
            }
            public Cc(string name)
            {
              this.CName=name;
            }
        }
    }
    

     序列化后的xml内容为:

    <?xml version="1.0" encoding="utf-8"?>
    <AaRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            Name="Aa">
      <pAttribute>23</pAttribute>
      <List>
        <Item xsi:type="Cc">
          <CName>testCcAbstract</CName>
        </Item>
      </List>
    </AaRoot>
    

     可以看到XmlRoot可以指定根结点名称,name不再作为XmlElement而是变成了AaRoot的属性。XmlIgnore标签标识的字段不进行序列化,protected、private、public static 声明的字段都不支持序列化。XmlArray可以指定List类型序列化后的名称,XmlArrayItem则对应List中的元素。

       6.尽量使用XmlSerializer(Type)、XmlSerializer(Type,String)这两种构造函数,如果使用其它构造函数则会导致内存泄漏。

    详情请看

    https://msdn.microsoft.com/zh-cn/library/system.xml.serialization.xmlserializer(VS.80).aspx

    为了提高性能,XML 序列化基础结构动态生成程序集,以便对指定类型进行序列化和反序列化。该基础结构将找到并重新使用这些程序集。仅当使用以下构造函数时,才会发生此行为:

    System.Xml.Serialization.XmlSerializer(Type)

    System.Xml.Serialization.XmlSerializer(Type,String)

    如果使用任何其他构造函数,则将生成同一个程序集的多个版本,这些版本始终不予卸载,从而导致内存泄漏和性能低下。最简单的解决方案是使用上面两个构造函数中的一个。

  • 相关阅读:
    安卓AndroidManifest.xml介绍
    Android系统开发入门
    蓝牙协议(bluetooth spec)
    解决:NoSuchAlgorithmException: Algorithm HmacSHA1 not available
    Spring bean 实现初始化、销毁方法的方式及顺序
    解决: maven编译项目报“非法字符: 65279 ”错误
    解决:eclipse 非正常关闭,导致无法正常启动
    ffmpeg 音频转换: use ffmpeg convert the audio from stereo to mono without changing the video part
    win10家庭版快速升级专业版
    Linux下更改目录及其下的子目录和文件的访问权限
  • 原文地址:https://www.cnblogs.com/lh218/p/4457719.html
Copyright © 2020-2023  润新知