標籤:
今天沒事,就下了個vs2015 preview,前段時間園子裡面也在熱炒這些新的文法糖,這裡我們就來看看到底都會產生些什麼樣的IL?
一:自動初始化屬性
確實這個比之前的版本簡化了一下,不過你肯定很好奇,到底編譯器給我們做了哪些東西呢?
1 class Student2 {3 public string Name { get; set; } = "ctrip";4 }
從這張圖中可以看到,在ctor中<Name>k__backingfield=“ctrip“的賦值在base::ctor之前,這就說明name是變數初始化賦值,而不屬於
建構函式賦值,那有什麼區別呢,如果base::ctor在<Name>k__backingfield=”ctrip"之前,那就是建構函式賦值了,不過我得特別要指明
一下,是原始碼層級的區別,而不是IL中的區別,因為在IL中都是建構函式賦值,不過語句順序不一樣而已,然後我把內部做的代碼複原如下:
1 class Student 2 { 3 private string k__BackingField = "ctrip"; 4 5 public string Name 6 { 7 get 8 { 9 return k__BackingField;10 }11 12 set13 {14 k__BackingField = value;15 }16 }17 }
然後再看看怎麼讓base::ctor在<Name>k__backingfield="ctrip"之前。
1 class Student 2 { 3 private string k__BackingField; 4 5 public string Name 6 { 7 get 8 { 9 return k__BackingField;10 }11 12 set13 {14 k__BackingField = value;15 }16 }17 18 public Student()19 {20 k__BackingField = "ctrip";21 }22 }
不好意思,一不小心就扯到了變數初始化和建構函式賦值在原始碼層級的區別。
二:唯讀屬性初始化
這個也是一個超級好玩的屬性,先來看看代碼:
1 class Student2 {3 public string Name { get; }4 5 public Student(string name)6 {7 Name = name;8 }9 }
但是我們記得,在之前的C#版本是不能這麼寫,但現在惹不住好奇心,先去底層看看到底產生了什麼。
然後我就奇怪了,屬性本來就可以是唯讀,現在編譯器已經放開了,那是不是有問題了,我如果真的是需要一個唯讀屬性,這個該如何是好
呢?然後我就試著在Name屬性中返回一個值,果然編譯器不允許存取,這就說明編譯器在裡面還做了一個貌似合理的判斷。
三:Lambda充當函數體
這個聽起來就有點怪怪的,還是先看個例子。
1 class Student2 {3 public string Name => "ctrip";4 5 public void Print(string name) => Console.WriteLine(name);6 }
不過當我看到這種寫法時,我也是醉了,假如你一年都沒有接觸C#,再回來看時,我想你肯定看不懂這些雞巴代碼了。。。沒辦法,還得繼續
看看IL在底層都做了些什嗎?
當看到IL的時候再次醉了,其實=>僅僅是一個{}方法體括弧而已呀!這不是徒增我們的學習成本嗎?然後我就繼續想,這裡的函數體就一條
console.wirteline語句,那我要是灌幾條語句會怎麼樣呢?可以想象肯定是要加括弧的,但是我真的加上{}後,編譯器淩亂了。。。
那這個圖就告訴我們,C#6.0的lamaba充當函數體的文法糖只適合一條語句,如果真要做到多條語句,那你只能單獨提取一個方法出來,
就像下面這樣。
好了,上篇大體就這樣了,時間不早了,先撤了。
看看C# 6.0中那些文法糖都幹了些什麼(上篇)