看看这个超级实用的一种类型——匿名类型

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

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

<?php
   //可以这么写
   $arr= array("name"=>"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的形式输出到前台,就比如下面这样:

 

public class Program
    {
        static void Main(string[] args)
        {
            var json = new Student() { Name = "john", Age = 25, IsMale = true };

            JavaScriptSerializer js = new JavaScriptSerializer();

            var r = js.Serialize(json);
    }

 

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

 

一:寻找场景

<1>  场景1:

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

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

public class Program
    {
        static void Main(string[] args)
        {
            var json = new Status() { status = "1", message = "提交成功" };

            JavaScriptSerializer js = new JavaScriptSerializer();

            var result = js.Serialize(json);

            Console.WriteLine(result);

            Console.Read();
        }

        public class Status
        {
            public string status { get; set; }

            public string message { get; set; }
        }
    }

 

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

static void Main(string[] args)
        {
            var json = new { status = "1", message = "提交成功" };

            JavaScriptSerializer js = new JavaScriptSerializer();

            var result = js.Serialize(json);

            Console.WriteLine(result);

            Console.Read();
        }

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

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

 

<2> 场景2:

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

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

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

/// <summary>
    /// 集合包装类
    /// </summary>
    public class StudentPage
    {
        public List<Student> list { get; set; }
        public int total { get; set; }
    }
    /// <summary>
    /// student实体类
    /// </summary>
    public class Student
    {
        public string Name { get; set; }

        public int Age { get; set; }

        public bool IsMale { get; set; }
    }

 

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

 

public class Program
    {
        static void Main(string[] args)
        {
            var list = new List<Student>()
            {
                  new Student(){ Name="john", Age=25, IsMale=true},
                  new Student(){ Name="mary", Age=24, IsMale=false},
                  new Student(){ Name="jackson",Age=30,IsMale=true}
            };

            //核心点
            var json = new { List = list, TotalCount = 20 };

            JavaScriptSerializer js = new JavaScriptSerializer();

            var result = js.Serialize(json);

            Console.WriteLine(result);

            Console.Read();
        }
    }

    public class Student
    {
        public string Name { get; set; }

        public int Age { get; set; }

        public bool IsMale { get; set; }
    }

 

看到这样的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的指令量,

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

 

时间: 2024-08-25 17:39:57

看看这个超级实用的一种类型——匿名类型的相关文章

C#超级实用的一种类型—匿名类型

顾名思义 匿名类型就是没有名字的类型.当一个新的匿名对象定义与前面已经存在的类型定义的内部变量类型相同时,编译器就会只生成一个类定义,而不是各一个.匿名类型对象中仍然可以再包含匿名对象. 在C#3.0中允许我们在程序中声明一个临时的类型来存储数据,例如: class Program { static void Main(string[] args) { //声明一个匿名对象,拥有 Name和Age 属性 var obj = new { Name = "Joey", Age = 25 }

超级实用的几种表单校验效果收集

************************************************************* 只能是写限定的东西 程序代码: ENTER键可以让光标移到下一个输入框 <input > 只能是中文<input onkeyup='value=value.replace(/[ -~]/g,'')' > 只能是英文和数字.屏蔽了输入法<input style='ime-mode:disabled' > 只能输入英文和数字<input onke

网页:超级实用的几种表单校验效果收集

网页 只能是写限定的东西 程序代码: ENTER键可以让光标移到下一个输入框 <input >// Coded by windy_sk <windy_sk@126.com> 20040205 function reportError(msg,url,line) {var str = 'You have found an error as below: \n\n';str += 'Err: ' + msg + ' on line: ' + line;alert(str);return

C#3.0新特性――隐含类型局部变量和匿名类型

C#3.0引进新关键字var,它是一个类型,可以用来声明局部变量. Code var I = 1; //int类型 var j = "reallypride"; //string类型 var k = new[] { 1, 2, 3, 4 }; //int[]类型 var x; //错误,必须初始化 var y = null; //错误,不可以为空 使用var变量要点: 1.使用var声明局部变量,编译器会根据后面的初始化表达式自动推断变量的类型,这个类型是强类型. 2.var变量在声明

超级实用的Excel图表技巧解析

  超级实用的Excel图表技巧解析          [例]如下图所示的excel图表中,从下至上分三种蓝色作为背景,分别显示差(<50).中(<100).优(<150)3个档次. 制作方法: 1.设计源数据表,把50.100和150输入到CDE列中. 2.选取A列和E列,插入图表 - 柱状图. 3.在柱子上右键单击 - 设置数据系列格式,把系列重叠调整最大,分类间距调整为0%. 4.依次复制D.C.B列数据,粘到图表上,结果如下图所示. 5.选取利润系列并单击右键 - 设置数据系列格

C#的三种复杂变量类型

前面介绍的变量都有一个基本的取值范围,除了String类型之外,每种类型的变量在内存中只占一定数量的字节,下面介绍3种用户自定义的复杂变量. 一. 枚举型 定义枚举型:关键字enum 使用方法: enum Ename { Value1,value2,----.valueN } 声明一个Ename类型的枚举变量 Ename  myenum=Ename.value;默认情况下枚举类型的类型是int,value1,value2等的值默认从0依次递增1.同时也可以使用其他类型.请看例题: enum Da

浅谈Javascript中的12种DOM节点类型_javascript技巧

前言 DOM的作用是将网页转为一个javascript对象,从而可以使用javascript对网页进行各种操作(比如增删内容).浏览器会根据DOM模型,将HTML文档解析成一系列的节点,再由这些节点组成一个树状结构.DOM的最小组成单位叫做节点(node),文档的树形结构(DOM树)由12种类型的节点组成. 属性 一般地,节点至少拥有nodeType.nodeName和nodeValue这三个基本属性. 节点类型不同,这三个属性的值也不相同 nodeType nodeType属性返回节点类型的常

三种facebook的类型和案例

近日,在微博上看到有关F-commerce的讨论也越来越多了,实际上国外也有很多品牌都在facebook上进行了尝试.所谓F-commerce,也就是通过facebook来销售商品. 我对f-commerce的定义:企业品牌利用facebook用户基础,通过facebook的社交图谱和社交组件进行,使用户可以更方便的与其在facebook上的好友进行互动.分享和交流的社会化电子商务. F-commerce其实有下面三种基本的类型: 1.Facebook店铺,零售商直接在facebook开设店铺,

C#教程:匿名类型和隐式类型变量的区别

隐式类型变量 (Implicitly typed local variables) 象下面的代码书写就是隐式类型变量 var i = 5; var str = "Csharp" var numbers = new int[]{1,2,3}; var orders = new System.Collections.Hashtable(); var orders1 = new Dictionary(); var i = xxx ; 的作用就是用 xxx 的类型声明为i的类型.并给i 赋值.