看看C# 6.0中那些语法糖都干了些什么(终结篇)

  1. 云栖社区>
  2. 博客>
  3. 正文

看看C# 6.0中那些语法糖都干了些什么(终结篇)

技术mix呢 2017-11-14 10:39:00 浏览1821
展开阅读全文

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

网友评论

登录后评论
0/500
评论
技术mix呢
+ 关注