成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

.NET 3.5擴展方法和Lambda表達式

開發 后端
本文探討了如何使用.NET 3.5擴展方法和Lambda表達式來實現實施功能為委托,效果為使用分解循環的清晰方式獲得合并循環的高性能的結果。

對于上文的簡化需求,使用Lambda表達式和內置的.NET 3.5擴展方法便可以寫成這樣:

  1. static List< int> EvenSquareLambda(IEnumerable< int> source)  
  2. {  
  3.     return source.Where(i => i % 2 == 0).Select(i => i * i).ToList();  
  4. }  

.NET 3.5擴展方法的延遲效果

應該已經有許多朋友了解了.NET 3.5中處理集合時擴展方法具有“延遲”的效果,也就是說Where和Select中的委托(兩個Lambda表達式)只有在調用ToList方法的時候才會執行。這是優點也是陷阱,在使用這些方法的時候我們還是需要了解這些方法的效果如何。不過這些方法其實都沒有任何任何“取巧”之處,換句話說,它們的行為和我們正常思維的結果是一致的。如果您想得明白,能夠自己寫出類似的方法,或者能夠“自圓其說”,十有八九也不會有什么偏差。但是如果您想不明白它們是如何構造的,還是通過實驗來確定一下吧。實驗的方式其實很簡單,只要像我們之前驗證“重復計算”陷阱那種方法就可以了,也就是觀察委托的執行時機和順序進行判斷。

好,回到我們現在的問題。我們知道了“延遲”效果,我們知道了Where和Select會在ToList的時候才會進行處理。不過,它們的處理方式是什么樣的,是像我們的“普通方法”那樣“創建臨時容器(如List< T>),并填充返回”嗎?對于這點我們不多作分析,還是通過“觀察委托執行的時機和順序”來尋找答案。使用這種方式的關鍵,便是在委托執行時打印出一些信息。為此,我們需要這樣一個Wrap方法(您自己做試驗時也可以使用這個方法):

  1. static Func< T, TResult> Wrap< T, TResult>(  
  2.     Func< T, TResult> func,  
  3.     string messgaeFormat)  
  4. {  
  5.     return i =>  
  6.     {  
  7.         var result = func(i);  
  8.         Console.WriteLine(messgaeFormat, i, result);  
  9.         return result;  
  10.     };  
  11. }  

Wrap方法的目的是將一個Func< T, TResult>委托對象進行封裝,并返回一個類型相同的委托對象。每次執行封裝后的委托時,都會執行我們提供的委托對象,并根據我們傳遞的messageFormat格式化輸出。例如:

  1. var wrapper = Wrap< intint>(i => i + 1, "{0} + 1 = {1}");  
  2. for (var i = 0; i <  3; i++) wrapper(i);  

則會輸出:

  1. 0 + 1 = 1 
  2. 1 + 1 = 2 
  3. 2 + 1 = 3 

那么,我們下面這段代碼會打印出什么內容呢?

  1. List< int> source = new List< int>();  
  2. for (var i = 0; i <  10; i++) source.Add(i);  
  3.  
  4. var finalSource = source  
  5.     .Where(Wrap< intbool>(i => i % 3 == 0, "{0} can be divided by 3? {1}"))  
  6.     .Select(Wrap< intint>(i => i * i, "The square of {0} equals {1}."))  
  7.     .Where(Wrap< intbool>(i => i % 2 == 0, "The result {0} can be devided by 2? {1}"));  
  8.  
  9. Console.WriteLine("===== Start =====");  
  10. foreach (var item in finalSource)  
  11. {  
  12.     Console.WriteLine("===== Print {0} =====", item);  
  13. }  
  14.  

我們準備一個列表,其中包含0到9共十個元素,并將其進行Where…Select…Where的處理,您可以猜出經過foreach之后屏幕上的內容嗎?

  1. ===== Start =====  
  2. 0 can be divided by 3? True  
  3. The square of 0 equals 0.  
  4. The result 0 can be devided by 2? True  
  5. ===== Print 0 =====  
  6. 1 can be divided by 3? False  
  7. 2 can be divided by 3? False  
  8. 3 can be divided by 3? True  
  9. The square of 3 equals 9.  
  10. The result 9 can be devided by 2? False  
  11. 4 can be divided by 3? False  
  12. 5 can be divided by 3? False  
  13. 6 can be divided by 3? True  
  14. The square of 6 equals 36.  
  15. The result 36 can be devided by 2? True  
  16. ===== Print 36 =====  
  17. 7 can be divided by 3? False  
  18. 8 can be divided by 3? False  
  19. 9 can be divided by 3? True  
  20. The square of 9 equals 81.  
  21. The result 81 can be devided by 2? False 

列表中元素的執行順序是這樣的:
***個元素“0”經過Where…Select…Where,***被Print出來。
第二個元素“1”經過Where,中止。
第三個元素“2”經過Where,中止。
第四個元素“4”經過Where…Select…Where,中止。
……

.NET 3.5擴展方法的神奇之處

這說明了,我們使用.NET框架自帶的Where或Select方法,最終的效果和上一節中的“合并循環”類似。因為,如果創建了臨時容器保存元素的話,就會在***個Where中把所有元素都交由***個委托(i => i % 3 == 0)執行,然后再把過濾后的元素交給Select中的委托(i => i * i)執行。請注意,在這里“合并循環”的效果對外部是隱藏的,我們的代碼似乎還是一步一步地處理集合。換句話說,我們使用“分解循環”的清晰方式,但獲得了“合并循環”的高效實現。這就是.NET框架這些擴展方法的神奇之處1。

在我們進行具體的性能測試之前,我們再來想一下,這里出現了那么多IEnumerable對象實現了哪個GoF 23中的模式呢?枚舉器?看到IEnumerable就說枚舉器也太老生常談了。其實這里同樣用到了“裝飾器”模式。每次Where或Select之后其實都是使用了一個新的IEnumerable對象來封裝原有的對象,這樣我們遍歷新的枚舉器時便會獲得“裝飾”后的效果。因此,以后如果有人問您“.NET框架中有哪些的裝飾器模式的體現”,除了人人都知道的Stream之外,您還可以回答說“.NET 3.5中System.Linq.Enumerable類里的一些擴展方法”,多酷。

以上就介紹了.NET 3.5擴展方法和Lambda表達式實現的高性能分解循環的委托方法。

【編輯推薦】

  1. Lambda表達式:要性能還是要清晰的代碼?
  2. .NET Lambda表達式的函數式特性:索引示例
  3. .NET Lambda表達式的語義:字符串列表范例
  4. 使用.NET 3.5 Lambda表達式實現委托
  5. 各版本.NET委托的寫法回顧
責任編輯:yangsai 來源: 老趙點滴
相關推薦

2009-08-10 09:41:07

.NET Lambda

2010-01-05 14:45:58

.NET Framew

2009-09-09 13:01:33

LINQ Lambda

2009-09-15 15:18:00

Linq Lambda

2022-12-05 09:31:51

接口lambda表達式

2009-09-17 09:09:50

Lambda表達式Linq查詢

2009-09-11 09:48:27

Linq Lambda

2009-08-27 09:44:59

C# Lambda表達

2009-09-15 17:30:00

Linq Lambda

2009-09-17 09:44:54

Linq Lambda

2009-09-17 10:40:22

Linq Lambda

2009-08-10 10:06:10

.NET Lambda

2012-06-26 10:03:58

JavaJava 8lambda

2011-05-20 17:50:45

C#

2024-03-25 13:46:12

C#Lambda編程

2010-09-14 14:05:42

C#委托

2013-04-07 15:44:26

Java8Lambda

2009-09-09 17:14:17

Linq lambda

2013-04-10 10:58:19

LambdaC#

2009-08-10 09:54:19

.NET Lambda
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产高清在线视频 | 产真a观专区 | 欧美精品在欧美一区二区少妇 | 中文字幕一二三区 | 一片毛片 | 一区二区三区欧美在线 | 久久久久精| 成人一区二区三区 | 久久久久久久久久久国产 | 完全免费在线视频 | 人人人人爽 | 91亚洲精品久久久电影 | 日本成人中文字幕 | 欧美精品一区二区在线观看 | 亚洲精品乱码久久久久久蜜桃 | 一级毛片免费完整视频 | 伊人看片| 精品国产91| 亚洲高清在线视频 | 国产精品久久久久久久久久了 | 中文字幕人成乱码在线观看 | 91视频在线| 久久新 | 欧美在线亚洲 | 亚洲免费精品一区 | 午夜男人免费视频 | 99久久婷婷 | 97在线观看| 二区在线视频 | 成人欧美一区二区 | 精品精品| 日韩有码一区 | 国产一区二区三区免费观看视频 | 久草在线 | 欧美日韩免费 | aa级毛片毛片免费观看久 | 国产欧美精品一区二区 | 久久av网| 午夜资源 | 91观看| 国产午夜久久久 |