zoukankan      html  css  js  c++  java
  • Json和序列化总结

    一、序言

       遇到问题,就经常逛园,不知你是否曾有,曾经遇到的问题,或者在园子里看到问题的方案,过一段时间,有可能还会摔跤,哈哈...大神请勿喷,小弟记忆不太好,还过来找资料,如果自己写把问题或某个知识点总结,问题会更深刻,自己写的东西更能熟悉的了解。看别人写的文章,那是相当的羡慕,可能因为不敢写,懒惰等等个人原因,一直处于跑步机上停留,从没前进一大步,一直只是想写阶段。今天尝试改变一点点过去的自己,从部分知识的梳理总结,在梳理过程中如果出现不对,错误的地方,还请大神多多指出.......废话少说,第一天的主题:Json和序列化

    二、json 和序列化

      首先我们先对json和序列化初步了解,之前面试面试官也问过相关的问题,什么是json,几种展现方式,你通常用序列化工具是什么,它有什么优势,下面通过简单的一个画图,说明json和序列化的认识和介绍:

    三、代码实例

        我们很多时候会涉及到几个序列化对象的使用:DataContractJsonSerializer,JavaScriptSerializer 和 Json.NET(Newtonsoft)。 少废话,上代码,下面就一个个登场:

      第一个主角:JavaScriptSerializer

         (1)首先我们添加 先添加引用 System.Web.Extensions  

            备注:  JavaScriptSerializer类  应用json.net 使用序列化和反序列化,为启动Ajax的应用程序提供序列化和反序列化

             命名空间:   System.Web.Script.Serialization
             程序集:  System.Web.Extensions(位于 System.Web.Extensions.dll)

     代码 实例

     static void Main(string[] args)
            {
                List<User> userList = new List<User>() { 
                new User { Name="帅哥",Age=13,Gender=""},
                new User { Name="美女",Age=13,Gender=""}
                };
                // JavaScriptSerializer序列化 
                var javaScrittLizer = new JavaScriptSerializer().Serialize(userList);
                Console.WriteLine("序列化:"+javaScrittLizer);
    
    
                // JavaScriptSerializer反序列化
                string strJson = "{"Name":"张三","Age":28,"Gender":"女"}";
                var deserialize = new JavaScriptSerializer().Deserialize<User>(strJson);
                Console.WriteLine("反序列化:姓名:"+ deserialize.Name+"年龄:"+deserialize.Age);
                Console.ReadKey();
            }
    
            public class User
            {
                public string Name { get; set; }
                public int Age { get; set; }
                public string Gender { get; set; }
            }

    结果:

    第二个主角:Json.NET

         (1)第一步先在Negut添加安装包

       (2)添加2.添加Newtonsoft.Json  和  Newtonsoft.Json.Linq 引用

       (3)Newtonsoft.Json我们主要使用三个方法,基本就能满足我们日常开发: 序列化:SerializeObject(), 反序列化:DeserializeObject()

                还有一个可能没有对应的实体类型(或者说不想添加对应的实体类),这时候可以用匿名对象解析方法DeserializeAnonymousType(),方便快捷,对应代码如下:

        (4)总结:Newtonsoft.Json采用了Emit缓存优化,运行效率比较接近于fastCSharp生成的手工代码效率了,真的很不错,后面我们测试数据展示给你大家,

     // 1.先从NuGet中添加Json.net  
            // 2.添加Newtonsoft.Json  和  Newtonsoft.Json.Linq 引用
            static void Main(string[] args)
            {
                List<User> userList = new List<User>() { 
                new User { Name="帅哥",Age=13,Gender=""},
                new User { Name="美女",Age=13,Gender=""}
                };
    
                //序列化
                var userserializer = JsonConvert.SerializeObject(userList);
                Console.WriteLine("序列化:"+ userserializer);
    
                //反序列化
                string strJson = "{"Name":"张三","Age":28,"Gender":"女"}";
                User user = JsonConvert.DeserializeObject<User>(strJson);
                Console.WriteLine("反序列化:姓名:{0},年龄:{1},性别:{2}", user.Name, user.Age, user.Gender);
    
                //匿名反序列化
                //可能没有对应的实体类型(或者说不想添加对应的实体类),这时候可以用匿名对象解析方法DeserializeAnonymousType(),方便快捷,对应代码如下:
                var tempEntity = new { Name = "0", Gender = string.Empty };
                tempEntity = JsonConvert.DeserializeAnonymousType("{"Name":"帅哥","Gender":"男"}", tempEntity);
                Console.WriteLine("匿名序列化: 姓名:" + tempEntity.Name + ",性别:" + tempEntity.Gender);
                Console.ReadKey();
            }
    
            public class User
            {
                public string Name { get; set; }
                public int Age { get; set; }
                public string Gender { get; set; }
            }

     效果显示:

      

     第三个主角:DataContractJsonSerializer

      (1)老规矩,需要添加引用:System.ServiceModel.Web 和 System.Runtime.Serialization

      (2)程序员就要干脆点,直接上代码:

           做DataContractJsonSerializer  demo测试的时候出现小插曲:

          (1)反序列化的时候,敲代码不小心  Deault 采用ANSI编码,不会编译报错,但是没有显示反序列化结果,大家小心,因为这里是UTF8  编码

          (2)User类中如果不加    [Serializable]   [DataContract]  这属性,会直接报错,为啥报错,我也百度了相关资料,代码中已经做出解释, 如果不加还会显示这样的字符串:<Name>k_BackingField

          大家可以去试试,为啥出现,代码和下面总结中会给出答案。

          还不懂的可以访问::: https://msdn.microsoft.com/zh-cn/library/bb412179.aspx

     /// <summary>
            /// DataContractJsonSerializer序列化案例
            /// 需要添加引用:System.ServiceModel.Web 和 System.Runtime.Serialization
            /// </summary>
            /// <param name="args"></param>
            static void Main(string[] args)
            {
                List<User> userList = new List<User>() { 
                new User { Name="帅哥",Age=13,Gender=""},
                new User { Name="美女",Age=13,Gender=""}
                };
    
                //序列化
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<User>));
                using (MemoryStream stream = new MemoryStream())
                {
                    serializer.WriteObject(stream, userList);
                    var dataString = Encoding.UTF8.GetString(stream.ToArray());
                    Console.WriteLine("序列化:" + dataString);
                }
    
                //序列化
                string strJson = "{"Name":"张三","Age":28,"Gender":"女"}";
                DataContractJsonSerializer desserializer = new DataContractJsonSerializer(typeof(User));
                var mStream = new MemoryStream(Encoding.Default.GetBytes(strJson));
                User desUser = (User)desserializer.ReadObject(mStream);
                Console.WriteLine("反序列化:" + "姓名:" + desUser.Name + ",年龄:" + desUser.Age);
                Console.ReadKey();
            }
    
            //Serializable特性的作用
            ///序列化的attribute,是为了利用序列化的技术 准备用于序列化的对象必须设置 [System.Serializable] 标签,
            ///该标签指示一个类可以序列化。 便于在网络中传输和保存这个标签是类可以被序列化的特性,表示这个类可以被序列化。
    
            ///数据契约(DataContract) 服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型。
            ///一旦声明一个类型为DataContract,那么该类型就可以被序列化在服务端和客户端之间传送,如下所示。
            [Serializable]  //指示一个类可以序列化 
            [DataContract]
            public class User
            {
                [DataMember]
                public string Name { get; set; }
                [DataMember]
                public int Age { get; set; }
                [DataMember]
                public string Gender { get; set; }
            }

    测试 效果:

    上网也看了查了很多资料,他们三个比较中性能的比较:最好使用第三方:Json.net,(个人推荐

     资料链接:  http://json.codeplex.com/  也可以在里面下载源码,研究研究,嘿嘿

    俗话说的好,不为书,只为实,那我们就来一下检测吧,实践才是检验真理的唯一标准,不能道听途说,哈哈哈哈。。。。。在此声明,我只能去验证它,不是挑战它,哈哈

     电脑配置配置原因,有些东西,没有显示上图效果,还是别的原因,大神有知道,还请多多指教  。。。。。

    static void Main(string[] args)
            {
                User user = new User { Name = "帅哥", Age = 20, Gender = "" };
                List<User> userList = new List<User>();
                for (int i = 0; i < 5000; i++)
                {
                    userList.Add(user);
                }
    
                Stopwatch sw = new Stopwatch();
                Stopwatch sw1 = new Stopwatch();
                Stopwatch sw2 = new Stopwatch();
    
                // JavaScriptSerializer序列化 
                sw.Start();
               //  var javaScrittLizer = new JavaScriptSerializer().Serialize(userList);
                Console.WriteLine("JavaScriptSerializer序列化:" + sw.Elapsed);
    
                //JsonConvert序列化
                sw1.Start();
                var userserializer = JsonConvert.SerializeObject(userList);
                Console.WriteLine("JsonConvert序列化:" + sw1.Elapsed);
    
                //DataContractJsonSerializer序列化
                sw2.Start();
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<User>));
                using (MemoryStream stream = new MemoryStream())
                {
                    serializer.WriteObject(stream, userList);
                    var dataString = Encoding.UTF8.GetString(stream.ToArray());
                    Console.WriteLine("DataContractJsonSerializer序列化:" + sw2.Elapsed);
                }
                Console.ReadKey();
            }
    
            [Serializable]  //指示一个类可以序列化 
            [DataContract]
            public class User
            {
                [DataMember]
                public string Name { get; set; }
                [DataMember]
                public int Age { get; set; }
                [DataMember]
                public string Gender { get; set; }
            }

     

    总结:

    Newtonsoft.Json采用了Emit缓存优化,运行效率比较接近于fastCSharp生成的手工代码效率了,真的很不错
     DataContractJsonSerializer在.NET Framework 3.5中引入,主要因为WCF的引入而添加了这个对象序列化的基本方法,并且微软同时将JavaScriptSerializer打上了过时(obsolete)的标签,编译时就会有警告出现。
    而在.NET Framework 3.5 SP1中,微软又将JavaScriptSerializer的“过时”标签给去掉了。
    使用Reflector去比较这两个类的内部实现发现,DataContractJsonSerializer在对象序列化时进行了更为严格的检查,感兴趣的可以去System.Runtime.Serialization.Json下面的核心方法InternalWriteObjectContent去看其实现。
    而在.NET Framework 3.5引入的自动属性,实际上就是个语法糖,编译器还是会生成一个int类型的<Name>k_BackingField的私有字段作为这个属性的后端字段,内部还是和以前的get/set方法一样。
    所以直接使用DataContractJsonSerializer进行序列化时,又将编译器生成的k_BackingField带了出来。
    而JavaScriptSerializer的实现则非常简单,将属性名和属性值分别存储在Dictionary里,然后进行字符串拼接返回而已,所以对类定义几乎没有检查并且对复杂类的支持不太好。

    以上都是本人,个人理解,有错误的地方,还请大神多多指教.....哈哈哈,第一篇终于写完了,不好的地方多多包涵。

  • 相关阅读:
    js 小程序获取本周七天
    js 时间处理函数 获取今天的前几天和后几天的任意一天
    路由配置
    3 vue-router 的默认hash 改mode:history去除#号 传参
    Eslint 配置及规则说明(报错)
    打开左侧菜单栏
    sublime 对vue的高亮显示
    gitlab 本地建库配置 config
    GIT 安装
    v-html的应用
  • 原文地址:https://www.cnblogs.com/lrzr/p/7275923.html
Copyright © 2011-2022 走看看