欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#基礎(chǔ)之匿名方法實(shí)例教程

 更新時間:2014年09月06日 09:19:39   投稿:shichen2014  
這篇文章主要介紹了C#的匿名方法,包括匿名方法的定義以及常用方法,并以示例形式說明其用法,需要的朋友可以參考下

本文以實(shí)例形式講解了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”起始的字符串,最后將所查找到的所有結(jié)果輸出。

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

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

至此我們也多少能夠猜到FindAll方法的具體實(shí)現(xiàn)。即針對List<T>中的每個元素,調(diào)用Predicate<T>所指代的函數(shù),如果函數(shù)返回為true,則將其加入新建的列表中。遍歷完所有的元素后,將新建的列表返回給調(diào)用者。如下:

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; 
} 

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

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

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

匿名方法只在需要的地方定義,定義的時候,使用delegate關(guān)鍵字,后接參數(shù)列表,然后跟上用一對花括號包括起來的函數(shù)體即可。上面的代碼可以重構(gòu)成下面的形式:

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方法了,直接將匿名方法作為參數(shù)傳遞給FindAll方法。其實(shí)匿名方法本身還是有名字的,只是我們并不關(guān)心它究竟該取什么名字,因而.NET幫我們隨便取了個名字罷了。

匿名方法在C#中應(yīng)用十分廣泛,因?yàn)槲凶鳛楹瘮?shù)參數(shù)是件非常平常的事情。在定義簡單的事件處理過程時,我們同樣可以使用匿名方法。比如:

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

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

上文提到,在定義匿名方法的時候,連參數(shù)列表都可以省略。因?yàn)榫幾g器可以根據(jù)委托的簽名來確定函數(shù)的簽名,然后只要再給函數(shù)起個名字就可以了。下面的代碼演示了這種使用方式:

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

在使用不帶參數(shù)和返回值的匿名方法定義時,需要注意以下兩點(diǎn):

1.如果在你的匿名方法中需要對參數(shù)進(jìn)行處理,那么你不能使用不定義參數(shù)列表的聲明方式。也就是在定義匿名方法的時候,需要給出參數(shù)列表。
2.不帶參數(shù)和返回值的匿名方法,可以被具有任何形式簽名的委托所指代。

上述第一點(diǎn)顯而易見,因?yàn)槟銢]有定義參數(shù)列表,也就沒有辦法使用參數(shù);要說明第二點(diǎn),我們可以看下面的代碼:

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 { }); 
 } 
} 

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

希望本文所述對大家的C#程序設(shè)計(jì)有所幫助

相關(guān)文章

  • C#中的三種定時計(jì)時器Timer用法介紹

    C#中的三種定時計(jì)時器Timer用法介紹

    這篇文章介紹了C#中的三種定時計(jì)時器Timer的用法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • C#異步下載文件

    C#異步下載文件

    這篇文章主要介紹了C#異步下載文件的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • C#打開揚(yáng)聲器的實(shí)操方法和代碼

    C#打開揚(yáng)聲器的實(shí)操方法和代碼

    在本篇文章中我們給大家分享的是關(guān)于C#如何打開揚(yáng)聲器的相關(guān)知識點(diǎn)內(nèi)容,需要的讀者們學(xué)習(xí)下。
    2019-08-08
  • C# 讀寫XML(代碼分享)

    C# 讀寫XML(代碼分享)

    本文主要介紹了C# 讀寫XML的相關(guān)知識,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • C#的this關(guān)鍵字的2種用法

    C#的this關(guān)鍵字的2種用法

    這篇文章主要給大家分享的是C#的this關(guān)鍵字的2種用法,在使用C#的過程中,發(fā)現(xiàn)this關(guān)鍵是比較少用的,但是在下面這二個場合下是必須要使用的,不使用它是解決不了問題。下面我們就來看看文章的具體內(nèi)容吧
    2021-10-10
  • C# 字符串的連接(實(shí)例講解)

    C# 字符串的連接(實(shí)例講解)

    下面小編就為大家分享一篇C# 字符串的連接實(shí)例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • 用序列化實(shí)現(xiàn)List<T> 實(shí)例的深復(fù)制(推薦)

    用序列化實(shí)現(xiàn)List<T> 實(shí)例的深復(fù)制(推薦)

    下面小編就為大家?guī)硪黄眯蛄谢瘜?shí)現(xiàn)List<T> 實(shí)例的深復(fù)制(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • c# 隨機(jī)函數(shù)的使用詳解

    c# 隨機(jī)函數(shù)的使用詳解

    本篇文章是對c#隨機(jī)函數(shù)的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • 將excel數(shù)據(jù)轉(zhuǎn)換成dataset示例

    將excel數(shù)據(jù)轉(zhuǎn)換成dataset示例

    這篇文章主要介紹了不借助第三方插件的情況下將Excel中的數(shù)據(jù)轉(zhuǎn)換成DataSet的方法,需要的朋友可以參考下
    2014-02-02
  • C#中實(shí)現(xiàn)Json序列化與反序列化的幾種方式

    C#中實(shí)現(xiàn)Json序列化與反序列化的幾種方式

    C#中實(shí)現(xiàn)Json的序列化與反序列化也算是個老話題,那么在這篇文章中我們將老話重提,本文中將會學(xué)到如何使用C#,來序列化對象成為Json格式的數(shù)據(jù),以及如何反序列化Json數(shù)據(jù)到對象。有需要的朋友們可以參考借鑒,下面來跟著小編一起學(xué)習(xí)學(xué)習(xí)吧。
    2016-12-12

最新評論