iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 24
1
Software Development

我要轉職成 C# / .NET 工程師系列 第 24

C#的var、dynamic、const、readonly

  • 分享至 

  • xImage
  •  

C#程式碼透過編譯器進行編譯時期檢查後轉換成中繼語言IL,IL會包裝成.exe.dll可行檔,透過CLR即時地編譯成機器碼執行。
C#是安全型別的靜態程式語言,所以C#的var,不同於JavaScript的var,不會發生以下事件,意義也與JavaScript不同。
https://ithelp.ithome.com.tw/upload/images/20191010/20120420IhKF58Qslv.png
那是以前的文章,看到C#4.0出了dynamic動態型別,可以達到上述JavaScript的var功能,我也不知道要說什麼。

var

C# 3.0開始提供了var隱含型別,可以讓我們不用明確宣告變數型別,可以簡化宣告型別的撰寫,少打一些字,在C#編譯器編譯時會自動把var替換成等號後面的型別並轉換成IL。
https://ithelp.ithome.com.tw/upload/images/20191010/20120420JQ5gHseh1g.png
https://ithelp.ithome.com.tw/upload/images/20191010/20120420gIER6TqCFF.png

從IL轉換成C#看到得型別:
https://ithelp.ithome.com.tw/upload/images/20191010/20120420IqxpoiIhHs.png

var型別的限制:

  • var只能宣告成區域變數
  • var宣告時必須決定初始值
  • var的初始值不能等於null

在Effective C#做法01:偏好隱含型別的區域變數

在書上作者是偏好使用var,但也沒要求一定要,優點是少打一些字,考量的地方是有些開發者如果宣告了不適合的型別的化,雖然程式能正常執行,但是發生適合的型別被自動轉型(隱含轉型:例如CLR轉型或運算子轉型)成不適合的型別,可能有轉換上的成本,於執行上的效能成本,透過var交給編譯器決定。

dynamic

C# 4.0連同.NET Framework推出,開始提供dynamic動態型別,編譯時成IL時會轉換成object靜態型別,在CLR執行時期會轉換成對應的型別。
https://ithelp.ithome.com.tw/upload/images/20191010/20120420Ar4j6mAjab.png
編譯成IL會轉換成object:
https://ithelp.ithome.com.tw/upload/images/20191010/20120420xTyvmugcCf.png
轉換回C#,中繼資料告訴我們這是dynamic
https://ithelp.ithome.com.tw/upload/images/20191010/20120420JXclruv0kf.png
如果選擇成C#4以下就會變轉成object
https://ithelp.ithome.com.tw/upload/images/20191010/20120420bc0uUJvXTW.png

dynamic我幾乎沒有用過,個人習慣用強型別來獲得C#編譯器的型別檢查。
dynamic操作過程也會發生自動轉型(隱含轉型:例如CLR轉型或運算子轉型),還是會想避免執行時期有意外發生。

const、readonly

C#中提供兩種常數const與readonly,前者是編譯後就無法改變的常數變數,後者是CLR執行後就無法改變的變數。
例如:
https://ithelp.ithome.com.tw/upload/images/20191010/20120420xHsCqa4x6K.png
編譯後的IL如以下,可以看到const值123已經寫入field,但是readonly還要在物件執行初始化後才會寫入456
https://ithelp.ithome.com.tw/upload/images/20191010/20120420dAmdk3z0M8.png

在Effective C#做法02:偏好readonly而非const

在效能上readonly的常數要執行時才能確定,會比編譯時就確定const還差那麼一點點,就是多幾個IL指令步驟,不過可以透過物件初始化時,透過建構式設定readonly常數,另外如果常數值是來自.net類別或是第三方組件,可以靠替換類別組件的方式來更改常數值,而不用重新編譯主程式。


上一篇
Indexer索引函式(索引子)-把物件當成陣列使用
下一篇
集合之 ArrayList的醜、泛型List<T>的好
系列文
我要轉職成 C# / .NET 工程師34
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言