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

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

概述终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的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之前是绝对不可以定义默认构造函数的,为什么这么说呢?道理很简单,因为值类型和引用类型的机制不一样,值类型不需要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;78 namespace ConsoleApplication39 {10 class Program11 {12 static void Main(string[] args)13 {14 Test t = new Test();15 var s = t.point.X; //请问有没有调用构造函数啊?啊啊啊啊啊。。。。。。。。。。。。。。。16 Console.Read();17 }18 }1920 public class Test21 {22 public Point point;23 }2425 public struct Point26 {27 public int X;2829 public int Y;3031 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 try4 {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 try4 {56 }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的语法糖分析到这里就结束了,感谢大家的关注。 

  终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的Js系列啦。

  还是按照江湖老规矩,先扒开看看到底是个什么玩意。

Main( Dictionary<,> dic = Dictionary<,> [] = [] = }

第一眼看到这个还是蛮新鲜的,不过转眼就能想到是不是跟数组初始化器,对象初始化器一个样?你要是这么想就对了,下面我们来看看这玩意会生成

什么样的IL。

从上图中可以清楚的看到set_Item方法,这个方法就是编译器上层的索引器语法糖,就是忽悠我们提高开发效率的,不过也还行,起码让我少输入了

两个dic,然后把代码还原如下:

Dictionary<,> dic[] = dic[] = ;

索性趁热打铁,看看这个索引器方法的内部代码是什么样的,从下图中可以看到是一个Insert *** 作。

  不知道有多少人知道值类型在C#6.0之前是绝对不可以定义默认构造函数的,为什么这么说呢?道理很简单,因为值类型和引用类型的机制不一样,

值类型不需要new就可以在栈中分配空间,比如下面的结构体Point,只要我们定义了,就可以方便的使用point.X值。

那问题来了,如果我定义了一个默认的构造函数,并且在里面写下x=5,y=5,那谁可以告诉我,当我定义point的时候,有没有调用构造函数呢???

Main( Test t = s = t.point.X; }

如果执行了默认构造函数,那我point.X的时候会输出5,是不是觉得有点奇怪呢?所以基于这个原因,C#6.0之前为了避嫌,就禁止了这种默认的值

类型构造形式。但是这次在C#6.0中居然放开了,所以我就很迫不及待的去看一看到底调没调用默认构造函数,如下图:

从图中看到并没有调用默认构造函数,到这里我也知道了,只有在我new的时候才会调用,所以我就发现,值类型是在模仿引用类型的使用方式了,

个人感觉真的没有必要放开这个限制。

  C#6.0中这个异常筛选器还真是个比较新奇的东西,不看不知道,一看吓一跳,比如下面的代码。

(ex.Message.Contains( }

如果你仔细看的话,好像就是一个catch中省略了{}而已嘛?并没有看到什么其他特殊的东西,然后我就非常好奇的把上面的代码恢复到6.0版本之前,

代码如下:

(ex.Message.Contains( }

接来下,我们就来看看这两份代码的IL到底会是个什么样子?内心狂鸡冻啊,啊啊啊啊啊啊啊。。。。都痉挛了。。。。。

可以看到,上面两份貌似相同的代码,其实生成的IL还是有很大区别的,新版代码中会用isinst判断是否为Exception的实例,并且用brtrue来判断当前是否

为null,如果是null,则不会执行ex.Message.Contains("timeout")语句了。但是老版代码并没有true/false判断,还是按照常规执行,所以现在可以知道,

其实并不是简单的省略了个"{}"大括号,这个语法糖在底层还是有些智能判断的。

好了,所有的C#6.0的语法糖分析到这里就结束了,感谢大家的关注。

总结

以上是内存溢出为你收集整理的看看C# 6.0中那些语法糖都干了些什么(终结篇)全部内容,希望文章能够帮你解决看看C# 6.0中那些语法糖都干了些什么(终结篇)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1264096.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存