詳解C# 匿名對(duì)象(匿名類(lèi)型)、var、動(dòng)態(tài)類(lèi)型 dynamic
隨著C#的發(fā)展,該語(yǔ)言?xún)?nèi)容不斷豐富,開(kāi)發(fā)變得更加方便快捷,C# 的鋒利盡顯無(wú)疑。C# 語(yǔ)言從誕生起就是強(qiáng)類(lèi)型語(yǔ)言,這一性質(zhì)到今天不曾改變,我想以后也不會(huì)變。既然是強(qiáng)類(lèi)型語(yǔ)言,那編寫(xiě)任一程序均要求滿(mǎn)足下面的基本條件:
1、變量聲明必須指明其類(lèi)型
2、變量類(lèi)型明確后,其類(lèi)型在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(); //下面出現(xiàn)編譯錯(cuò)誤,變量類(lèi)型在聲明后無(wú)法再變更 s = a; student = s; a = 10.1f; }
然而,在實(shí)際開(kāi)發(fā)中我們經(jīng)常面臨如下幾種常見(jiàn)問(wèn)題:
1、在一個(gè)較大的程序程序中,只有一處或很少幾處(不超過(guò)3處)需要用到 某個(gè)或某些類(lèi)型(如上 Student),其他地方不再需要這些類(lèi)型。單獨(dú)聲明一個(gè)Student類(lèi)型,所需代碼量,可能超過(guò)使用該類(lèi)型時(shí)的代碼量,投入產(chǎn)出比不劃算。
2、在一處程序中,只需要某種類(lèi)型對(duì)象的部分屬性或方法參與運(yùn)算。在這種情況下將該類(lèi)型對(duì)象臨時(shí)轉(zhuǎn)換為程序所需的部分屬性和方法的對(duì)象,可使程序更加精簡(jiǎn)。
3、其他情況........我暫未留意到......歡迎補(bǔ)充........
上面這些 C# 實(shí)際開(kāi)發(fā)中常見(jiàn)問(wèn)題,在 JavaScript 開(kāi)發(fā)中有著比較好的解決方案,如下:
//在此處js中需要模擬一個(gè)學(xué)生對(duì)象 student = {"name":"張三","age":20,"like":"LOL"}; //在此處js中需要模擬一個(gè)老師對(duì)象 teacher = {"name":"李老師","like":"沒(méi)收學(xué)生手機(jī),自己LOL"}; //此處需要將學(xué)生student轉(zhuǎn)換成只有name和age的對(duì)象 person = {"name":student.name,"age":student.age};
如果你不熟悉上面的js語(yǔ)法,你可以去百度搜索 “json語(yǔ)法”,告訴你很簡(jiǎn)單哦(而且很重要)。
匿名對(duì)象(匿名類(lèi)型)
因此C#在3.0版本中吸收了JavaScript腳本語(yǔ)言的這種語(yǔ)法優(yōu)點(diǎn),對(duì)C#做了相應(yīng)升級(jí)使其也支持這種語(yǔ)法形式(C#依然是強(qiáng)類(lèi)型語(yǔ)言)。示例代碼如下:
static void Main(string[] args) { new {Name="張三",Age=20,Like="LOL"}; }
上面的C#代碼 通過(guò)new關(guān)鍵字告訴編譯器要?jiǎng)?chuàng)建一個(gè)對(duì)象,該對(duì)象具有Name,Age,Like三個(gè)屬性,=后為屬性對(duì)應(yīng)的值。如此我們避開(kāi)了“創(chuàng)建一個(gè)對(duì)象首先要有該對(duì)象類(lèi)型的約束”,因此在開(kāi)發(fā)過(guò)程中對(duì)于使用較少的類(lèi)型我們無(wú)需再創(chuàng)建單獨(dú)的類(lèi)了,上面提到的問(wèn)題1被解決。
現(xiàn)在創(chuàng)建出來(lái)的對(duì)象沒(méi)指定具體類(lèi)型,因此稱(chēng)為匿名對(duì)象。
Var登場(chǎng)
現(xiàn)在要使用匿名對(duì)象,則需要使用變量引用它。雖然我們?cè)趧?chuàng)建時(shí)沒(méi)有指定對(duì)象的類(lèi)型,但編譯器會(huì)在編譯過(guò)程中幫我們創(chuàng)建一個(gè)具有相關(guān)屬性和方法的類(lèi)型。此時(shí)編譯出的類(lèi)型名稱(chēng)是隨機(jī)生成的,因此變量類(lèi)型無(wú)法確定。示例如下:
static void Main(string[] args) { //XXX為類(lèi)型聲明 //x為引用變量 XXX x = new {Name="張三",Age=20,Like="LOL"}; }
雖然我們不知道編譯器生成的類(lèi)型名稱(chēng),但我們可 讓編譯器自己根據(jù)編譯的結(jié)果來(lái)推斷變量類(lèi)型。此時(shí)var關(guān)鍵字便發(fā)揮作用了:
static void Main(string[] args) { var x = new {Name="張三",Age=20,Like="LOL"}; }
var 關(guān)鍵字說(shuō)明 x 的類(lèi)型由賦于的值來(lái)決定(推定),并能根據(jù)編譯器推定給出智能提示,如下圖:
var使用注意事項(xiàng):
1、var 僅能聲明方法內(nèi)的局部變量
2、var 聲明的變量在被賦值后類(lèi)型即確定下了,后續(xù)程序中不能在賦其他類(lèi)型的值
3、var x = new object() 沒(méi)有意義,不要寫(xiě)這樣的代碼...............
現(xiàn)在有匿名對(duì)象和var推斷類(lèi)型的支持,我們就能處理上面提到的問(wèn)題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,那問(wèn)題2對(duì)應(yīng)的用法將是鋪天蓋地的.......
動(dòng)態(tài)類(lèi)型 dynamic 出場(chǎng)
對(duì)于匿名類(lèi)型的使用一般局限于方法的局部,可理解為:隨用隨定義,用完就消失。有如下情況應(yīng)該怎么辦?
static void Main(string[] args) { var x = GetObject(); } private static XXX GetObject() { return new { Name = "張三", Age = 20, Like = "LOL" }; }
通過(guò)GetObject方法返回一個(gè)匿名對(duì)象,所以方法返回值 類(lèi)型名稱(chēng)無(wú)法確定,此處暫時(shí)用XXX代替。在這種情況下返回的類(lèi)型不確定,可以使用 dynamic 來(lái)指明。如下:
static void Main(string[] args) { var x = GetObject(); Console.WriteLine(x.Name); } private static dynamic GetObject() { return new { Name = "張三", Age = 20, Like = "LOL" }; }
此時(shí)方法不會(huì)出現(xiàn)語(yǔ)法錯(cuò)誤,程序可以成功編譯并執(zhí)行。那么 dynamic 到底做了什么,可以使上面的程序成功編譯呢?
dynamic的作用:
1、dynamic 表示動(dòng)態(tài)類(lèi)型,動(dòng)態(tài)類(lèi)型的含義就是 程序編寫(xiě)、編譯階段 類(lèi)型不確定,在Runtime時(shí)再通過(guò)反射機(jī)制確定相關(guān)對(duì)象的屬性或方法。因此編寫(xiě)階段不會(huì)進(jìn)行語(yǔ)法檢測(cè)。
2、dynamic 可用來(lái)聲明 字段、屬性、方法參數(shù)、方法返回值
3、dynamic 不支持智能提示,因?yàn)槟銓?xiě)代碼時(shí) dynamic 是什么沒(méi)法知曉(反射)
dynamic 聲明的變量,可理解為 object 類(lèi)型變量。所以給dynamic變量賦任何類(lèi)型值都正確,但在使用變量來(lái)取得某個(gè)屬性值或調(diào)用某方法時(shí)(此時(shí)程序肯定處于Runtime狀態(tài)),CLR會(huì)檢查(反射)所調(diào)用的屬性或方法是否存在,不存在報(bào)運(yùn)行時(shí)異常。
dynamic在 Asp.net Mvc web開(kāi)發(fā)中處處使用,雖然看上去很復(fù)雜,本質(zhì)就上面所說(shuō)內(nèi)容。
說(shuō)明:
var 和 dynamic 看似功能類(lèi)似,但它們是不同的:
var |
dynamic | |
聲明字段 | × | √ |
局部變量 | √ | √ |
方法參數(shù)類(lèi)型 | × | √ |
方法返回值類(lèi)型 | × | √ |
總結(jié)
以上所述是小編給大家介紹的C# 匿名對(duì)象(匿名類(lèi)型)、var、動(dòng)態(tài)類(lèi)型 dynamic,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)我們網(wǎng)站的支持!
上一篇:C#設(shè)計(jì)模式之Visitor訪問(wèn)者模式解決長(zhǎng)隆歡樂(lè)世界問(wèn)題實(shí)例
欄 目:C#教程
下一篇:C#實(shí)現(xiàn)發(fā)送郵件的方法
本文標(biāo)題:詳解C# 匿名對(duì)象(匿名類(lèi)型)、var、動(dòng)態(tài)類(lèi)型 dynamic
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/5496.html
您可能感興趣的文章
- 01-10C#中Socket通信用法實(shí)例詳解
- 01-10C#實(shí)現(xiàn)獲取不同對(duì)象中名稱(chēng)相同屬性的方法
- 01-10C#裝箱和拆箱原理詳解
- 01-10C#編程自學(xué)之類(lèi)和對(duì)象
- 01-10C#類(lèi)的多態(tài)性詳解
- 01-10C#創(chuàng)建不規(guī)則窗體的4種方式詳解
- 01-10C#中深度復(fù)制和淺度復(fù)制詳解
- 01-10C#編程實(shí)現(xiàn)對(duì)象與JSON串互相轉(zhuǎn)換實(shí)例分析
- 01-10C#警惕匿名方法造成的變量共享實(shí)例分析
- 01-10C#數(shù)據(jù)結(jié)構(gòu)之隊(duì)列(Quene)實(shí)例詳解


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開(kāi)的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻 器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過(guò)重寫(xiě)Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文