這段時(shí)間忙的像狗一樣,寫博客的事情也就耽擱了,繼續(xù)扯,為什么說decimal神奇呢,大家都知道decimal是基元類型,但是
這個(gè)decimal類型在IL中居然沒有相應(yīng)的IL指令,也就是說CLR根本不認(rèn)識decimal,全是編譯器這一層在糊弄我們。
話不多說,看下最simple的例子,(加了點(diǎn)注釋方便理解)
1 static void Main(string[] args) 2 { 3 //居然調(diào)用了有參構(gòu)造函數(shù) 4 decimal d = 1; 5 6 //直接將常量10推送到計(jì)算堆棧,然后將10放入局部變量索引為1的位置,也就是i 7 int i = 10; 8 9 //居然調(diào)用了隱式轉(zhuǎn)換操作符,IL中就是調(diào)用相應(yīng)的方法10 d = i;11 12 //居然調(diào)用了顯式轉(zhuǎn)換操作符,IL中就是調(diào)用相應(yīng)的方法13 i = (int)d;14 }

從IL中可以看到,對decimal的所有操作最后玩的都是方法,對編譯器上層的我們而言卻一無所知,那么下一個(gè)問題來了,這些
都是怎么做到的呢?
一:decimal源代碼
當(dāng)我們對decimal的實(shí)現(xiàn)充滿好奇心的時(shí)候,最滿足的方式的就是看源代碼了,大家應(yīng)該都有對新鮮事物的好奇心,不管看不看
得懂都得裝X看。
1:implicit/explicit 操作符
從下面的IL中我們看到了這些亂七八槽的操作符,可能我們用的比較少或者有些人都沒看過,不過終有它的用武之地。
結(jié)合上面的IL代碼,我們發(fā)現(xiàn)了implicit和explicit關(guān)鍵字,這兩個(gè)就是所謂的轉(zhuǎn)換操作符,顧名思義,implicit就是所謂的隱式轉(zhuǎn)換
操作符,explicit是顯式轉(zhuǎn)換了,再結(jié)合上面的IL代碼,我們會發(fā)現(xiàn)給我們最終生成的是op_Implicit 和 op_Explicit方法。
可能有些人看不明白了,那我就舉個(gè)例子吧。
1 public class PRogram 2 { 3 static void Main(string[] args) 4 { 5 //這里就是語法糖,c=10 最終調(diào)用的就是:隱式轉(zhuǎn)換調(diào)用 6 Complex c = 10; 7 8 //語法糖,(int)最終調(diào)用的是:顯式轉(zhuǎn)換調(diào)用 9 int j = (int)c;10 }11 }12 13 public struct Complex14 {15 public Complex(int num) { }16 17 /// <summary>18 /// 隱式轉(zhuǎn)換調(diào)用的方法19 /// </summary>20 /// <param name="value"></param>21 /// <returns></returns>22 public static implicit Operator Complex(int value)23 {24 return new Complex(value);25 }26 27 /// <summary>28 /// 強(qiáng)制轉(zhuǎn)換調(diào)用的方法29 /// </summary>30 /// <param name="value"></param>31 /// <returns></returns>32 public static explicit operator int(Complex value)33 {34 return Convert.ToInt32(value);35 }36 }

從我的sample和IL中看,我想你應(yīng)該清楚了,為了方便我們編碼效率以及更好的讓人理解,C#提供了這么個(gè)好玩的語法糖,清晰明了。
2:op_*** 重載操作符
既然是基元類型就避免不了大量的算術(shù)運(yùn)算和比較元算,那這些decimal又是如何做到的?還是繼續(xù)在源代碼里面找找。

從源代碼里面可以看到,原來C#用operator重載運(yùn)算符對我們這個(gè)++,--,!=,<= 進(jìn)行了重載,和轉(zhuǎn)換運(yùn)算符一樣,最終
在IL層也是轉(zhuǎn)換為各種方法。
還是看個(gè)例子:
1 static void Main(string[] args) 2 { 3 decimal i = 10; 4 5 decimal j = 12; 6 7 var r1 = i > j; 8 9 var r2 = i == j;10 }

好了,我想你一切都清楚了,當(dāng)我們在愉快的寫著++,--的時(shí)候,殊不知編譯器給我們做的太多太多,最后得要感謝一下編譯器。
新聞熱點(diǎn)
疑難解答
圖片精選