博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
看看这个超级实用的一种类型——匿名类型
阅读量:5283 次
发布时间:2019-06-14

本文共 4604 字,大约阅读时间需要 15 分钟。

原文:

  既然说到匿名类型超级实用,得要找到场景来说服一下,如果大家玩过php,里面有一个万能的关联数组array,任你在关联数组array里面怎么写,都

可以用json_encode来生成json,非常非常的方便。

"hxc","age"=20,"isMale"=>true); //也可以这么写 $arrayName = array("list" =>array( array("name" => "john", "age" => "20","isMale" => true), array("name" => "mary", "age" => "24","isMale" => false), array("name" => "jackson", "age" => "30","isMale" => true) ),"totalCount"=>100); $json=json_encode($arr); echo $json;?>

 

而在使用C#的时候,我们要向前台输出json的时候,都是要先定义一个实体,再给实体各种赋值,然后序列化成json的形式输出到前台,就比如下面这样:

 

1     public class Program 2     { 3         static void Main(string[] args) 4         { 5             var json = new Student() { Name = "john", Age = 25, IsMale = true }; 6  7             JavaScriptSerializer js = new JavaScriptSerializer(); 8  9             var r = js.Serialize(json);10     }

 

自从.netframework 3.5中新增了匿名类型之后,一切都有了新的变化。

 

一:寻找场景

<1>  场景1:

   有时候我们想向前台输出json,但是这个json是个非常简单的状态json,就像这样{"status":"1","message":"提交成功"},但是以往的做法我必须要自己

先定义一个状态类,再序列化它,就像下面这样。

1     public class Program 2     { 3         static void Main(string[] args) 4         { 5             var json = new Status() { status = "1", message = "提交成功" }; 6  7             JavaScriptSerializer js = new JavaScriptSerializer(); 8  9             var result = js.Serialize(json);10 11             Console.WriteLine(result);12 13             Console.Read();14         }15 16         public class Status17         {18             public string status { get; set; }19 20             public string message { get; set; }21         }22     }

 

再看看我们使用匿名类型的话,会是怎样?

1         static void Main(string[] args) 2         { 3             var json = new { status = "1", message = "提交成功" }; 4  5             JavaScriptSerializer js = new JavaScriptSerializer(); 6  7             var result = js.Serialize(json); 8  9             Console.WriteLine(result);10 11             Console.Read();12         }

从上下文的代码量来说,确实让我们少写了很多代码,也就提高了我们的开发效率,有了这个匿名类型之后,我们也可以像php的array一样,随心所欲的定义

简单或者复杂的结构,然后序列化为json。

 

<2> 场景2:

    还有一个经常用到的场景就是,我们在获取列表数据的时候,经常是采用分页的形式,比如一页是20条数据,但是为了前端方便分页,后端必须要传递一

个totalcout参数,这样的话,前端才知道pagecount=Math.ceil(totalcount/pagesize),算出总页数,在传统的方法上,我们需要在底层的List上再包装

一个类,然后再在这个类中增加一个totalcount属性,就像下面这样。

1     ///  2     /// 集合包装类 3     ///  4     public class StudentPage 5     { 6         public List
list { get; set; } 7 public int total { get; set; } 8 } 9 ///
10 /// student实体类11 /// 12 public class Student13 {14 public string Name { get; set; }15 16 public int Age { get; set; }17 18 public bool IsMale { get; set; }19 }

 

有了匿名类型之后,我们再也不用这么写了,应该像下面这样。

 

1     public class Program 2     { 3         static void Main(string[] args) 4         { 5             var list = new List
() 6 { 7 new Student(){ Name="john", Age=25, IsMale=true}, 8 new Student(){ Name="mary", Age=24, IsMale=false}, 9 new Student(){ Name="jackson",Age=30,IsMale=true}10 };11 12 //核心点13 var json = new { List = list, TotalCount = 20 };14 15 JavaScriptSerializer js = new JavaScriptSerializer();16 17 var result = js.Serialize(json);18 19 Console.WriteLine(result);20 21 Console.Read();22 }23 }24 25 public class Student26 {27 public string Name { get; set; }28 29 public int Age { get; set; }30 31 public bool IsMale { get; set; }32 }

 

看到这样的json是不是有一种很爽的感觉?是的,确实在我们开发中非常的实用,那么问题来了,这么实用东西,它的原理在哪里可以学得到?

 

二:基本原理

  既然想学,我们就剖析下它的IL代码,看看这个东西到底都做了些什么?为了方便理解,我就定义一个非常简单的匿名类。

1 var json = new { Name = "jackson", Age = 20 };

 

然后我们看看IL中到底都发生了什么?

 

不看IL还好,一看真是吓一跳,就一句话的事情,变成IL后就有这么多的玩意。。。而且类名取得也是非常奇葩,开头居然有<>这种尖括号,当

然这么写的原因很简单,就是避免我们定义的类名与自动生成的相冲突,再说编译器也不允许用<>开头的类名,虽然在CLR层面是允许的,好了,

我们继续往下面,从IL上我们还发现了

两个模板参数:<Age>j__TPar 和 <Name>j__TPar。

两个字段:<Age>i__Field 和<Name>i__Field。

两个属性方法:get_Name和get_Age,这里我们发现并没有set_Name和set_Age方法,也就说明该属性是个只读属性。

 

最后我们还发现匿名类型还重写了equals,gethashcode 和 toString 方法,这里我就只看下equals方法吧。

 

 

可以看到,当类型中有泛型参数的加入,IL代码就变得非常难看并且容易混淆,不过可以找到几个关键指令,在重写object的equals方法之后,

匿名类型中比较相等的方法是采用逐一字段比较的,这就跟值类型的比较方式很类似了,既然是逐一比较,那么下面的两个匿名对象应该是相等的。

这个在引用类型中是不可想象的。

 

不过有趣的是,这时候我们再来看看IL代码,发现并没有生成两个匿名类,而是json和json2公用一个匿名类,这个好处就是减少了IL的指令量,

可以说编译器还是非常智能的,能够将资源优化到最佳。

 

好了,大体原理就这样了,如果你够聪明,一定会找到适合它的项目场景的 ^_^。

 

posted on
2015-01-16 14:51 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/4228731.html

你可能感兴趣的文章
Android 设置界面的圆角选项
查看>>
百度地图api服务端根据经纬度得到地址
查看>>
根据xml生成相应的对象类
查看>>
Android StageFrightMediaScanner源码解析
查看>>
打包java程序生成exe
查看>>
八叉树
查看>>
Git 远程仓库
查看>>
关于静态文本框透明度的问题
查看>>
javascript的发展及个人笔记
查看>>
全选,反全选,反选,获取选中的值,根据子选择控制全选按钮
查看>>
[CF#250 Div.2 D]The Child and Zoo(并查集)
查看>>
博客园博客插入公式
查看>>
hdu 1028 Ignatius and the Princess III(母函数入门+模板)
查看>>
Ubuntu下配置安装telnet server
查看>>
Codeforces 235 E Number Challenge
查看>>
ubuntu 常见命令整理
查看>>
EJBCA安装教程+postgresql+wildfly10
查看>>
(五十四)涂鸦的实现和截图的保存
查看>>
配置EditPlus使其可以编译运行java程序
查看>>
java中的占位符\t\n\r\f
查看>>