热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#用XmlSerializer进行序列化和反序列化

和BinaryFormatter序列化一样,做一个可以序列化的类Person:namespaceSerializable{[Serializable]

和BinaryFormatter序列化一样,做一个可以序列化的类Person:

namespace Serializable
{
    [Serializable] //不可少! 
    public class Person
    {
        private String name;
        private String sex;
        private int age;

        public Person() //XmlSerializer序列化要求一定要有无参数构造函数 
        {
            name = "";
            sex = "";
            age = 0;
        }

        public Person(String n, String s, int a)
        {
            name = n;
            sex = s;
            age = a;
        }

        public String Name
        {
            get 
            {
                return name;
            }
            set 
            {
                name = value;
            }
        }

        public String Sex
        {
            get
            {
                return sex;
            }
            set
            {
                sex = value;
            }
        }

        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                age = value;
            }
        }
    }
}

 

//主运行程序

namespace Serializable
{
    class Program
    {
        static void Main(string[] args)
        {
            Person p1 = new Person("张三", "男", 20);
            //序列化
            try
            {
                FileStream fs = new FileStream("serialiable.xml", FileMode.Create);
                XmlSerializer xs = new XmlSerializer(typeof(Person));
                xs.Serialize(fs, p1);
                fs.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.WriteLine("序列化成功!");

            Console.Read();

            //反序列化
            try
            {
                FileStream fs = new FileStream("serialiable.xml", FileMode.Open, FileAccess.Read);
                XmlSerializer xs = new XmlSerializer(typeof(Person));
                Person p = (Person)xs.Deserialize(fs);
                Console.WriteLine(p.Name + p.Sex + p.Age);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.Read();
            Console.Read();
        }
    }
}

 

结果图:

 

生成的XML文件:

  1. 这篇随笔对应的.Net命名空间是System.Xml.Serialization;文中的示例代码需要引用这个命名空间。
  2. 为什么要做序列化和反序列化?
  3. .Net程序执行时,对象都驻留在内存中;内存中的对象如果需要传递给其他系统使用;或者在关机时需要保存下来以便下次再次启动程序使用就需要序列化和反序列化。
  4. 范围:本文只介绍xml序列化,其实序列化可以是二进制的序列化,也可以是其他格式的序列化。
  5. 看一段最简单的Xml序列化代码
  6. class Program
  7. {
  8. static void Main(string[] args)
  9. {
  10. int i = 10;
  11. //声明Xml序列化对象实例serializer
  12. XmlSerializer serializer = new XmlSerializer(typeof(int));
  13. //执行序列化并将序列化结果输出到控制台
  14. serializer.Serialize(Console.Out, i);
  15. Console.Read();
  16. }
  17. }
  18. 上面代码对int i进行了序列化,并将序列化的结果输出到了控制台,输出结果如下
  19. "1.0" encoding="gb2312"?>
  20. <int>10int>
  21. 可以将上述序列化的xml进行反序列化&#xff0c;如下代码
  22. static void Main(string[] args)
  23. {
  24. using (StringReader rdr &#61; new StringReader(&#64;"
  25. 10"))
  26. {
  27. //声明序列化对象实例serializer
  28. XmlSerializer serializer &#61; new XmlSerializer(typeof(int));
  29. //反序列化&#xff0c;并将反序列化结果值赋给变量i
  30. int i &#61; (int)serializer.Deserialize(rdr);
  31. //输出反序列化结果
  32. Console.WriteLine("i &#61; " &#43; i);
  33. Console.Read();
  34. }
  35. }
  36. 以上代码用最简单的方式说明了xml序列化和反序列化的过程&#xff0c;.Net系统类库为我们做了大量的工作&#xff0c;序列化和反序列化都非常简单。但是在现实中业务需求往往比较复杂&#xff0c;不可能只简单的序列化一个int变量&#xff0c;显示中我们需要对复杂类型进行可控制的序列化。
  37. 自定义对象的Xml序列化&#xff1a;
  38. System.Xml.Serialization命名空间中有一系列的特性类&#xff0c;用来控制复杂类型序列化的控制。例如XmlElementAttribute、XmlAttributeAttribute、XmlArrayAttribute、XmlArrayItemAttribute、XmlRootAttribute等等。
  39. 看一个小例子&#xff0c;有一个自定义类Cat&#xff0c;Cat类有三个属性分别为Color&#xff0c;Saying&#xff0c;Speed。
  40. namespace UseXmlSerialization
  41. {
  42. class Program
  43. {
  44. static void Main(string[] args)
  45. {
  46. //声明一个猫咪对象
  47. var c &#61; new Cat { Color &#61; "White", Speed &#61; 10, Saying &#61; "White or black,  so long as the cat can catch mice,  it is a good cat" };
  48. //序列化这个对象
  49. XmlSerializer serializer &#61; new XmlSerializer(typeof(Cat));
  50. //将对象序列化输出到控制台
  51. serializer.Serialize(Console.Out, c);
  52. Console.Read();
  53. }
  54. }
  55. [XmlRoot("cat")]
  56. public class Cat
  57. {
  58. //定义Color属性的序列化为cat节点的属性
  59. [XmlAttribute("color")]
  60. public string Color { get; set; }
  61. //要求不序列化Speed属性
  62. [XmlIgnore]
  63. public int Speed { get; set; }
  64. //设置Saying属性序列化为Xml子元素
  65. [XmlElement("saying")]
  66. public string Saying { get; set; }
  67. }
  68. }
  69. 可以使用XmlElement指定属性序列化为子节点&#xff08;默认情况会序列化为子节点&#xff09;&#xff1b;或者使用XmlAttribute特性制定属性序列化为Xml节点的属性&#xff1b;还可以通过XmlIgnore特性修饰要求序列化程序不序列化修饰属性。
  70. 对象数组的Xml序列化&#xff1a;
  71. 数组的Xml序列化需要使用XmlArrayAttribute和XmlArrayItemAttribute&#xff1b;XmlArrayAttribute指定数组元素的Xml节点名&#xff0c;XmlArrayItemAttribute指定数组元素的Xml节点名。
  72. 如下代码示例&#xff1a;
  73. using System;
  74. using System.Collections.Generic;
  75. using System.Linq;
  76. using System.Text;
  77. using System.Xml.Serialization;
  78. namespace UseXmlSerialization
  79. {
  80. class Program
  81. {
  82. static void Main(string[] args)
  83. {
  84. //声明一个猫咪对象
  85. var cWhite &#61; new Cat { Color &#61; "White", Speed &#61; 10, Saying &#61; "White or black,  so long as the cat can catch mice,  it is a good cat" };
  86. var cBlack &#61; new Cat { Color &#61; "Black", Speed &#61; 10, Saying &#61; "White or black,  so long as the cat can catch mice,  it is a good cat" };
  87. CatCollection cc &#61; new CatCollection { Cats &#61; new Cat[] { cWhite,cBlack} };
  88. //序列化这个对象
  89. XmlSerializer serializer &#61; new XmlSerializer(typeof(CatCollection));
  90. //将对象序列化输出到控制台
  91. serializer.Serialize(Console.Out, cc);
  92. Console.Read();
  93. }
  94. }
  95. [XmlRoot("cats")]
  96. public class CatCollection
  97. {
  98. [XmlArray("items"),XmlArrayItem("item")]
  99. public Cat[] Cats { get; set; }
  100. }
  101. [XmlRoot("cat")]
  102. public class Cat
  103. {
  104. //定义Color属性的序列化为cat节点的属性
  105. [XmlAttribute("color")]
  106. public string Color { get; set; }
  107. //要求不序列化Speed属性
  108. [XmlIgnore]
  109. public int Speed { get; set; }
  110. //设置Saying属性序列化为Xml子元素
  111. [XmlElement("saying")]
  112. public string Saying { get; set; }
  113. }
  114. }
  115. 以上代码将输出&#xff1a;
  116. "1.0" encoding&#61;"gb2312"?>
  117. "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd&#61;"http://ww
  118. w.w3.org/2001/XMLSchema">
  119. "White">
  120. White or black,  so long as the cat can catch mice,  it is a good
  121. cat
  122. "Black">
  123. White or black,  so long as the cat can catch mice,  it is a good
  124. cat
  125. XmlSerializer内存泄漏问题&#xff1a;
  126. 仔细看了下msdn&#xff0c;确实存在泄漏的情况&#xff0c;msdn说明如下&#xff1a;
  127. 动态生成的程序集
  128. 为了提高性能&#xff0c;XML 序列化基础结构将动态生成程序集&#xff0c;以序列化和反序列化指定类型。此基础结构将查找并重复使用这些程序集。此行为仅在使用以下构造函数时发生&#xff1a;
  129. XmlSerializer(Type)
  130. XmlSerializer.XmlSerializer(Type, String)
  131. 如果使用任何其他构造函数&#xff0c;则会生成同一程序集的多个版本&#xff0c;且绝不会被卸载&#xff0c;这将导致内存泄漏和性能降低。最简单的解决方案是使用先前提到的两个构造函数的其中一个。否则&#xff0c;必须在 Hashtable 中缓存程序集&#xff0c;如以下示例中所示。
  132. 也就是说我们在使用XmlSerializer序列化&#xff0c;初始化XmlSerializer对象时最好使用下面两个构造函数否则会引起内存泄漏。
  133. XmlSerializer(Type)
  134. XmlSerializer.XmlSerializer(Type, String)




推荐阅读
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文为Codeforces 1294A题目的解析,主要讨论了Collecting Coins整除+不整除问题。文章详细介绍了题目的背景和要求,并给出了解题思路和代码实现。同时提供了在线测评地址和相关参考链接。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
author-avatar
ESC咻咻_973
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有