C#基礎之匿名方法執行個體教程

來源:互聯網
上載者:User

標籤:提示   ted   html   open   net   span   str   條件判斷   clear   

本文以執行個體形式講解了C#的匿名方法的用法,分享給大家供大家參考之用。具體如下:

匿名方法是C# 2.0的語言新特性。首先看個最簡單的例子:

class Program{ static void Main(string[] args) {  List<string> names = new List<string>();  names.Add("Sunny Chen");  names.Add("Kitty Wang");  names.Add("Sunny Crystal");  List<string> found = names.FindAll( new Predicate<string>(NameMatches));  if (found != null)  {   foreach (string str in found)    Console.WriteLine(str);  } } static bool NameMatches(string name) {  return name.StartsWith("sunny", StringComparison.OrdinalIgnoreCase); }}

這段代碼在開始的時候初始化了一個字串列表(string list),然後通過列表的FindAll方法來尋找以“sunny”起始的字串,最後將所尋找到的所有結果輸出。

我們需要著重介紹List<T>的FindAll方法。這個方法是一個參數為Predicate<T>類型、傳回值為List<T>類型的函數。注意,Predicate<T>是一個泛型委派,它指代這樣一些函數:這些函數僅有一個T類型的參數,並且傳回值是布爾類型。通過reflector等工具,我們可以看到Predicate<T>的定義如下:

public delegate bool Predicate<T>(T obj);

至此我們也多少能夠猜到FindAll方法的具體實現。即針對List<T>中的每個元素,調用Predicate<T>所指代的函數,如果函數返回為true,則將其加入建立的列表中。遍曆完所有的元素後,將建立的列表返回給調用者。如下:

public List<T> FindAll<T>(Predicate<T> match){ List<T> ret = new List<T>(); foreach (T elem in items) {  if (match(elem))   ret.Add(elem); } return ret;} 

因此,針對上面的例子,要調用FindAll方法,我們必須先定義一個參數為string類型,傳回值為布爾類型的函數,在這個函數中,對參數進行條件判斷,如果符合條件(也就是以“sunny”作為起始字串),那麼就返回true,否則返回false。最後再將這個函數作為參數傳遞給FindAll。於是也就得到了最上面的代碼。

在上面的例子中,為了調用FindAll方法,我們不得不新定義一個函數,其實這個函數除了FindAll方法要用外,別的地方都幾乎很少使用到它,你還不得不給它起個名字。如果程式中有多處需要調用FindAll方法,或者類似的情況,那麼整個程式也就會出現一大批“只有一個地方使用”的函數,使得代碼難於閱讀和維護。

由於存在這樣的問題,C# 2.0引入了匿名方法。開發人員在實現方法的時候,只需要給出方法的參數列表(甚至也可以不給)以及方法具體實現,而不需要關心方法的傳回值,更不必給方法起名字。最關鍵的是,只在需要的地方定義匿名方法,保證了代碼的簡潔。

匿名方法只在需要的地方定義,定義的時候,使用delegate關鍵字,後接參數列表,然後跟上用一對花括弧包括起來的函數體即可。上面的代碼可以重構成下面的形式:

class Program{ static void Main(string[] args) {  List<string> names = new List<string>();  names.Add("Sunny Chen");  names.Add("Kitty Wang");  names.Add("Sunny Crystal");  List<string> found = names.FindAll(   delegate(string name)   {    return name.StartsWith("sunny", StringComparison.OrdinalIgnoreCase);   });  if (found != null)  {   foreach (string str in found)    Console.WriteLine(str);  } } //static bool NameMatches(string name) //{ // return name.StartsWith("sunny", //  StringComparison.OrdinalIgnoreCase); //}} 

此時,我們完全不需要NameMatches方法了,直接將匿名方法作為參數傳遞給FindAll方法。其實匿名方法本身還是有名字的,只是我們並不關心它究竟該取什麼名字,因而.NET幫我們隨便取了個名字罷了。

匿名方法在C#中應用十分廣泛,因為委託作為函數參數是件非常平常的事情。在定義簡單的事件處理過程時,我們同樣可以使用匿名方法。比如:

ServiceHost host = new ServiceHost(typeof(FileTransferImpl));host.Opened += delegate(object sender, EventArgs e){ Console.WriteLine("Service Opened.");};

匿名方法可以很方便地使用本地變數,這與單獨定義的命名方法相比,能夠簡化編程。比如上文的例子中,假如Main函數裡面定義了一個整型本地變數(局部變數)number,那麼可以在delegate (string name)這一匿名方法定義中使用number變數。

上文提到,在定義匿名方法的時候,連參數列表都可以省略。因為編譯器可以根據委託的簽名來確定函數的簽名,然後只要再給函數起個名字就可以了。下面的代碼示範了這種使用方式:

delegate void IntDelegate(int x);// 帶參數的定義方式IntDelegate d2 = delegate(int p) { Console.WriteLine(p); };// 不帶參數的定義方式(當然也沒帶傳回值)IntDelegate d3 = delegate { Console.WriteLine("Hello."); };

在使用不帶參數和傳回值的匿名方法定義時,需要注意以下兩點:

1.如果在你的匿名方法中需要對參數進行處理,那麼你不能使用不定義參數列表的聲明方式。也就是在定義匿名方法的時候,需要給出參數列表。

2.不帶參數和傳回值的匿名方法,可以被具有任何形式簽名的委託所指代。

上述第一點顯而易見,因為你沒有定義參數列表,也就沒有辦法使用參數;要說明第二點,我們可以看下面的代碼:

class Program{ delegate void IntDelegate(int x); delegate void StringDelegate(string y); static void Output(IntDelegate id) { } static void Output(StringDelegate sd) { } static void Main(string[] args) {  /*   * ERROR: The call is ambiguous between   *  Output(IntDelegate)   *    and   *  Output(StringDelegate)   */  Output(delegate { }); }}

上面的代碼沒法編譯通過,因為編譯器不知道應該將delegate { }這一匿名方法還原為由IntDelegate指代的函數,還是還原為由StringDelegate指代的函數。此時只能顯式給定參數列表,以便讓編譯器知道,我們究竟是想調用哪個Output函數。

希望本文所述對大家的C#程式設計有所協助

除聲明外, 跑步客文章均為原創,轉載請以連結形式標明本文地址
  C#基礎之匿名方法執行個體教程

本文地址:  http://www.paobuke.com/develop/c-develop/pbk23547.html






相關內容為IObservable實現自己的運算子(詳解)C#中調用DLL時未能負載檔案或程式集錯誤的處理方法(詳解)詳解C#的設計模式編程之抽象原廠模式的應用實現ASP.NET無重新整理下載並提示下載完成的開發思路
C#通過DataSet讀寫xml檔案的方法C#遍曆作業系統下所有磁碟機的方法C#實現發送簡單HTTP請求的方法C#演算法之全排列遞迴演算法執行個體講解

C#基礎之匿名方法執行個體教程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.