程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#基礎知識 >> 淺談C#在3.0和3.5中的新特性的本質

淺談C#在3.0和3.5中的新特性的本質

編輯:C#基礎知識

 話說.net 4.0都出來了,連.net 3.5都還沒熟悉,是不是有點落伍阿? 恩 我也這麼覺得。為了跟上人類進步的步伐。 今天花了些時間了解了下c#3.5的基本情況。我認為大致有下面幾點新東西:

1、var 關鍵字 2、自動屬性(Automatic property) 3、匿名類 4、擴展方法
  當然,話說回來,所有這些新特性都是編譯器給我們玩的小把戲,也就是人們常說的“語法糖”。在IL級別沒有任何變化。       在js中定義變量使用var關鍵字,可以使用var來定義一個變量,保存任何一種類型的值,但是在C#中只能在聲明的時候賦值如:var v = "123";並且只能用作局部變量。不能聲明一個var類型的field,或通過方法傳遞一個var類型的參數等。              自動屬性還是有點意思,可以減輕一些工作量:        public string Name        {            get;            set;        }        是不是有點眼熟呢?呵呵, 不要和抽象屬性搞混了,        public abstract string Name        {            get;            set;        }       C#編譯器認得到。利用自動屬性,就可以免得定義使用私有成員了,事實上就像我上面說的那樣:都是“語法糖” ,在編譯成IL的過程中,編譯器已經自動為你聲明了一個私有成員。那你或許又有疑問了:自動生成的私有成員會不會和你已經有的成員相沖突呢? 恩, 有道理。因為大家都有這樣的經歷:聲明了一個名稱為Name的Property就不能聲明一個get_Name的方法了,因為在IL中屬性是通過方法來實現的。但是現在請放心:自動生成的成員永遠不會和你自己的類成員相沖突。 來看下  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'
 
  其中get_Name和set_Name和以前的屬性是一樣的,不過編譯器自動生成了一個 類似<XXXX>k__BackingField的成員,因為包含C#中變量不允許的符號(“<”,">"),所以在使用的時候還是大可放心的。       那用自動屬性和用pulic成員又有啥區別呢?這倒也是,property 好就好在取數和賦值的時候可以執行一些額外的邏輯。而自動屬性有沒有這些功能。我能想到的有兩個原因要使用自動property而不是public field (1)代碼一致性,現在在代碼裡面基本上看不到使用public field的了 (2)在.Net 中有些地方還只支持property 而不支持public field. 難道不是嗎? 當然了,在編寫web頁面或者web控件的時候最好就不用自動屬性了,原因就不用我說了。
  匿名類的聲明方式如下: var v = new {name="Ben",age = 5}; string a = v.name;
  編譯的時候生成一個范型類,然後調用此范型類的構造函數。具體的就不多說了
  至於 擴展方法,他可以給你一種能力,能動態的擴展一個類型的方法。就像js 一樣: Array.prototype.IndexOf = function(index){//....} 通過擴展方法 你可在String類中添加你自己的方法 如:OfMyName() 實現方法如下: namespace MyNameSpace {     public static class TestStaticMethod     {         public static string OfMyName(this string s)         {             return s + "Ben";         }     } }
  然後在MyNameSpace這個名字空間內都可以這樣使用了: String a ="Hello "; String b =a.OfMyString(); 當然在IL中還是調用TestStaticMethod.OfMyName的。所以還是編譯器耍的障眼法。不過不要真的被迷惑了,請看下面的代碼: namespace MyNameSpace {     public static class TestStaticMethod     {         public static string OfMyName(this string s)         {             return s + "Ben";         }     }       //新加的一個靜態類,其中也包含OfMyName方法       public static class TestStaticMethod_2     {         public static string OfMyName(this string s)         {             return s + "Benjamin";         }     } } 然後調用: String a ="Hello "; String b =a.OfMyString(); 結果會增麼樣呢? 編譯失敗!!! 因為在 IL中還是把a.OfMyString()影射到具體的類中的方法,而現在不知道要去調用TestStaticMethod.OfMyName 還是TestStaticMethod_2.OfMyName。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved