可以用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:
有时候我们想向前台输出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 Status
17 {
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:
还有一个经常用到的场景就是,我们在获取列表数据的时候,经常是采用分页的形式,比如一页是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 Student
13 {
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 Student
26 {
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上我们还发现了
两个模板参数:j__TPar 和
两个字段:i__Field 和
两个属性方法:get_Name和get_Age,这里我们发现并没有set_Name和set_Age方法,也就说明该属性是个只读属性。
最后我们还发现匿名类型还重写了equals,gethashcode 和 toString 方法,这里我就只看下equals方法吧。
可以看到,当类型中有泛型参数的加入,IL代码就变得非常难看并且容易混淆,不过可以找到几个关键指令,在重写object的equals方法之后,
匿名类型中比较相等的方法是采用逐一字段比较的,这就跟值类型的比较方式很类似了,既然是逐一比较,那么下面的两个匿名对象应该是相等的。
这个在引用类型中是不可想象的。
不过有趣的是,这时候我们再来看看IL代码,发现并没有生成两个匿名类,而是json和json2公用一个匿名类,这个好处就是减少了IL的指令量,
可以说编译器还是非常智能的,能够将资源优化到最佳。
好了,大体原理就这样了,如果你够聪明,一定会找到适合它的项目场景的 ^_^。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net