最终写到终结篇了,整个人像在梦游一样。说完这一篇我得继续写我的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,如需转载请自行联系原作者