「 C# 4 引入了一個新類型 dynamic。該類型是一種靜態類型,但類型爲 dynamic 的對象會跳過靜態類型檢查。"
——Microsoft Docs[1]
dynamic
是C# 4中加入的一個新的「上下文關鍵字」,它指示動態類型。咱們能夠直接建立一個dynamic類型的變量,能夠將任意對象賦值給它。以下所示:ide
dynamic dynVar1 = 1; dynamic dynVar2 = new Object();
當咱們在代碼中使用了dynamic
類型時,就是在告訴編譯器關閉對該對象的運行時檢查,而在運行時肯定對象類型。好比,如下代碼能夠成功編譯:工具
dynamic numericDyn = 80; numericDyn.Greet();
可是在這段代碼會拋出一個運行時異常RuntimeBinderException
,提示咱們類型int
不包含方法Greet()
的定義。這說明了在底層,dynamic
變量類型在運行時仍然是肯定的,也就是說,C#依然是靜態類型化語言。當咱們在一個dynamic
變量上調用GetType()
時,會輸出該對象的實際類型。以下所示:優化
Console.WriteLine(numericDyn.GetType()); // Console prints System.Int32
要注意的是,在使用dynamic
類型的變量時,編譯器沒法對該變量所指向的對象做任何類型推斷,也沒法枚舉方法與屬性。所以,IntelliSense和重構工具在此時失效。動畫
下面這個例子能夠清晰地說明這一點。咱們首先建立一個類,再用一個dynamic
類型變量裝載一個Cat
對象的引用,再試圖重構Cat
中的一個方法。
完整代碼:ui
using System; namespace DynamicKeywordTest { class Program { static void Main(string[] args) { dynamic dynCat = new Cat(); dynCat.Meow(); } class Cat { public void Meow() { Console.WriteLine(String.Format("Cat {0} meows.", this.GetHashCode())); } } } }
使用Visual Studio
的重構工具,將方法Meow()
重命名爲Honk()
,咱們發現dynCat.Meow()並無更改。
this
var
, object
和dynamic
關鍵字var
用於編譯時類型推斷。編譯器在編譯時自動肯定var
表明的類型。以下列代碼:spa
var varInt = 1; var varStr = "Hello, Vars!";
關閉優化編譯,使用.NET Reflector
反編譯獲得code
int num = 1; string str = "Hello, Vars!";
該關鍵字能夠在編譯時獲得類型信息,因而能夠進行IntelliSense和重構。orm
類型object
是全部對象的基類,有着與dynamic
類似的用法,可是必須進行強制轉換才能夠用子類的方法、屬性等。如:對象
object objCat = new Cat(); objCat.Meow(); // CS1061 'object' does not contain a definition of 'Meow' ((Cat)objCat).Meow(); // OK dynamic dynCat = new Cat(); dynCat.Meow(); // OK, but no IntelliSense
這些關鍵字能夠混用,如:
dynamic dynObj = new Object(); var anotherObj = dynObj;
最終,dynObj
類型爲dynamic
,anotherObj
類型爲dynamic
。
本文只是對於dynamic
關鍵字的第一次探索,更多信息能夠在Microsoft Docs和其餘博文,如這篇中找到。因爲這是筆者的第一篇文章,不足之處請各位讀者多多指正,敬請期待下一篇文章。