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

詳解C#委托、時間和Lambda表達式

開發 后端
今天我們要討論的是C#委托、時間和Lambda表達式這些比較重要的內容。同時我們還會對比C++來具體分析一下這些內容。

關于這個論題,

Delegates, Events, and Lambda Expressions 對此有比較深入的分析,可以參考。

C# vs C++之一:委托 vs 函數指針 比較了委托和C++指針的區別。

.NET 中的委托確實和C/C++的函數指針非常相似。它是一個值類型,它包裝了一個指向方法的引用。它的作用也是為了能夠將方法和變量一樣作為參數傳遞。委托的典型應用是控件的事件處理方法。很顯然,一個控件在設計的時候沒有辦法知道當特定事件發生的時候,需要什么方法來處理,這就需要將方法作為參數傳遞給控件。在LINQ中,也大量用到了委托。

聲明一個委托要使用delegate關鍵字,如下:

delegate int Echo(string message);這句代碼聲明了一個委托類型,這個委托類型的實例可以接受參數為string,返回值為int型的函數。這個方法可以是對象的方法,也可以靜態方法,還可以是匿名方法,只要方法的簽名和返回值是和聲明一致的。這和C的函數指針很像,但是函數指針僅僅包含函數入口地址,而委托是一個類型,它具有比函數指針更強的功能。其中一點就是當方法是實例方法的時候,這個方法可以獲得對象的其他變量的值,文首的第二篇文章對此有詳細介紹,不再贅述。第二點就是委托是支持多播的,也就是一串方法可以可以依次被執行。例如:

  1. static int EchoOriginal(string message)  
  2. {  
  3.     Console.WriteLine(message);  
  4.     return 1;  
  5. }  
  6.  
  7. static int EchoReverse(string message)  
  8. {  
  9.     StringBuilder sb=new StringBuilder();  
  10.     for(int i=message.Length-1;i>=0;i--)               
  11.         sb.Append(message[i]);               
  12.     Console.WriteLine(sb.ToString());  
  13.     return -1;  
  14. }         
  15.  
  16. static void Main(string[] args)  
  17. {  
  18.     Echo eo = EchoOriginal;  
  19.     Echo er = EchoReverse;  
  20.     Echo all = eo + er;  
  21.     eo("Hello world");  
  22.     int i=all("Hello Delegate");  
  23.     Console.WriteLine(i);  

我們定義兩個方法,這兩個方法都符合Echo的聲明,最后Echo的all實例可以接受兩個委托,調用all的時候,eo,er會被一次釣魚,返回值是最后一個委托的返回值。程序的輸出是:

  1. Hello world   
  2. Hello Delegate   
  3. etageleD olleH   
  4. -1 

事實上,方法并不需要和委托聲明類型的簽名完全一致,.net允許方法的返回值是繼承自聲明的返回值的類型,方法的參數類型是聲明的參數的父類型。這就是Covariance and Contravariance in Delegates.

.NET的事件機制是以委托為基礎的。事件機制有兩部分組成,一部分是事件發布者,一部分是事件響應者。其實現原理就是由事件發布者聲明一個委托對象,由事件響應者向那個委托掛載具體的處理方法,事件發布者在需要的時候調用這個委托,這樣響應者的代碼就會被執行。事實上,.NET也是這么做的。C#的event關鍵字就僅僅做了少量的工作,其中包括為類生成一個私有的delegate. event所支持的委托是有限制的委托,它的返回值必須是void,參數是兩個,第一個是事件發生者,第二個參數是事件需要攜帶的參數。最簡單的事件處理委托.net已經聲明了:

  1. public delegate void EventHandler(  
  2.    Object sender,    EventArgs e ) 

聲明事件的基本方式是 event 委托類型 事件名稱;舉個例子,有這樣的類,每當找到一個奇數,他就會觸發一個事件。我們的程序在接到這個事件的時候在屏幕輸出一個提示。類的代碼可以這樣實現:

  1. public class OddFinder  
  2.    {  
  3.        public event EventHandler FindOdd;  
  4.  
  5.        public void Find(int from, int to)  
  6.        {  
  7.            for (int i = from; i <= to; i++)  
  8.            {  
  9.                if (i % 2 != 0)  
  10.                    if (FindOdd != null)  
  11.            FindOdd(this, EventArgs.Empty);  
  12.            }  
  13.        }  
  14.    } 

這個類很簡單,展示了發起事件的基本方法。首先聲明一個事件,指明這個事件處理函數的委托類型。在需要觸發事件的時候,首先判斷是否有事件處理函數掛載,然后調用這個委托即可。外部處理程序把事件處理程序掛載上去:

  1. static void Main(string[] args)  
  2. {  
  3.      OddFinder f = new OddFinder();  
  4.      f.FindOdd += new EventHandler(f_FindOdd);  
  5.      f.Find(1, 5);  
  6. }  
  7.  
  8. static void f_FindOdd(object sender, EventArgs e)  
  9. {  
  10.     Console.WriteLine("Found!");  

這樣程序運行后,就會在屏幕上輸出3次Found!。如果需要在觸發事件的時候,傳遞更多的信息給事件處理函數,比如當前找到的奇數是多少,那么就需要新建一個類繼承自EventArgs,在這個類中可以添加一些需要的數據。 再聲明一個委托,第二個參數為EventArgs類型即可。

以上是基本的委托和事件的介紹,自.net 1.0開始就是如此,.net 2.0 引入了匿名方法,可以簡化委托的某些操作。例如:

  1. f.FindOdd += delegate(object sender, EventArgs e)  
  2. {  
  3.     Console.WriteLine("Found!");  
  4. }; 

匿名方法使用delegate關鍵字加上參數表,最后是代碼塊來定義。它可以作為委托賦值給委托類型。它可以省去單獨定義一個方法的麻煩。

.NET 3.0之后引入了Lambda表達式,它進一步簡化了匿名方法的寫法,使得在C#中,把函數作為參數傳遞變得更加簡單自然,從而C#變得更加具有函數式語言的味道。關于函數式語言的進一步介紹,可以參考:Functional Programming Languages . 函數式語言的理論基礎是Lambda Calulus,關于此可以參考A Tutorial Introduction to the Lambda Calculus .

Lambda表達式本質上還是匿名方法,它的一般形式是:

(input parameters) => expression左側是參數列表,=>右側是方法體,可以是一個表達式(expression lambda),也可以是大括號括起來的語句段(statement lambda)。它省略了delegate關鍵字,使得代碼更加緊湊。例如:

n=>n%2==0;

等價于

delegate(int n){ return n%2==0;}

expression lambda 廣泛應用于LINQ,它可以用來構造Expression Tree,Expression Tree是LINQ的基礎。可以通過動態構造Expression Tree來實現復雜的動態LINQ查詢,不過這種方法雖然通用,對于數據庫查詢,使用起來和傳統的拼接字符串相比還是很麻煩。下文將介紹微軟的一個LINQ擴展,Dynamic LINQ.

原文標題:C# 委托,事件和Lambda表達式

鏈接:http://www.cnblogs.com/yinzixin/archive/2010/09/14/1825611.html

【編輯推薦】

 

  1. C#模式窗體中的按鈕操作
  2. C#模式窗體操作詳解
  3. C#窗體繼承原理以及實現淺析
  4. C#窗體關閉事件的重載實現淺析
  5. C#窗體位置與大小設置詳解
責任編輯:彭凡 來源: 博客園
相關推薦

2011-05-20 17:50:45

C#

2009-08-27 09:44:59

C# Lambda表達

2009-09-14 13:57:20

C# Lambda表達Lambda表達式

2009-08-27 09:57:50

C# Lambda表達

2009-08-26 16:17:23

C# Lambda表達

2009-08-10 09:41:07

.NET Lambda

2009-08-07 15:41:39

C#正規表達式

2024-03-25 13:46:12

C#Lambda編程

2009-07-09 09:51:07

Lambda表達式C#

2021-08-31 07:19:41

Lambda表達式C#

2009-07-01 09:56:10

C#3.0

2009-08-03 17:27:14

C#正則表達式

2022-11-07 07:11:19

C#lambda函數

2010-10-19 10:03:02

Lambda表達式

2025-03-06 08:16:08

lambda表達式變量

2009-08-20 16:23:32

C#正則表達式語法

2009-09-17 09:09:50

Lambda表達式Linq查詢

2009-05-22 09:48:07

表達式樹泛型委托.NET

2023-11-02 08:25:58

C++Lambda

2009-04-09 09:19:25

C#規則表達式.NET
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品国产精品国产偷麻豆 | 欧美视频第二页 | 午夜精品福利视频 | 一区二区三区欧美在线观看 | 亚洲精品在线看 | 中文字幕日韩一区 | 欧美一级免费看 | 国产99久久久国产精品 | 色综合网站 | 欧美日韩视频 | 精品视频国产 | 国产一级特黄aaa大片评分 | 中文字幕日韩欧美一区二区三区 | 老妇激情毛片免费 | 国产一级片一区二区 | 在线观看中文字幕一区二区 | 久久精品国产a三级三级三级 | 成人精品免费视频 | 国产高清精品一区二区三区 | 中文字幕影院 | 成人国产精品色哟哟 | 久久高清| 久草网视频| 午夜成人在线视频 | 国产一区二区三区不卡av | 亚洲精品国产一区 | 伊人久久综合 | 一级毛片视频 | 日韩精品久久 | 99久久精品免费看国产小宝寻花 | 精品欧美乱码久久久久久 | 亚洲欧美中文日韩在线 | 国产精品jizz在线观看老狼 | 综合色在线| 免费福利视频一区二区三区 | 免费一级毛片 | 国产高清精品一区二区三区 | 永久网站 | 精品国产欧美一区二区三区成人 | 欧美一级α片 | 国产一区二区三区在线免费观看 |