1. 程式人生 > 程式設計 >淺析C# Dynamic關鍵字

淺析C# Dynamic關鍵字

dynamic關鍵字和動態語言執行時(DLR)是.Net 4.0中新增的功能。

什麼是"動態"?

  程式語言有時可以劃分為靜態型別化語言和動態型別化語言。C#和Java經常被認為是靜態化型別的語言,而Python、Ruby和JavaScript是動態型別語言。

  一般而言,動態語言在編譯時不會對型別進行檢查,而是在執行時識別物件的型別。這種方法有利有弊:程式碼編寫起來更快、更容易,但無法獲取編譯器錯誤,只能通過單元測試和其他方法來確保應用正常執行。

  C#最初是作為純靜態語言建立的,但是C#4添加了一些動態元素,用於改進與動態語言和框架之間的互操作性。C# 團隊考慮了多種設計選項,但最終確定新增一個新關鍵字來支援這些功能:dynamic。

  dynamic關鍵字可充當C#型別系統中的靜態型別宣告。這樣,C#就獲得了動態功能,同時仍然作為靜態型別化語言而存在。

  由於編譯時不會去檢查型別,所以導致IDE的IntellSense失效。

dynamic、Object還是Var?

  那麼,dynamic、Object和var之間的實際區別是什麼?何時使用它們?

  先說說var,經常有人會拿dynamic和var進行比較。實際上,var和dynamic完全是兩個概念,根本不應該放在一起做比較。

  var實際上編譯器拋給我們的語法糖,一旦被編譯,編譯器就會自動匹配var變數的實際型別,並用實際型別來替換該變數的宣告,等同於我們在編碼時使用了實際型別宣告。而dynamic被編譯後是一個Object型別,編譯器編譯時不會對dynamic進行型別檢查。

  再說說Object,上面提到dynamic型別再編譯後是一個Object型別,同樣是Object型別,那麼兩者的區別是什麼呢?

  除了在編譯時是否進行型別檢查之外,另外一個重要的區別就是型別轉化,這也是dynamic很有價值的地方,dynamic型別的例項和其他型別的例項間的轉換是很簡單的,開發人員能夠很方便地在dyanmic和非dynamic行為間切換。任何例項都能隱式轉換為dynamic型別例項,見下面的例子:

dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();

反之亦然,型別為dynamic的任何表示式也能夠隱式轉換為其他型別。

int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;

dynamic與反射  

以前我們這樣使用反射:

public class DynamicSample
{
 public string Name { get; set; }
 
 public int Add(int a,int b)
 {
  return a + b;
 }
}
DynamicSample dynamicSample = new DynamicSample();
 //create instance為了簡化演示,我沒有使用反射
var addMethod = typeof(DynamicSample).GetMethod("Add");
int re = (int)addMethod.Invoke(dynamicSample,new object[] { 1,2 });

現在,我們有了簡化的寫法:

dynamic dynamicSample2 = new DynamicSample();
int re2 = dynamicSample2.Add(1,2);

我們可能會對這樣的簡化不以為然,畢竟看起來程式碼並沒有減少多少,此方法也不能使用 IntelliSense,但是,如果考慮到效率兼優美兩個特性,那麼dynamic的優勢就顯現出來了。編譯器對dynamic進行了優化,比沒有經過快取的反射效率快了很多。

以上就是淺析C# Dynamic關鍵字的詳細內容,更多關於C# Dynamic關鍵字的資料請關注我們其它相關文章!