C#3.5新特性的介紹
話說.net 4.0都出來了,連.net 3.5都還沒熟悉,是不是有點(diǎn)落伍阿? 恩 我也這么覺得。為了跟上人類進(jìn)步的步伐。 今天花了些時(shí)間了解了下c#3.5新特性。我認(rèn)為大致有下面幾點(diǎn)新東西:
1、var 關(guān)鍵字
2、自動(dòng)屬性(Automatic property)
3、匿名類
4、擴(kuò)展方法
當(dāng)然,話說回來,所有這些c#3.5新特性都是編譯器給我們玩的小把戲,也就是人們常說的“語法糖”。在IL級別沒有任何變化。
在js中定義變量使用var關(guān)鍵字,可以使用var來定義一個(gè)變量,保存任何一種類型的值,但是在C#中只能在聲明的時(shí)候賦值如:var v = "123";并且只能用作局部變量。不能聲明一個(gè)var類型的field,或通過方法傳遞一個(gè)var類型的參數(shù)等。
自動(dòng)屬性還是有點(diǎn)意思,可以減輕一些工作量:
- public string Name
- {
- get;
- set;
- }
是不是有點(diǎn)眼熟呢?呵呵, 不要和抽象屬性搞混了,
- public abstract string Name
- {
- get;
- set;
- }
C#編譯器認(rèn)得到。利用自動(dòng)屬性,就可以免得定義使用私有成員了,事實(shí)上就像我上面說的那樣:都是“語法糖” ,在編譯成IL的過程中,編譯器已經(jīng)自動(dòng)為你聲明了一個(gè)私有成員。那你或許又有疑問了:自動(dòng)生成的私有成員會不會和你已經(jīng)有的成員相沖突呢? 恩, 有道理。因?yàn)榇蠹叶加羞@樣的經(jīng)歷:聲明了一個(gè)名稱為Name的Property就不能聲明一個(gè)get_Name的方法了,因?yàn)樵贗L中屬性是通過方法來實(shí)現(xiàn)的。但是現(xiàn)在請放心:自動(dòng)生成的成員永遠(yuǎn)不會和你自己的類成員相沖突。
來看下
- public string Name
- {
- get;
- set;
- }
生成的IL代碼:
- .method public hidebysig specialname instance string
- get_Name() cil managed
- {
- .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
- // Code size 11 (0xb)
- .maxstack 1
- .locals init (string V_0)
- IL_0000: ldarg.0
- IL_0001: ldfld string DotNewFeature.TestAutoProperty::'< Name>k__BackingField'
- IL_0006: stloc.0
- IL_0007: br.s IL_0009
- IL_0009: ldloc.0
- IL_000a: ret
- } // end of method TestAutoProperty::get_Name
- .method public hidebysig specialname instance void
- set_Name(string 'value') cil managed
- {
- .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
- // Code size 8 (0x8)
- .maxstack 8
- IL_0000: ldarg.0
- IL_0001: ldarg.1
- IL_0002: stfld string DotNewFeature.TestAutoProperty::'< Name>k__BackingField'
- IL_0007: ret
- } // end of method TestAutoProperty::set_Name
- .field private string '< Name>k__BackingField'
其中g(shù)et_Name和set_Name和以前的屬性是一樣的,不過編譯器自動(dòng)生成了一個(gè) 類似< XXXX>k__BackingField的成員,因?yàn)榘珻#中變量不允許的符號(“< ”,">"),所以在使用的時(shí)候還是大可放心的。
那用自動(dòng)屬性和用pulic成員又有啥區(qū)別呢?這倒也是,property 好就好在取數(shù)和賦值的時(shí)候可以執(zhí)行一些額外的邏輯。而自動(dòng)屬性有沒有這些功能。我能想到的有兩個(gè)原因要使用自動(dòng)property而不是public field
(1)代碼一致性,現(xiàn)在在代碼里面基本上看不到使用public field的了
(2)在.Net 中有些地方還只支持property 而不支持public field. 難道不是嗎?
當(dāng)然了,在編寫web頁面或者web控件的時(shí)候最好就不用自動(dòng)屬性了,原因就不用我說了。
匿名類的聲明方式如下:
- var v = new {name="Ben",age = 5};
- string a = v.name;
編譯的時(shí)候生成一個(gè)范型類,然后調(diào)用此范型類的構(gòu)造函數(shù)。具體的就不多說了
至于 擴(kuò)展方法,他可以給你一種能力,能動(dòng)態(tài)的擴(kuò)展一個(gè)類型的方法。就像js 一樣:
- Array.prototype.IndexOf = function(index){//....}
通過擴(kuò)展方法 你可在String類中添加你自己的方法 如:OfMyName()
實(shí)現(xiàn)方法如下:
- namespace MyNameSpace
- {
- public static class TestStaticMethod
- {
- public static string OfMyName(this string s)
- {
- return s + "Ben";
- }
- }
- }
然后在MyNameSpace這個(gè)名字空間內(nèi)都可以這樣使用了:
- String a ="Hello ";
- String b =a. OfMyName();
當(dāng)然在IL中還是調(diào)用TestStaticMethod.OfMyName的。所以還是編譯器耍的障眼法。不過不要真的被迷惑了,請看下面的代碼:
- namespace MyNameSpace
- {
- public static class TestStaticMethod
- {
- public static string OfMyName(this string s)
- {
- return s + "Ben";
- }
- }
- //新加的一個(gè)靜態(tài)類,其中也包含OfMyName方法
- public static class TestStaticMethod_2
- {
- public static string OfMyName(this string s)
- {
- return s + "Benjamin";
- }
- }
- }
然后調(diào)用:
String a ="Hello ";
String b =a. OfMyName();
結(jié)果會增么樣呢?
編譯失?。。。?因?yàn)樵?IL中還是把a(bǔ). OfMyName()映射到具體的類中的方法,而現(xiàn)在不知道要去調(diào)用TestStaticMethod.OfMyName 還是TestStaticMethod_2.OfMyName。
C#3.5新特性就給大家介紹到這里了。
【編輯推薦】