天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

C# 委托,事件和Lambda表達式

  關于這個論題,Delegates, Events, and Lambda Expressions 對此有比較深入的分析,可以參考。C# vs C++之一:委托 vs 函數指針 比較了委托和C++指針的區別。

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

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

delegate int Echo(string message);

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

static int EchoOriginal(string message)
{
Console.WriteLine(message);
return 1;
}

static int EchoReverse(string message)
{
StringBuilder sb=new StringBuilder();
for(int i=message.Length-1;i>=0;i--)
sb.Append(message[i]);
Console.WriteLine(sb.ToString());
return -1;
}

static void Main(string[] args)
{
Echo eo = EchoOriginal;
Echo er = EchoReverse;
Echo all = eo + er;
eo("Hello world");
int i=all("Hello Delegate");
Console.WriteLine(i);
}

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

  Hello world
  Hello Delegate
  etageleD olleH
  -1

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

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

 public delegate void EventHandler(
Object sender, EventArgs e )

  聲明事件的基本方式是 event 委托類型事件名稱;

  舉個例子,有這樣的類,每當找到一個奇數,他就會觸發一個事件。我們的程序在接到這個事件的時候在屏幕輸出一個提示。類的代碼可以這樣實現:

public class OddFinder
{
public event EventHandler FindOdd;

public void Find(int from, int to)
{
for (int i = from; i <= to; i++)
{
if (i % 2 != 0)
if (FindOdd != null)
FindOdd(this, EventArgs.Empty);
}
}
}

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

static void Main(string[] args)
{
OddFinder f = new OddFinder();
f.FindOdd += new EventHandler(f_FindOdd);
f.Find(1, 5);
}

static void f_FindOdd(object sender, EventArgs e)
{
Console.WriteLine("Found!");
}

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

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

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

  匿名方法使用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;        
        

NET技術C# 委托,事件和Lambda表達式,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 3D漫画H精品啪啪无码 | 美美哒免费影视8 | 亚洲AV无码影院在线播放 | YIN荡的老师系列第6部分视频 | 亚洲日韩中文字幕区 | 午夜精品久久久久久影视riav | 草莓视频在线看免费高清观看 | 日本高清免费一本在线观看 | 恋夜影院支持安卓视频美女 | 精品国产麻豆免费人成网站 | 超碰在线97久久视频观看 | 538prom国产在线视频一区 | 伊人久久影院 | GAY2022空少被体育生暴菊 | 日日噜噜大屁股熟妇 | 成人网络电视破解版 | 偷拍亚洲色自拍 | 亚洲AV无码专区国产乱码网站 | 九九精彩视频在线观看视频 | 国产伦精品一区二区三区免费观看 | 欧美一区二区三区播放 | 日本一卡二卡三卡四卡无卡免费播放 | 国产精品成人不卡在线观看 | 19十主播福利视频 | 夜夜女人国产香蕉久久精品 | 接吻吃胸摸下面啪啪教程 | 做暖免费观看日本 | 久久香蕉国产线看观看精品 | 无限资源在线观看8 | 国产一区二区内射最近更新 | 欧美精品成人a多人在线观看 | 蜜臀AV人妻久久无码精品麻豆 | 亚洲午夜久久久无码精品网红A片 | 岛国大片在线观看完整版 | 阿娇和冠希13分钟在线观看 | 国产精品第3页 | 大胸美女被c | 2012中文字幕在线动漫电影 | 午夜理论片YY4399影院 | 精品国产中文字幕在线视频 | 亚洲欧美成人在线 |