日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
C#2.0之殤,以及函數(shù)式編程的未來

似乎還有不少項目在用C#2.0,但是C#2.0的生產(chǎn)力實在不如C#3.0——如果您不信,那么一會兒就會意識到這一點。有朋友認為語言能力不重要,有了好用的框架/類庫也可以有很高的生產(chǎn)力。所以這篇文章,我們就設(shè)法使用“類庫”來彌補C#2.0的缺陷。

在萍鄉(xiāng)等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供做網(wǎng)站、網(wǎng)站設(shè)計 網(wǎng)站設(shè)計制作定制網(wǎng)站設(shè)計,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站建設(shè),營銷型網(wǎng)站,成都外貿(mào)網(wǎng)站建設(shè)公司,萍鄉(xiāng)網(wǎng)站建設(shè)費用合理。

但是,我們真做的到嗎?

C#2.0之殤

C#2.0較C#1.0來說是一個突破,其中引入了泛型,以及匿名方法等新特性。如果前者還可以說是平臺的增強,而語言只是個“輔助”的話,而后者則百分之一百是編譯器的魔法了。別小看這個特性,它為C#3.0的高生產(chǎn)力踏出了堅實的一步——不過還是差了很多。例如,我們有一個要求:“把一個字符串?dāng)?shù)組中的元素轉(zhuǎn)化為整數(shù),再將其中的偶數(shù)放入一個List< int>容器中”。如果是C#3.0,這是再簡單不過的功能:

 
 
 
  1. string[]strArray={"1","2","3","4"};  
  2. vareven=strArray.Select(s=>Int32.Parse(s)).Where(i=>i%2==0).ToList();  

那么對于C#2.0(當(dāng)然對于C#1.0也一樣),代碼又該怎么寫呢?

 
 
 
  1. List< int>even=newList< int>();  
  2. foreach(stringsinstrArray)  
  3. {  
  4. inti=Int32.Parse(s);  
  5. if(i%2==0)  
  6. {  
  7. even.Add(i);  
  8. }  
  9. }  

有人說函數(shù)式編程有什么用,C#3.0就是個很好的證明。C#3.0中引入了Lambda表達式,增強了在語言中構(gòu)造匿名方法的能力——這是一個語言中函數(shù)式編程特性的必備條件。C#3.0的實現(xiàn)與C#2.0相比,可讀性高,可以直接看出轉(zhuǎn)化、過濾,以及構(gòu)造容器的過程和標(biāo)準(zhǔn)。由于語言能力的增強,程序的表現(xiàn)能力得到了很大的提高,在很多時候,我們可以省去將一些代碼提取為獨立方法的必要。當(dāng)然,即使您將其提取為額外的方法,C#3.0也可以讓您寫出更少的代碼。

如果您覺得以上代碼的差距還不是過于明顯的話——那么以下功能呢?

 
 
 
  1. int[]intArray={1,2,3,4,5,6,7,8,9,10};  
  2.  
  3. //所有偶數(shù)的平均數(shù)  
  4.  
  5. varevenAverage=intArray.Where(i=>i%2==0).Average();  
  6.  
  7. //都是偶數(shù)?  
  8.  
  9. varallEven=intArray.All(i=>i%2==0);  
  10.  
  11. //包含偶數(shù)?  
  12.  
  13. varcontainsEven=intArray.Any(i=>i%2==0);  
  14.  
  15. //第4到第8個數(shù)  
  16.  
  17. varfourthToEighth=intArray.Skip(3).Take(5);  

如果您使用C#2.0來寫,您會怎么做?

拯救C#2.0

C#3.0通過引入了函數(shù)式編程特性大幅增強了語言的生產(chǎn)力。如果說C#2.0和Java還沒有太大差距的話,那么C#3.0已經(jīng)將Java甩開地太遠太遠。不過真要說起來,在Java中并非不可以加入函數(shù)式編程的理念。只不過,如果沒有足夠的語言特性進行支持(如快速構(gòu)造匿名函數(shù)、閉包、一定程度的類型推演等等),函數(shù)式編程對于某些語言來說幾乎只能成為“理念”。不過現(xiàn)在,我們暫且先放下對“函數(shù)式編程”相關(guān)內(nèi)容的探索,設(shè)法拯救C#2.0所缺失的生產(chǎn)力吧。

C#3.0中可以使用Lambda表達式構(gòu)造一個匿名函數(shù),這個能力其實在C#2.0中也有。我們姑且認為這點不是造成差距的主要原因,那么有一點是C#2.0絕對無法實現(xiàn)的,那就是“擴展方法”。C#3.0中的擴展方法,可以“零耦合”地為一個,甚至一系列類型添加“實例方法”。當(dāng)然,這也是編譯器的功能,實際上我們只是定義了一些靜態(tài)方法而已。這一點在C#2.0中還是可以做到的:

 
 
 
  1. publicclassEnumerable  
  2.  
  3. {  
  4.  
  5. publicstaticIEnumerable< T>Where< T>(Func< T,bool>predicate,IEnumerable< T>source)  
  6.  
  7. {  
  8.  
  9. foreach(Titeminsource)  
  10.  
  11. {  
  12.  
  13. if(predicate(item))  
  14.  
  15. {  
  16.  
  17. yieldreturnitem;  
  18.  
  19. }  
  20.  
  21. }  
  22.  
  23. }  
  24.  
  25. publicstaticIEnumerable< TResult>Select< T,TResult>(Func< T,TResult>selector,IEnumerable< T>source)  
  26.  
  27. {  
  28.  
  29. foreach(Titeminsource)  
  30.  
  31. {  
  32.  
  33. yieldreturnselector(item);  
  34.  
  35. }  
  36.  
  37. }  
  38.  
  39. publicstaticList< T>ToList< T>(IEnumerable< T>source)  
  40.  
  41. {  
  42.  
  43. List< T>list=newList< T>();  
  44.  
  45. foreach(Titeminsource)  
  46.  
  47. {  
  48.  
  49. list.Add(item);  
  50.  
  51. }  
  52.  
  53. returnlist;  
  54.  
  55. }  
  56.  
  57. }  

于是現(xiàn)在,我們便可以換種寫法來實現(xiàn)相同的功能了:

 
 
 
  1. string[]strArray={"1","2","3","4"};  
  2.  
  3. List< int>even=  
  4.  
  5. Enumerable.ToList(  
  6.  
  7. Enumerable.Where(  
  8.  
  9. delegate(inti){returni%2==0;},  
  10.  
  11. Enumerable.Select(  
  12.  
  13. delegate(strings){returnInt32.Parse(s);},  
  14.  
  15. strArray)));  

即使您可以接受delegate關(guān)鍵字構(gòu)造匿名函數(shù)的能力,但是上面的做法還是有個天生的缺陷:邏輯與表現(xiàn)的次序想反。我們想表現(xiàn)的邏輯順序為:轉(zhuǎn)化(Select)、過濾(Where)、及容器構(gòu)造(ToList),C#3.0所表現(xiàn)出的順序和它相同,而C#2.0的順序則相反。由于語言能力的缺失,這個差距無法彌補。很多時候,語言的一些“小功能”并不能說是可有可無的特性,它很可能直接決定了是否可以用某種語言來構(gòu)造InternalDSL或進行BDD。例如,由于F#的靈活語法,F(xiàn)sTest使得開發(fā)人員可以寫出"foobar"|>shouldcontains"foo"這樣的語句來避免機械的Assert語法。同樣,老趙也曾經(jīng)使用actor< =msg這樣的邏輯來替代actor.Post(msg)的顯式調(diào)用方式。

封裝邏輯

既然沒有“擴展方法”,我們要避免靜態(tài)方法的調(diào)用形式,那么就只能在一個類中定義邏輯了。這點并不困難,畢竟在API的設(shè)計發(fā)展至今,已經(jīng)進入了關(guān)注FluentInterface的階段,這方面已經(jīng)積累了大量的實踐。于是我們構(gòu)造一個Enumerable< T>類,封裝IEnumerable< T>對象,以此作為擴展的入口:

 
 
 
  1. publicclassEnumerable< T>  
  2.  
  3. {  
  4.  
  5. privateIEnumerable< T>m_source;  
  6.  
  7. publicEnumerable(IEnumerable< T>source)  
  8.  
  9. {  
  10.  
  11. if(source==null)thrownewArgumentNullException("source");  
  12.  
  13. this.m_source=source;  
  14.  
  15. }  
  16.  
  17. ...  
  18.  
  19. }  
  20.  
  21. 并以此定義所需的Select和Where方法:  
  22.  
  23. publicEnumerable< T>Where(Func< T,bool>predicate)  
  24.  
  25. {  
  26.  
  27. if(predicate==null)thrownewArgumentNullException("predicate");  
  28.  
  29. returnnewEnumerable< T>(Where(this.m_source,predicate));  
  30.  
  31. }  
  32.  
  33. privatestaticIEnumerable< T>Where(IEnumerable< T>source,Func< T,bool>predicate)  
  34.  
  35. {  
  36.  
  37. foreach(Titeminsource)  
  38.  
  39. {  
  40.  
  41. if(predicate(item))  
  42.  
  43. {  
  44.  
  45. yieldreturnitem;  
  46.  
  47. }  
  48.  
  49. }  
  50.  
  51. }  
  52.  
  53. publicEnumerable< TResult>Select< TResult>(Func< T,TResult>selector)  
  54.  
  55. {  
  56.  
  57. if(selector==null)thrownewArgumentNullException("selector");  
  58.  
  59. returnnewEnumerable< TResult>(Select(this.m_source,selector));  
  60.  
  61. }  
  62.  
  63. privatestaticIEnumerable< TResult>Select< TResult>(IEnumerable< T>source,Func< T,TResult>selector)  
  64.  
  65. {  
  66.  
  67. foreach(Titeminsource)  
  68.  
  69. {  
  70.  
  71. yieldreturnselector(item);  
  72.  
  73. }  
  74.  
  75. }  

這些擴展都是些高階函數(shù),也都有延遲效果,相信很容易理解,在此就不多作解釋了。在這里我們直接觀察其使用方式:

 
 
 
  1. List< int>even=newEnumerable< string>(strArray)  
  2.  
  3. .Select(delegate(strings){returnInt32.Parse(s);})  
  4.  
  5. .Where(delegate(inti){returni%2==0;})  
  6.  
  7. .ToList();  

不知道您對此有何感覺?

老趙對此并不滿意,尤其是和C#3.0相較之下。我們雖然定義了Enumerable封裝類,并提供了Select和Where等邏輯,但是由于匿名函數(shù)的構(gòu)造還是較為丑陋。使用delegate構(gòu)造匿名函數(shù)還是引起了不少噪音:

與JavaScript的function關(guān)鍵字,和VB.NET的Function關(guān)鍵字一樣,C#2.0在構(gòu)造匿名函數(shù)時無法省確delegate關(guān)鍵字。

與C#3.0中的Lambda表達式相比,使用delegate匿名函數(shù)缺少了必要的類型推演。

使用delegate構(gòu)造匿名函數(shù)時必須提供完整的方法體,也就是只能提供“語句”,而不能僅為一個“表達式”,因此return和最后的分號無法省確。

我們設(shè)法拯救C#2.0,但是我們真的做到了嗎?

框架/類庫真能彌補語言的生產(chǎn)力嗎?

【編輯推薦】

  1. 淺談CLR 4.0安全模型的運作機制
  2. 探秘CLR 4.0中的代碼契約
  3. CLR線程池的作用與原理淺析
  4. SQL Server 2005中的CLR集成
  5. CLR 4.0中的新內(nèi)容 狀態(tài)錯亂異常

名稱欄目:C#2.0之殤,以及函數(shù)式編程的未來
本文網(wǎng)址:http://m.5511xx.com/article/djgehdh.html