C#中匿名物件與var以及動態型別 dynamic的詳解

黄舟
發布: 2017-09-06 13:53:03
原創
2532 人瀏覽過

隨著C#的發展,該語言內容不斷豐富,開發變得更加方便快捷,C# 的鋒利盡顯無疑。 C# 語言從誕生就是強型別語言,這性質到今天不曾改變,我想以後也不會改變。既然是強類型語言,那麼編寫任一程式都要求滿足下面的基本條件:

1、變數宣告必須指明其型別

2、變數型別明確後,其類型在Runtime亦無法改變

程式碼如下:

    public  class Student
    {        
    public string Name { get; set; }        
    public int Age { get; set; }        
    public string Like { get; set; }
    }
登入後複製
static void Main(string[] args)
{    int a = 10;    string s = "abc";
    Student student = new Student();    //下面出现编译错误,变量类型在声明后无法再变更
    s = a;
    student = s;
    a = 10.1f;
}
登入後複製

然而,在實際開發中我們常面臨以下幾種常見問題:

1、在一個較大的在程序程序中,只有一處或很少幾處(不超過3處)需要用到某個或某些類型(如上Student),其他地方不再需要這些類型。單獨聲明一個Student類型,所需代碼量,可能超過使用該類型時的代碼量,投入產出比不划算。

2、在一個程式中,只需要某種類型物件的部分屬性或方法參與運算。在這種情況下將該類型對象暫時轉換為程式所需的部分屬性和方法的對象,可使程式更加精簡。

3、其他情況........我暫未留意到......歡迎補充........

上面這些C# 實際開發中常見問題,在JavaScript 開發中有著比較好的解決方案,如下:

//在此处js中需要模拟一个学生对象
student = {"name":"张三","age":20,"like":"LOL"};
//在此处js中需要模拟一个老师对象
teacher = {"name":"李老师","like":"没收学生手机,自己LOL"};
//此处需要将学生student转换成只有name和age的对象
person = {"name":student.name,"age":student.age};
登入後複製

如果你不熟悉上面的js語法,你可以去百度搜尋“json語法”,告訴你很簡單哦(而且很重要)。

匿名物件(匿名類型)

因此C#在3.0版本中吸收了JavaScript腳本語言的這種語法優點,對C#做了相應升級使其也支援這種語法形式(C#依然是強類型語言)。範例程式碼如下:

static void Main(string[] args)
{     new {Name="张三",Age=20,Like="LOL"};
}
登入後複製

上面的C#程式碼 透過new關鍵字告訴編譯器要建立一個對象,該物件具有Name,Age,Like三個屬性,=後為屬性對應的值。如此我們避開了“創建一個物件首先要有該物件類型的約束”,因此在開發過程中對於使用較少的類型我們無需再創建單獨的類了,上面提到的問題1被解決

現在建立出來的物件並沒有指定具體類型,因此稱為匿名物件

Var登場

現在要使用匿名對象,則需要使用變數來引用它。雖然我們在建立時沒有指定物件的類型,但編譯器會在編譯過程中幫我們建立一個具有相關屬性和方法的類型。此時編譯出的型別名稱是隨機產生的,因此變數類型無法確定。範例如下:

static void Main(string[] args)
{    //XXX为类型声明    //x为引用变量 
     XXX x = new {Name="张三",Age=20,Like="LOL"};
}
登入後複製

雖然我們不知道編譯器產生的型別名稱,但我們可 讓編譯器自己根據編譯的結果來推斷變數型別。 此時var關鍵字便發揮作用了:

static void Main(string[] args)
{     var x = new {Name="张三",Age=20,Like="LOL"};
}
登入後複製

var 關鍵字說明x 的類型由賦於的值來決定(推定),並能根據編譯器推定給出智能提示,如下圖:

var使用注意事項:

#1、var 只能宣告方法內的局部變數

2、var 宣告的變數在被賦值後型別即確定下了,後續程式中不能在賦其他型別的值

3、 var x = new object() 沒有意義,不要寫這樣的程式碼...............

 現在有匿名物件和var推論類型的支持,我們就能處理上述的問題2。範例程式碼如下:

        static void Main(string[] args)
        {            
        var x = new { Name = "张三", Age = 20, Like = "LOL" };            
        var s = new { Name = x.Name, Age = x.Age };  
        }
登入後複製

上面僅為範例,如果你熟悉Linq或Entity Framework,那麼問題2對應的用法將是鋪天蓋地的.......

動態型別dynamic 出場

對於匿名型別的使用一般侷限於方法的局部,可理解為:隨用隨定義,用完就消失。 有以下情況該怎麼辦?


        static void Main(string[] args)
        {            
        var x = GetObject(); 
        }        
        private static XXX GetObject()
        {            
        return new { Name = "张三", Age = 20, Like = "LOL" };
        }
登入後複製

透過GetObject方法傳回一個匿名對象,所以方法傳回值 類型名稱無法確定,這裡暫時用XXX取代。在這種情況下傳回的類型不確定,可以使用 dynamic 來指明。如下:

          Main( x =    { Name = , Age = , Like =
登入後複製

此時方法不會出現語法錯誤,程式可以成功編譯並執行。那麼 dynamic 到底做了什麼,可以讓上面的程式成功編譯呢?

dynamic的作用:

1、dynamic 表示動態類型,動態類型的意思是程式編寫、編譯階段類型不確定,在Runtime時再透過反射機制確定相關物件的屬性或方法。因此編寫階段不會進行語法檢測。

2、dynamic 可用來宣告欄位、屬性、方法參數、方法回傳值

#3、dynamic 不支援智慧提示,因為你寫程式碼時dynamic  是什麼無法知曉(反射)

dynamic 宣告的變量,可理解為 object 類型變數。所以給dynamic變數賦任何型別值都正確,但在使用變數來取得某個屬性值或呼叫某方法時(此時程式肯定處於Runtime狀態),CLR會檢查(反射)所呼叫的屬性或方法是否存在,不存在報運行時異常。

dynamic在 Asp.net Mvc web開發中處處使用,雖然看起來很複雜,本質就上面所說內容。

說明:

var 和dynamic 看似功能類似,但它們是不同的:

## var dynamic 宣告欄位 × √## 局部變數 方法參數型別
 √  √
 ×  √
########################################################################################### #### 方法傳回值類型###### ×####### √#############

以上是C#中匿名物件與var以及動態型別 dynamic的詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板