終于寫(xiě)到終結(jié)篇了,整個(gè)人像在夢(mèng)游一樣,說(shuō)完這一篇我得繼續(xù)寫(xiě)我的js系列啦。
一:帶索引的對(duì)象初始化器
還是按照江湖老規(guī)矩,先扒開(kāi)看看到底是個(gè)什么玩意。
1 static void Main(string[] args)2 {3 Dictionary<string, string> dic = new Dictionary<string, string>()4 {5 ["Name"] = "ctr第一眼看到這個(gè)還是蠻新鮮的,不過(guò)轉(zhuǎn)眼就能想到是不是跟數(shù)組初始化器,對(duì)象初始化器一個(gè)樣?你要是這么想就對(duì)了,下面我們來(lái)看看這玩意會(huì)生成
什么樣的IL。

從上圖中可以清楚的看到set_Item方法,這個(gè)方法就是編譯器上層的索引器語(yǔ)法糖,就是忽悠我們提高開(kāi)發(fā)效率的,不過(guò)也還行,起碼讓我少輸入了
兩個(gè)dic,然后把代碼還原如下:
1 Dictionary<string, string> dic = new Dictionary<string, string>();2 dic["Name"] = "ctrip";3 dic["Age"] = "20";
索性趁熱打鐵,看看這個(gè)索引器方法的內(nèi)部代碼是什么樣的,從下圖中可以看到是一個(gè)Insert操作。

二:無(wú)參數(shù)的結(jié)構(gòu)體構(gòu)造函數(shù)
不知道有多少人知道值類(lèi)型在C#6.0之前是絕對(duì)不可以定義默認(rèn)構(gòu)造函數(shù)的,為什么這么說(shuō)呢?道理很簡(jiǎn)單,因?yàn)橹殿?lèi)型和引用類(lèi)型的機(jī)制不一樣,
值類(lèi)型不需要new就可以在棧中分配空間,比如下面的結(jié)構(gòu)體Point,只要我們定義了,就可以方便的使用point.X值。

那問(wèn)題來(lái)了,如果我定義了一個(gè)默認(rèn)的構(gòu)造函數(shù),并且在里面寫(xiě)下x=5,y=5,那誰(shuí)可以告訴我,當(dāng)我定義point的時(shí)候,有沒(méi)有調(diào)用構(gòu)造函數(shù)呢???
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 PRogram11 {12 static void Main(string[] args)13 {14 Test t = new Test();15 var s = t.point.X; //請(qǐng)問(wèn)有沒(méi)有調(diào)用構(gòu)造函數(shù)啊?啊啊啊啊啊。。。。。。。。。。。。。。。16 Console.Read();17 }18 }19 20 public class Test21 {22 public Point point;23 }24 25 public struct Point26 {27 public int X;28 29 public int Y;30 31 public Point()32 {33 X = 5;34 Y = 5;35 }36 }37 }
如果執(zhí)行了默認(rèn)構(gòu)造函數(shù),那我point.X的時(shí)候會(huì)輸出5,是不是覺(jué)得有點(diǎn)奇怪呢?所以基于這個(gè)原因,C#6.0之前為了避嫌,就禁止了這種默認(rèn)的值
類(lèi)型構(gòu)造形式。但是這次在C#6.0中居然放開(kāi)了,所以我就很迫不及待的去看一看到底調(diào)沒(méi)調(diào)用默認(rèn)構(gòu)造函數(shù),如下圖:

從圖中看到并沒(méi)有調(diào)用默認(rèn)構(gòu)造函數(shù),到這里我也知道了,只有在我new的時(shí)候才會(huì)調(diào)用,所以我就發(fā)現(xiàn),值類(lèi)型是在模仿引用類(lèi)型的使用方式了,
個(gè)人感覺(jué)真的沒(méi)有必要放開(kāi)這個(gè)限制。

三:異常篩選器
C#6.0中這個(gè)異常篩選器還真是個(gè)比較新奇的東西,不看不知道,一看嚇一跳,比如下面的代碼。
1 public void Run() 2 { 3 try 4 { 5 } 6 catch (Exception ex) 7 if (ex.Message.Contains("timeout")) 8 { 9 throw;10 }11 }如果你仔細(xì)看的話(huà),好像就是一個(gè)catch中省略了{(lán)}而已嘛?并沒(méi)有看到什么其他特殊的東西,然后我就非常好奇的把上面的代碼恢復(fù)到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 }接來(lái)下,我們就來(lái)看看這兩份代碼的IL到底會(huì)是個(gè)什么樣子??jī)?nèi)心狂雞凍啊,啊啊啊啊啊啊啊。。。。都痙攣了。。。。。

可以看到,上面兩份貌似相同的代碼,其實(shí)生成的IL還是有很大區(qū)別的,新版代碼中會(huì)用isinst判斷是否為Exception的實(shí)例,并且用brtrue來(lái)判斷當(dāng)前是否
為null,如果是null,則不會(huì)執(zhí)行ex.Message.Contains("timeout")語(yǔ)句了。但是老版代碼并沒(méi)有true/false判斷,還是按照常規(guī)執(zhí)行,所以現(xiàn)在可以知道,
其實(shí)并不是簡(jiǎn)單的省略了個(gè)"{}"大括號(hào),這個(gè)語(yǔ)法糖在底層還是有些智能判斷的。
好了,所有的C#6.0的語(yǔ)法糖分析到這里就結(jié)束了,感謝大家的關(guān)注。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注