1. 程式人生 > >C# 委託,匿名方法,lambda表示式使用方法

C# 委託,匿名方法,lambda表示式使用方法

在 2.0 之前的 C# 版本中,宣告委託的唯一方法是使用命名方法。 C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表示式取代了匿名方法,作為編寫內聯程式碼的首選方式。 有一種情況下,匿名方法提供了 Lambda 表示式中所沒有的功能。 您可使用匿名方法來忽略引數列表。 這意味著匿名方法可轉換為具有各種簽名的委託。 這對於 Lambda 表示式來說是不可能的。 有關 lambda 表示式的更多特定資訊,請參見 Lambda 表示式(C# 程式設計指南)

委託:

delegate int calculator(int x, int y); //委託型別
static void Main() { calculator cal = new calculator(Adding); int He = cal(1, 1); Console.Write(He); } /// <summary> /// 加法 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public static int
Adding(int x, int y) { return x + y; }

匿名方法:

 delegate int calculator(int x, int y); //委託
 static void Main()
 {
     calculator cal = delegate(int num1,int num2)
     {
         return num1 + num2;
     };
     int he = cal(1, 1);
     Console.Write(he);
 }

lambda表示式:

delegate int calculator(int
x, int y); //委託型別 static void Main() { calculator cal = (x, y) => x + y;//Lambda表示式,大家發現沒有,程式碼一個比一個簡潔 int he = cal(1, 1); Console.Write(he); }

下列規則適用於 Lambda 表示式中的變數範圍:

捕獲的變數將不會被作為垃圾回收,直至引用變數的委託超出範圍為止。

在外部方法中看不到 Lambda 表示式內引入的變數。

Lambda 表示式無法從封閉方法中直接捕獲 ref 或 out 引數。

Lambda 表示式中的返回語句不會導致封閉方法返回。

Lambda 表示式不能包含其目標位於所包含匿名函式主體外部或內部的 goto 語句、break 語句或 continue 語句。

Lambda表示式的本質是“匿名方法”,即當編譯我們的程式程式碼時,“編譯器”會自動將“Lambda表示式”轉換為“匿名方法”,如下例:


string[] names={"agen","balen","coure","apple"};
string[] findNameA=Array.FindAll<string>(names,delegate(string v){return v.StartsWith("a");});
string[] findNameB=Array.FindAll<string>(names,v=>v.StartsWith("a"));

上面中兩個FindAll方法的反編譯程式碼如下:

string[]findNameA=Array.FindAll<string>(names,delegate(stringv){returnv.StartsWith("a");});
string[]findNameB=Array.FindAll<string>(names,delegate(stringv){returnv.StartsWith("a");});

Lambda表示式的語法格式:

引數列表 => 語句或語句塊 其中“引數列”中可包含任意個引數(與委託對應),如果引數列中有0個或1個以上引數,則必須使用括號括住引數列,如下:

  1. () => Console.Write(“0個引數”)
  2. I => Console.Write(“1個引數時引數列中可省略括號,值為:{0}”,i)
  3. (x,y) => Console.Write(“包含2個引數,值為:{0}*{1}”,x,y)

而“語句或語句塊”中如果只有一條語句,則可以不用大括號括住否則必須使用,如下:

  1. I => Console.Write(“只有一條語句”)
  2. I => { Console.Write(“使用大括號的表示式”); }
  3. I => { i++;Console.Write(“兩條語句的情況”); } //兩條語句時必須要大括號

如果“語句或語句塊”有返回值時,如果只有一條語句則可以不輸寫“return”語句,編譯器會自動處理,否則必須加上。

“Lambda表示式”是委託的實現方法,所以必須遵循以下規則: 1)“Lambda表示式”的引數數量必須和“委託”的引數數量相同; 2)如果“委託”的引數中包括有ref或out修飾符,則“Lambda表示式”的引數列中也必須包括有修飾符;