程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> [C# 3.0 入門] [第一章 Lambda表達式] 第五節

[C# 3.0 入門] [第一章 Lambda表達式] 第五節

編輯:關於C#

[C# 3.0 入門] [第一章 Lambda表達式] 第五節:Lambda表達式的使用范例 & Lambda表達式的各種變體

Lambda表達式的使用范例

到現在為止的例子大多數,完全都是從文法上到功能上的說明,多數情況下不必使用Lambda表達式也能夠寫出來。最後,我還是來展示幾個有一定實用性的Lambda表達式的實例。

這裡是一個,輸入整形的數組,以其值為除數,執行除法運算後輸出結果的程序。因為要執行除法運算,所以輸入的值可能存在不能接受的值(0)的情況(就是說,這個示例代碼可以在輸入值不正確的情況下也能正常工作)。

那麼,這個程序的輸入如果是0的情況下,就提示信息然後必須退出。這個意圖如果用Lambda表達式該怎麼寫呢?

這個問題的要點有兩個。

l 在執行計算的循環中檢查0值的話,計算開始後會發生中斷。就是說,可能會同時計算值與錯誤信息兩者都輸出。

l 如果不輸出計算值只輸出錯誤信息的話,最好在計算的循環之前在設置一個檢查0值的循環。但是,這樣寫的話就用了兩個循環太冗長了。

總之,兩個方法都有缺點。換做筆者,如果有“計算開始前應該先檢查完畢”的要求,去除繁冗更重要,所以更願意選擇在循環內判定。

1using System;
2
3class Program
4{
5  static void Main(string[] args)
6  {
7    int[] a = { 1, 2, 0 };
8
9    foreach (int n in a)
10    {
11      if ( n == 0 )
12      {
13        Console.WriteLine("數組裡面含有0。");
14        return;
15      }
16      Console.WriteLine(100 / n);
17    }
18    // 輸出:
19    // 100
20    // 50
21    // 數組裡面含有0。
22  }
23}
24
25

List18 循環內判定的情況

然而,如果使用Lambda表達式,就會有一種完全不同的答案。要判斷所有數組的元素是否都滿足一定的條件,只需用一個調用一個方法的Lambda表達式,事情就有著落了。在不損失可讀性的范圍內,把Lambda表達式寫進if語句的條件中就能輕松的實現了。

實際寫出來的例子如下。Any方法是,集合的元素中只要含有一個滿足參數的Lambda表達式的元素就返回true。這個用到了.NET Framework的擴展方法,為了能夠使用,要在代碼前面加上“using System.Linq;”。

1using System;
2using System.Linq; // 為了使用Any方法
3
4class Program
5{
6  static void Main(string[] args)
7  {
8    int[] a = { 1, 2, 0 };
9
10    if (a.Any(x => x == 0))
11    {
12      Console.WriteLine("數組中含有0");
13      return;
14    }
15    foreach (int n in a) Console.WriteLine(100 / n);
16  }
17  // 輸出:數組中含有0。
18}
19

List19 使用Lambda表達式在計算之前就檢驗0值

如果是不能使用.Net Framework 3.5的場合,List19的if語句就要寫成下面的形式(稍稍有些冗長),這樣在.NET Framework 2.0下也同樣能夠使用。

if (Array.FindIndex(a, x => x == 0) >= 0)

這個例子,用Lambda表達式對集合數據的處理,感覺就像對單個值進行判斷的“if ( n == 0 )”一樣,對集合使用“if (a.Any(x => x == 0))”就能夠處理。

總之吧,使用循環的方法對集合元素進行判斷處理的方法,用僅僅一句if就能給替換了。如果經常使用這種技術,代碼的結構也會更明快簡潔。

【短評】“=>”是不等號?

BASIC系的語言中,不等號的寫法,“=”與“>”的順序沒有明確的規定。這樣的語言中,“>=”“=>”是等價的。正因為如此,熟悉了這樣的語言的話“=>運算符”就很容易會被誤認為是不等號。

例如如果有下面的Lambda表達式,如果是有上述語言的使用經驗的人看來,很容易就認為是不等號了。

x => 0

但是,使用Visual Basic的IDE的程序員,幾乎就不會看見作為不等號的“=>”。因為在IDE中輸入“=>”時,當場就會被自動替換為“>=”(Visual Basic 6.0與Visual Studio 2008會要求確認)

所以綜合起來考慮,如果是使用會把“=>”與不等號搞混的編程語言,那最好就要養成良好的編程習慣。

Lambda表達式的各種變體

Lambda表達式有各種變體。特別是在參數只有一個的情況下,因為在語法上可以省略參數兩邊的括弧,全面把握起來會比較困難。所以,下面的代碼給出幾種主流的變體的寫法。

1using System;
2
3delegate int NoArg();
4delegate int OneArg(int onlyOne);
5delegate int TowArgs(int first, int second);
6delegate void NoRetVal ();
7
8class Program
9{
10  static void Main(string[] args)
11  {
12   NoArg    sample1 = () => 0;
13   OneArg   sample2 = (x) => x * 2;
14   OneArg   sample3 = (int x) => x * 2;
15   OneArg   sample4 = x => x * 2;
16   TowArgs  sample5 = (x, y) => x * y;
17   TowArgs  sample6 = (int x, int y) => x * y;
18   OneArg   sample7 = (x) => { return x * 2; };
19   OneArg   sample8 = (int x) => { return x * 2; };
20   NoRetVal sample9 = () => Console.WriteLine("Hello!");
21  }
22}
23

List20 Lambda表達式的各種變體

sample1 = () => 0

在寫沒有參數的Lambda表達式的時候,要寫上沒有參數的空的括號。

sample2 = (x) => x * 2

有參數的情況下,用括號把參數表括上是最基本的寫法。

sample3 = (int x) => x * 2

當然,如果能夠明確指定參數的類型更好。

sample4 = x => x * 2

僅當參數只有一個的時候,參數兩邊的括弧可以省略。

sample5 = (x, y) => x * y

參數有多個的時候,用逗號分隔

sample6 = (int x, int y) => x * y

參數有多個的時候,也可以指定類型

sample7 = (x) => { return x * 2; }

Lambda語句的例子

sample8 = (int x) => { return x * 2; }

Lambda語中也可以指定類型

sample9 = () => Console.WriteLine("Hello!")

沒有返回值的情況,寫成調用void型返回值的方法的形式。

下期預告

介紹到這裡,Lambda表達式的大部分內容已經介紹過了。僅僅運用本章的知識,就能夠使代碼發生很大的質的變化了。

然而,如果說要完全理解了Lambda表達式的話,僅僅這樣的話還為時尚早。

實際上,推斷被省略了的類型聲明的“類型推斷”的麻煩事還在後頭呢。下一章,就來說說類型推斷。同時,也將會討論一下使用Lambda表達式的代理類型在類庫中的使用方法。例如,本章中的例子裡就用到了Action類型和Func類型。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved