Lambda Expression 的學習筆記

上課筆記:C# Advanced Topics: Take Your C# Skills to the Next Level

Lambda Expression

  • It is an anonymous method (匿名函式).
    • No access modifier
    • No name
    • No return statement

情境一:經驗值加倍

Normal case

現在我們有一個 劍士,再開啟經驗值加倍後,可以獲得多少經驗值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Warrior
{
private int _exp;

public int Exp
{
get { return this._exp; }
set { this._exp += value; }
}
}

internal class Program
{
private static void Main(string[] args)
{
var character = new Warrior();

var rewardExp = 100;
character.Exp = DoubleExp(rewardExp);
Console.WriteLine(
$@"獲得 100 經驗值後,目前角色有{character.Exp}。");
}

private static int DoubleExp(int exp)
{
return exp * 2;
}
}

Lambda expression

那我們可以怎麼用 Lambda 來表示? 在 MSDN 中有提到:

「若要建立 Lambda 運算式,請在 Lambda 運算子 => 的左邊指定輸入參數 (如果有的話),並將運算式或陳述式區塊放在另一邊。」

白話一點,就是「 args => expression 」,課程中有說明你可以這樣念「 args goes to expression」。

那我們該怎麼使用這個 Lambda expression ? 我們搭配 delegate 來完成情境

  • Func
    • 輸入參數可以從 無參數 到 十六個參數
    • return value
  • Action
    • 輸入參數可以從 無參數 到 十六個參數
    • return void

那麼我們在這個情境中,我們需要的是 Func

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
internal class Program
{
private static void Main(string[] args)
{
var character = new Warrior();

var rewardExp = 100;

//character.Exp = DoubleExp(rewardExp);
Func<int, int> doubleExp = exp => exp * 2;
character.Exp = doubleExp(rewardExp);

Console.WriteLine(
$@"獲得 100 經驗值後,目前角色有{character.Exp}。");
}
}

透過 ReSharper 我們可以將多餘的方法移除。
(方法名稱反灰,代表它是 Unused 的)

那如果是沒有參數的話,就這樣表示就好:()=> expression

那多個參數,就是:(x, y)=> expression

情境二:在包包找物品

現在我們有一個 劍士,包包內有一堆東西,我要找出物品的稀有度是 3 的物品,準備要把它們賣掉。

Normal case

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
internal class Program
{
private static void Main(string[] args)
{
var character = new Warrior();

var findTooCommonItem =
character.Backpack.FindAll(IsRarityLessThenFour);
Console.WriteLine();
foreach (var item in findTooCommonItem)
{
Console.WriteLine(
$@"名稱:{item.Name},稀有度:{item.Rarity}");
Console.WriteLine("");
}
}

private static bool IsRarityLessThenFour(Item item)
{
return item.Rarity < 4;
}
}

我們看一下 List.Find 方法 (Predicate) from MSDN.aspx) 中的說明:

  • Predicate of T 它其實是 delegate method,這個 method 會判斷 List of T 中的 element 是否有符合條件的,如果是,就回傳該 element。
  • 而在 List of T 的 Find method 中,它會找到第一個符合條件的 element。

ok! 了解了什麼是 Predicate 之後,那我們還可以怎麼修改,讓它變成 Lambda expression ~

Lambda expression

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
internal class Program
{
private static void Main(string[] args)
{
var character = new Warrior();

// 我們可以這樣解讀:我要在 character 的 背包裡面,
// 找尋所有 「物品」的稀有度 是在 4 以下的。
var findTooCommonItem =
character.Backpack.FindAll(item => item.Rarity < 4);

Console.WriteLine();
foreach (var item in findTooCommonItem)
{
Console.WriteLine(
$@"名稱:{item.Name},稀有度:{item.Rarity}");
Console.WriteLine("");
}
}
}

看,精簡了許多。

See also