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)

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

时间: 2024-10-23 23:08:53

XmlSerializer序列化小结的相关文章

java对象序列化小结

百度百科上介绍序列化是这样的: 序列化 (Serialization): 将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象. 序列化使其他代码可以查看或修改那些不序列化便无法访问的对象实例数据.确切地说,代码执行序列化需要特殊的权限:即指定了 SerializationFormatter 标志的 SecurityPermission.在默认策略下,通过 Internet 下载

C# XmlSerializer序列化浅析

C# 中使用 XmlSerializer 实现类和xml文件的序列化和反序列化,使用起来非常简单. C# XmlSerializer实现序列化: XmlSerializer xml = new XmlSerializer(typeof(ClassName)); FileStream fs = new FileStream(@"d:\t.xml",FileMode.Create); xml.Serialize(fs, new Class()); fs.Close(); C# XmlSer

.NET调用外部接口将得到的List数据,并使用XmlSerializer序列化List对象成XML格式

BidOpeningData.BidSupervisionSoapClient client = new BidOpeningData.BidSupervisionSoapClient(); Dictionary<string, string> param = new Dictionary<string, string>(); param.Add(CommonParam.ConnKey, DBConnHelper.GetConnectionKey(DBConnHelper.Busi

C#调用XmlSerializer序列化时生成CDATA节点解决方法

public class Person{    public string Name { get; set; }    public int Age { get; set; }        } 引用内容 <?xml version="1.0"?><Person xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-

XmlSerializer 对象的Xml序列化和反序列化,XMLROOT别名设置

这篇随笔对应的.Net命名空间是System.Xml.Serialization:文中的示例代码需要引用这个命名空间. 为什么要做序列化和反序列化? .Net程序执行时,对象都驻留在内存中:内存中的对象如果需要传递给其他系统使用:或者在关机时需要保存下来以便下次再次启动程序使用就需要序列化和反序列化. 范围:本文只介绍xml序列化,其实序列化可以是二进制的序列化,也可以是其他格式的序列化. 看一段最简单的Xml序列化代码 1 2 3 4 5 6 7 8 9 10 11 12 class Prog

C# XmlSerializer 对象的Xml序列化和反序列化

.Net程序执行时,对象都驻留在内存中:内存中的对象如果需要传递给其他系统使用:或者在关机时需要保存下来以便下次再次启动程序使用就需要序列化和反序列化. System.Xml.Serialization命名空间中有一系列的特性类,用来控制复杂类型序列化.例如XmlElementAttribute.XmlAttributeAttribute.XmlArrayAttribute.XmlArrayItemAttribute.XmlRootAttribute等等. 可以使用XmlElement指定属性序

java枚举小结

在百度百科上是这样介绍枚举的: 在C#或C++,java等一些计算机编程语言中,枚举类型是一种基本数据类型而不是构造数据类型,而在C语言等计算机编程语言中,它是一种构造数据类型.枚举类型用于声明一组命名的常数,当一个变量有几种可能的取值时,可以将它定义为枚举类型. 而在java中,枚举扩大了这一概念,因为在java中,枚举已经称为一个类,因此完全具有类的特性. 我们都知道枚举是JDK1.5才推出的新概念,那么在此之前,我们如果想使用一些固定的常量集合,比如性别(2个),季节(4个),星期(7个)

C#编程总结(一)序列化

C#编程总结(一)序列化 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储和传输数据. 几种序列化技术:      1)二进制序列化保持类型保真度,这对于在应用程序的不同调用之间保留对象的状态很有用.例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象.您可以将对象序列化到流.磁盘.内存和网络等等.远程处理使用序列化“通过值”在计算机或应用程序域之间传递对象.      2)XML 序列化仅序列化公共属性和

十五天精通WCF——第十二天 说说wcf中的那几种序列化

我们都知道wcf是由信道栈组成的,在我们传输的参数走到传输信道层之前,先需要经过序列化的过程,也就是将参数序列化为message,这篇 我们就来说说这里的序列化,蛮有意思的,可能初学者也明白,在wcf中默认的序列化是DataContractSerializer,确实是这样,不过wcf在信道中 其实不仅仅支持DataContractSerializer,它还支持其他类型的序列化,比如XmlSerializer,NetDataContractSerializer以及DataContractJson