文章出處

 

  接著上篇繼續扯,其實語法糖也不是什么壞事,第一個就是吃不吃隨你,第二個就是最好要知道這些糖在底層都做了些什么,不過有一點

叫眼見為實,這樣才能安心的使用,一口氣上五樓,不費勁。

 

一:字符串嵌入值

  我想String.Format方法就是化成灰大家都認識,比如下面代碼:

1     class Bird
2     {
3         private string Name = "swallow";
4 
5         public void Fly()
6         {
7             var result = string.Format("hello {0}", Name);
8         }
9     }

  這個Format有一個不好的地方就是,如果占位符太多,就特別容易搞錯,如果你少了一個參數,代碼就會報錯。

 

接下來跟趟順風車,去看看string.Format底層代碼,還是蠻驚訝的發現,其實底層不過調用的就是StirngBuilder.AppendFormat方法。

 

因為容易報錯,所以為了保險起見就用字符串拼接的方式來實現,但是我也知道字符串拼接是耗時的一種操作,寫個StringBuilder又嫌麻煩,

還好C#6.0中提供了一種新鮮玩法,先看代碼:

 1     class Bird
 2     {
 3         private string Name = "swallow";
 4 
 5         public void Fly()
 6         {
 7             //var result = string.Format("hello {0}{1}", Name);
 8 
 9             var result = "\{"hello"}:\{Name}";
10 
11             Console.WriteLine(result);
12         }
13     }

 

然后就迫不及待的去看看底層怎么玩的,其實在下面的IL圖中可以看到,在底層最終還是調用了String.Format方法來實現的。

 

 

二:using靜態類

  這種寫法看起來有點不倫不類的,乍一看也沒有什么用處,不過可以告訴我們一個原理,就是不管你上層怎么變,編譯器還是一樣使用

全命名,這就叫萬變不離其宗吧。

 

三:空值判斷

  先還是來看看這種玩法的真容。

1     class Bird
2     {
3         public void Fly(string name)
4         {
5             var result = name?.Length;
6         }
7     }

是不是看著有點眼暈?那就對了,編譯器就是這樣靜靜的端著碗看著我們寫這些裝逼的代碼,不過再怎么裝逼,也逃不過ILdasm的眼睛。


 

其實仔細看IL代碼之后,覺得一切還是那么的熟悉,重點就是這個brtrue.s。它的狀態也決定了兩條執行流,不過在IL上面也看到了V_1這個編譯

器給我們單獨定義的一個變量,代碼還原如下:

 1     class Bird
 2     {
 3         public void Fly(string name)
 4         {
 5             int? r;
 6 
 7             if (name == null)
 8             {
 9                 int? V_1 = new Nullable<int>();
10 
11                 r = V_1;
12             }
13             else
14             {
15                 r = new Nullable<int>(name.Length);
16             }
17         }
18     }

 

四:nameof表達式

  當我知道這個關鍵字的用途時,我的第一反應就是公司框架里面的LogManager類,當我們new LogManager的時候,會同時把當前的類名

傳遞下去,然后做些后期處理,但是在以前我們只能這么做,要么用反射,要么寫死。

 1 namespace ConsoleApplication3
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             //第一種:使用反射
 8             var ilog = new LoggerManager(typeof(Program));
 9 
10             //第二種:寫死
11             ilog = new LoggerManager("Program");
12 
13             Console.WriteLine("world");
14         }
15     }
16 
17     class LoggerManager
18     {
19         /// <summary>
20         /// 構造函數記錄下類名
21         /// </summary>
22         /// <param name="type"></param>
23         public LoggerManager(Type type)
24         {
25             //todo
26             Console.WriteLine(type.Name);
27         }
28         public LoggerManager(string className)
29         {
30             //todo
31             Console.WriteLine(className);
32         }
33     }
34 }

 

我想大家也能看到,第一種使用了反射,這是需要讀取元數據的,性能你懂的,第二個雖然是字符串,你也看到了,是寫死的方式,這個時候就

急需一個加強版,就像下面這樣。

看到IL后,反正我是雞動了。。。nameof具有上面兩者的優點,既靈活,性能又高。。。。不錯不錯,贊一下。

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()