自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

解析C#委托、時(shí)間和Lambda表達(dá)式

開發(fā) 后端
.NET 中的委托確實(shí)和C/C++的函數(shù)指針非常相似。它是一個(gè)值類型,它包裝了一個(gè)指向方法的引用。來看本文,希望對(duì)你有幫助。

.NET 中的委托確實(shí)和C/C++的函數(shù)指針非常相似。它是一個(gè)值類型,它包裝了一個(gè)指向方法的引用。它的作用也是為了能夠?qū)⒎椒ê妥兞恳粯幼鳛閰?shù)傳遞。委托的典型應(yīng)用是控件的事件處理方法。很顯然,一個(gè)控件在設(shè)計(jì)的時(shí)候沒有辦法知道當(dāng)特定事件發(fā)生的時(shí)候,需要什么方法來處理,這就需要將方法作為參數(shù)傳遞給控件。在LINQ中,也大量用到了委托。

聲明一個(gè)委托要使用delegate關(guān)鍵字,如下:

delegate int Echo(string message);這句代碼聲明了一個(gè)委托類型,這個(gè)委托類型的實(shí)例可以接受參數(shù)為string,返回值為int型的函數(shù)。這個(gè)方法可以是對(duì)象的方法,也可以靜態(tài)方法,還可以是匿名方法,只要方法的簽名和返回值是和聲明一致的。這和C的函數(shù)指針很像,但是函數(shù)指針僅僅包含函數(shù)入口地址,而委托是一個(gè)類型,它具有比函數(shù)指針更強(qiáng)的功能。

其中一點(diǎn)就是當(dāng)方法是實(shí)例方法的時(shí)候,這個(gè)方法可以獲得對(duì)象的其他變量的值,文首的第二篇文章對(duì)此有詳細(xì)介紹,不再贅述。第二點(diǎn)就是委托是支持多播的,也就是一串方法可以可以依次被執(zhí)行。例如:

以下是代碼片段:

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

 

我們定義兩個(gè)方法,這兩個(gè)方法都符合Echo的聲明,***Echo的all實(shí)例可以接受兩個(gè)委托,調(diào)用all的時(shí)候,eo,er會(huì)被一次釣魚,返回值是***一個(gè)委托的返回值。程序的輸出是:

Hello world

Hello Delegat

etageleD olleH

-1

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

.NET的事件機(jī)制是以委托為基礎(chǔ)的。事件機(jī)制有兩部分組成,一部分是事件發(fā)布者,一部分是事件響應(yīng)者。其實(shí)現(xiàn)原理就是由事件發(fā)布者聲明一個(gè)委托對(duì)象,由事件響應(yīng)者向那個(gè)委托掛載具體的處理方法,事件發(fā)布者在需要的時(shí)候調(diào)用這個(gè)委托,這樣響應(yīng)者的代碼就會(huì)被執(zhí)行。事實(shí)上,.NET也是這么做的。C#的event關(guān)鍵字就僅僅做了少量的工作,其中包括為類生成一個(gè)私有的delegate. event所支持的委托是有限制的委托,它的返回值必須是void,參數(shù)是兩個(gè),***個(gè)是事件發(fā)生者,第二個(gè)參數(shù)是事件需要攜帶的參數(shù)。最簡(jiǎn)單的事件處理委托.net已經(jīng)聲明了:

以下是代碼片段:

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

 

聲明事件的基本方式是 event 委托類型 事件名稱;舉個(gè)例子,有這樣的類,每當(dāng)找到一個(gè)奇數(shù),他就會(huì)觸發(fā)一個(gè)事件。我們的程序在接到這個(gè)事件的時(shí)候在屏幕輸出一個(gè)提示。類的代碼可以這樣實(shí)現(xiàn):

以下是代碼片段:

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

 

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

以下是代碼片段:

  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. static void f_FindOdd(object sender, EventArgs e)   
  8. {   
  9. Console.WriteLine("Found!");   

 

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

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

以下是代碼片段:

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

 

匿名方法使用delegate關(guān)鍵字加上參數(shù)表,***是代碼塊來定義。它可以作為委托賦值給委托類型。它可以省去單獨(dú)定義一個(gè)方法的麻煩。

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

Lambda表達(dá)式本質(zhì)上還是匿名方法,它的一般形式是:

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

 

  1. n=>n%2==0; 

 

等價(jià)于

 

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

 

expression lambda 廣泛應(yīng)用于LINQ,它可以用來構(gòu)造Expression Tree,Expression Tree是LINQ的基礎(chǔ)??梢酝ㄟ^動(dòng)態(tài)構(gòu)造Expression Tree來實(shí)現(xiàn)復(fù)雜的動(dòng)態(tài)LINQ查詢,不過這種方法雖然通用,對(duì)于數(shù)據(jù)庫查詢,使用起來和傳統(tǒng)的拼接字符串相比還是很麻煩。

【編輯推薦】

  1. 詳解ADO.NET學(xué)習(xí)和使用方法
  2. Delphi基礎(chǔ) 回調(diào)函數(shù)及其使用
  3. 詳解VB.NET變量聲明的方法
  4. 解析.NET中容易混淆的委托與接口
  5. 盤點(diǎn)VB.NET對(duì)話框制作技巧 
責(zé)任編輯:于鐵 來源: IY專家網(wǎng)博客
相關(guān)推薦

2010-09-14 14:05:42

C#委托

2009-08-27 09:44:59

C# Lambda表達(dá)

2009-08-26 16:17:23

C# Lambda表達(dá)

2009-08-27 09:57:50

C# Lambda表達(dá)

2009-08-10 09:41:07

.NET Lambda

2024-03-25 13:46:12

C#Lambda編程

2021-08-31 07:19:41

Lambda表達(dá)式C#

2009-07-09 09:51:07

Lambda表達(dá)式C#

2009-09-14 13:57:20

C# Lambda表達(dá)Lambda表達(dá)式

2010-10-19 10:03:02

Lambda表達(dá)式

2022-11-07 07:11:19

C#lambda函數(shù)

2009-09-17 09:09:50

Lambda表達(dá)式Linq查詢

2009-08-07 15:41:39

C#正規(guī)表達(dá)式

2009-07-01 09:56:10

C#3.0

2020-10-16 06:40:25

C++匿名函數(shù)

2009-09-11 09:48:27

Linq Lambda

2023-11-02 08:25:58

C++Lambda

2009-05-22 09:48:07

表達(dá)式樹泛型委托.NET

2009-08-24 17:14:41

正則表達(dá)式C#和.NET框架

2009-09-09 13:01:33

LINQ Lambda
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)