最终写到终结篇了,整个人像在梦游一样。说完这一篇我得继续写我的js系列啦。
一:带索引的对象初始化器
还是依照江湖老规矩,先扒开看看究竟是个什么玩意。
1 static void Main(string[] args)
2 {
3 Dictionary<string, string> dic = new Dictionary<string, string>()
4 {
5 ["Name"] = "ctrip",
6 ["Age"] = "15"
7 };
8 }
第一眼看到这个还是蛮新奇的,只是转眼就能想到是不是跟数组初始化器。对象初始化器一个样?你要是这么想就对了,以下我们来看看这玩意会生成
什么样的IL。

从上图中能够清楚的看到set_Item方法,这种方法就是编译器上层的索引器语法糖,就是忽悠我们提高开发效率的。只是也还行,起码让我少输入了
两个dic,然后把代码还原例如以下:
1 Dictionary<string, string> dic = new Dictionary<string, string>();
2 dic["Name"] = "ctrip";
3 dic["Age"] = "20";
索性趁热打铁,看看这个索引器方法的内部代码是什么样的,从下图中能够看到是一个Insert操作。

二:无參数的结构体构造函数
不知道有多少人知道值类型在C#6.0之前是绝对不能够定义默认构造函数的,为什么这么说呢?道理非常easy。由于值类型和引用类型的机制不一样。
值类型不须要new就能够在栈中分配空间,比方以下的结构体Point,仅仅要我们定义了,就能够方便的使用point.X值。

那问题来了,假设我定义了一个默认的构造函数,而且在里面写下x=5。y=5。那谁能够告诉我,当我定义point的时候。有没有调用构造函数呢???
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using System.Console;
7
8 namespace ConsoleApplication3
9 {
10 class Program
11 {
12 static void Main(string[] args)
13 {
14 Test t = new Test();
15 var s = t.point.X; //请问有没有调用构造函数啊?啊啊啊啊啊。
。。。。。
。。
。。
。
。。。。
16 Console.Read();
17 }
18 }
19
20 public class Test
21 {
22 public Point point;
23 }
24
25 public struct Point
26 {
27 public int X;
28
29 public int Y;
30
31 public Point()
32 {
33 X = 5;
34 Y = 5;
35 }
36 }
37 }
假设运行了默认构造函数,那我point.X的时候会输出5,是不是认为有点奇怪呢?所以基于这个原因,C#6.0之前为了避嫌,就禁止了这样的默认的值
类型构造形式。
可是这次在C#6.0中竟然放开了,所以我就非常迫不及待的去看一看究竟调没调用默认构造函数,例如以下图:

从图中看到并没有调用默认构造函数,到这里我也知道了。仅仅有在我new的时候才会调用,所以我就发现。值类型是在模仿引用类型的使用方式了,
个人感觉真的没有必要放开这个限制。

三:异常筛选器
C#6.0中这个异常筛选器还真是个比較新鲜的东西。不看不知道,一看吓一跳,比方以下的代码。
1 public void Run()
2 {
3 try
4 {
5 }
6 catch (Exception ex)
7 if (ex.Message.Contains("timeout"))
8 {
9 throw;
10 }
11 }
假设你细致看的话,好像就是一个catch中省略了{}而已嘛?并没有看到什么其它特殊的东西,然后我就很好奇的把上面的代码恢复到6.0版本号之前,
代码例如以下:
1 public void Run1()
2 {
3 try
4 {
5
6 }
7 catch (Exception ex)
8 {
9 if (ex.Message.Contains("timeout"))
10 {
11 throw;
12 }
13 }
14 }
接来下。我们就来看看这两份代码的IL究竟会是个什么样子?内心狂鸡冻啊。啊啊啊啊啊啊啊。
。。。都痉挛了。。。
。。

能够看到。上面两份貌似同样的代码,事实上生成的IL还是有非常大差别的,新版代码中会用isinst推断是否为Exception的实例,而且用brtrue来推断当前是否
为null,假设是null,则不会运行ex.Message.Contains("timeout")语句了。
可是老版代码并没有true/false推断,还是依照常规运行。所以如今能够知道,
事实上并非简单的省略了个"{}"大括号。这个语法糖在底层还是有些智能推断的。
好了,全部的C#6.0的语法糖分析到这里就结束了。感谢大家的关注。
本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5398838.html,如需转载请自行联系原作者
网友评论