zoukankan      html  css  js  c++  java
  • 泛型集合的序列化和反序列化

    1.    泛型集合的序列化比较简单,和普通对象没有两样,但是.net FrameWork里面没有提供现成的API,这是一个我自己封装的一个方法,采用了object作为被序列化对象的参数类型,亦即可以接受任意类型的对象,并通过调用GetType方法获得被序列化对象的转换前的类型(或者说是被序列化对象的真正类型,objectc#里是所有对象的基类),牺牲了一点点类型转换带来的性能损失,但是带来了很好的封装性,易用性。我简单了做了个对比测试,写了一个以具体类型作为参数的序列化方法,(方法内代码一模一样),序列化一个简单对象,重复执行1万次,相差大概10毫秒级,只要你对性能要求不是特别苛刻,我觉得都适合采用。

     

    /// <summary>

            /// 序列化成xml字符串

            /// </summary>

            /// <param name="obj"></param>

            /// <returns>序列化后的字符串</returns>

            public  string Serialize(object obj)

            {

                XmlSerializer xs = new XmlSerializer(obj.GetType());

                using (MemoryStream ms = new MemoryStream())

                {

                    System.Xml.XmlTextWriter xtw = new System.Xml.XmlTextWriter(ms, System.Text.Encoding.UTF8);

                    xtw.Formatting = System.Xml.Formatting.Indented;

                    xs.Serialize(xtw, obj);

                    ms.Seek(0, SeekOrigin.Begin);

                    using (StreamReader sr = new StreamReader(ms))

                    {

                        string str = sr.ReadToEnd();

                        xtw.Close();

                        ms.Close();

                        return str;

                    }

                }

            }

       调用代码举例如下:

        public class classA

        {

            public string name { get; set; }

            public string address { get; set; }

    }

        List<classA> list = new List<classA>() { new classA() { name = "1", address = "2" }, new classA { name = "2", address = "3" } };

     

    string s = Serialize(list);

     s = Serialize(new classA() { name = "1", address = "2" });

     

    2.   现在重点来说说集合对象的反序列化。翻遍了MSDN上关于序列化和反序列化的文章,都是长篇大论教你怎么序列化和反序列化一个对象,唯独没有讨论怎么序列化和反序列化集合对象的,

    更别提泛型集合了。当我在xml文件里直接录入两个结构一模一样的节点时,IDE智能感应提示我xml文件里必须有而且是唯一的一个根节点,也就是说,如果你想反序列化一个对象数组,

    classA[],你还必须得在xml文件里最外层节点套一个像<root></root>这样的根节点,反序列化以后得到root对象,通过读取这个root对象的属性才能得到这个对象数组,

    有没有直接一点的办法呢?于是我调用前面写好的序列化方法,把一个集合对象序列化成字符串,得到的字符串形式如下<ArrayOfClassA><classA>..</classA></ ArrayOfClassA>,

    看到这里,相信聪明的读者也领悟到了,只要往xml文件按这种格式编写,root替换成ArrayOfClassA(注意这里classA首字母变成大写了),反序列化时候就能直接得到classA[],对于 List<classA>也一样。所以,xml文件编写格式举例如下:

    <?xml version="1.0" encoding="utf-8"?>

    <ArrayOfClassA>

      <classA>

        <name>111</name>

        <address>222</address>

      </classA>

      <classA>

        <name>2111</name>

        <address>1222</address>

      </classA>

    </ArrayOfClassA>

     

    .net FrameWork里既有对xml字符串的反序列化方法,也有对xml文件的反序列化方法,对比了一下代码,无非就是流读取对象不一样,一个是StringReader,StreamReader,而他们都继承于TextReader我干脆把它们都集合为一个方法。反序列化的封装方法如下:

     

    /// <summary>

            /// 反序列化方法

            /// </summary>     

            /// <param name="xml">xml字符串</param>   

            /// <param name="type">反序列化对象的类型</param>   

            /// <returns>反序列化后的对象</returns>

            public object Desrialize(string xml, Type type)

            {

                object obj = null;

                XmlSerializer xs = new XmlSerializer(type);

                TextReader tr;

                if (!File.Exists(xml))

                {

                    tr = new StringReader(xml);

                }

                else

                {

                    tr = new StreamReader(xml);

                }

                using (tr)

                {

                    obj = xs.Deserialize(tr);

                }

                return obj;

            }

    调用代码如下        

           List<classA> list = Desrialize("xxx.xml",typeof(List<classA>)) as List<classA>;

     

    当然也可反序列化单个对象

           classA  item = Desrialize("xxx.xml",typeof(classA)) as classA;

     

    然而,这里还是觉得不够完美,因为泛型没用上啊:

             /// <summary>

           /// 反序列化方法

           /// </summary>

           /// <typeparam name="T">反序列化对象类型</typeparam>

           /// <param name="xml">反序列化字符串或者xml文件路径</param>

           /// <returns></returns>

            public T Desrialize<T>(string xml)

            {

                T obj = default(T);

                XmlSerializer xs = new XmlSerializer(typeof(T));

                TextReader tr;

     

                if (!File.Exists(xml))

                {

                    tr = new StringReader(xml);

                }

                else

                {

                    tr = new StreamReader(xml);

                }

                using (tr)

                {

                    obj = (T)xs.Deserialize(tr);

                }

                return obj;

            }

     

    调用代码如下        

           List<classA> list = Desrialize<List<classA>>("xxx.xml");

     

    当然也可反序列化单个对象

           classA  item = Desrialize<classA>("xxx.xml");

     

  • 相关阅读:
    [转载]JavaScript世界的一等公民 函数
    JavaScript基础知识词法结构
    JavaScript触发asp.net服务器端控件事件
    WinForm窗体间传值大全
    快速导入Excel
    让虚拟机支持USB HDD 启动
    常见的mysql导出excel工具介绍
    silverlight 播放器,丑丑版
    快速导出Excel
    一个C#编写QQ接口软件QQ协议(转)
  • 原文地址:https://www.cnblogs.com/lindping/p/2004836.html
Copyright © 2011-2022 走看看