C#基礎知識之Dynamic類型


Dynamic類型是C#4.0中引入的新類型,它允許其操作掠過編譯器類型檢查,而在運行時處理。

編程語言有時可以划分為靜態類型化語言和動態類型化語言。C#和Java經常被認為是靜態化類型的語言,而Python、Ruby和JavaScript是動態類型語言。一般而言,動態語言在編譯時不會對類型進行檢查,而是在運行時識別對象的類型。這種方法有利有弊:代碼編寫起來更快、更容易,但無法獲取編譯器錯誤,只能通過單元測試和其他方法來確保應用正常運行。C#最初是作為純靜態語言創建的,但是C#4添加了一些動態元素,用於改進與動態語言和框架之間的互操作性。C# 團隊考慮了多種設計選項,但最終確定添加一個新關鍵字來支持這些功能:Dynamic。Dynamic關鍵字可充當C#類型系統中的動態類型聲明。這樣,C#就獲得了動態功能。由於編譯時不會去檢查類型,所以導致IDE的IntellSense失效。

Dynamic類型在絕大多數情況下和object類型相似,不同之處在於編譯器對於包含了dynamic的表達式不做進一步解析和類型檢查。編譯器將這些信息收集到一起,用於在運行時鑒定操作。也就是具體類型在運行時程序才知道。實際上,dynamic類型的變量被編譯成object類型,因此,dynamic類型實際上只存在於編譯期,而運行時並不存在。

先來看一段有趣的代碼:

static void Main(string[] args)
{
    dynamic dyn = 1;
    object obj = 1;
    dyn += 1;   //編譯期間不檢查,到運行時確定為int類型
    //obj += 1;   //此段代碼編譯不通過,提示  運算度+=無法應用於"object"與"int"類型的操作數。
    Console.WriteLine(dyn.GetType());   //輸出Systen.Int32
    Console.ReadKey();
} 
View Code

 

使用dynamic類型要注意的問題:

  由於dynamic類型的變量在設計時是未知的,因此無法看到Visual Studio對dynamic類型變量的成員進行自動提示,因為編譯器也不知道。

  由於dynamic類型變量的具體類型要在運行時才能確定,因此你對該變量的成員調用必須是正確的,如果調用了變量沒有的屬性或方法,將會產生異常。

public class Program
{
    static void Main(string[] args)
    {
        Person p = new Person();
        p.Name = "張三";
        ShowInfo(p);
        Console.WriteLine(p.Name);
        Console.ReadKey();
    }
    static void ShowInfo(dynamic d)
    {
        Console.WriteLine(d.Name);
        d.Name = "神靈武士";
    }
}
public class Person
{
    public string Name { get; set; }
}
View Code

 

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;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM