C# 學習筆記 運算式 與 陳述式 Lambda

一起加入C#的世界吧,這次介紹的是陳述式 Lambda 以及 運算式 Lambda。

開始前你得先知道...

委派是一種可以安全封裝方法的類型,他類似C、C++的函式指標(function pointer),但委派是一個安全的物件導向類型,這個就是他與C、C++函式指標不同的地方。
匿名方法在 C# 2.0 時引進,他是一個將程式區塊當作委派參數傳遞的一種方式,因為匿名方式不需要再分別建立方法,所以可以減少實作委派時另外需要撰寫的程式碼。

想要更了解匿名方法委派的朋友們可以到官方文件詳細了解他們。

Note:另外還有兩種委派分別為 Func<T,...>Action<T,...> ,簡單來說 Func 有回傳值,而 Action 沒有,詳細可以去官方文件觀看,也可以到這篇部落格文章瞭解哦~

Lambda 是在 C# 3.0 時出現的
在 C# 3.0 之後的版本,Lambda 運算式成為了撰寫內嵌程式碼的首選而非匿名方法。

微軟官方定義 Lambda 的文件如下

Lambda 運算式是匿名函式,可用來建立委派運算式樹狀架構類型。 使用 Lambda 運算式可以撰寫區域函式,這些函式可以當做引數傳遞,或是當做函式呼叫的值傳回。

若要建立 Lambda 運算式,請在 Lambda 運算子 => 的左邊指定輸入參數 (如果有的話),並將運算式或陳述式區塊放在另一邊。例如,Lambda 運算式 x => x * x 會指定名為 x 的參數,並傳回 x 的平方值。

Note : Lambda 中的參數,在外部是無法使用(看見)的。 ex: x => x * x 其中的 x 參數是在外部無法使用(看見)的,在使用完畢時該參數 x 就會被進行記憶體回收。

以下是 在官方文件中提到的 Lambda 一般規則:

  • Lambda 必須包含與委派類型相同數目的參數。

  • Lambda 中的每個輸入參數都必須能夠隱含轉換為其對應的委派參數。

  • Lambda 的傳回值 (如果有的話) 必須能夠隱含轉換為委派的傳回類型。

運算式 Lambda (Expression Lambda)

運算式 Lambda 的基本形式如下

(input parameters) => expression

以下的Code是修改自MSDN中的範例,新增匿名方法做展示匿名方法語 Lambda 的不同

delegate int del(int i);
static void Main(string[] args)
{
    int j;
    //Lambda方法
    del expressionLambda = x => x * x;
    j = expressionLambda(5); //j = 25  
    Console.Write(j);

    //匿名方法
    del anonymousMethod = delegate (int x)
    {
        return x * x;
    };
    j = anonymousMethod(5);
    Console.Write(j); //j still 25 
}

其運算式 Lambda 常見的寫法有以下四種

//這個方式是利用編譯器進行型別推斷,讓我們可以省去寫傳入參數型別的寫法
(x, y) => x + y;

//有時候編譯器會無法判斷輸入類型,所以出現這種情況時,就需要明確的指定類型
(int x, string s) => s.Length > x;

//只有一個傳入參數時,可以省去括號
x => x * x

//在不需要傳入參數時必須以空括號來表示
() => "S" + "Q" + "Z";

陳述式 Lambda(Expression Lambda)

陳述式 Lambda 的基本形式如下

(input parameters) => { statement; }

在此可以發現陳述式 Lambda 其實與 運算式 Lambda 十分相像,其不同之處在於陳述式必須包含於大括號之內,知道匿名方法的人也會發現他與匿名方法的差別僅在於將 delegate 關鍵字變更為「=>」運算子而已。

為了讓各位快速理解他們的差異性在哪所以一樣用 Code 來展示 陳述式 Lambda 與 匿名方法

delegate int del(int i);
static void Main(string[] args)
{
    int j;
    //Lambda方法
    del statementLambda = x =>
    {
        x = x + 2;
        return x * x; //j =49
    };
    j = statementLambda(5);
    Console.Write(j);

    //匿名方法
    del anonymousMethod = delegate(int x)
    {
        x = x + 2;
        return x * x;
    };
    j = anonymousMethod(5);
    Console.Write(j); //j still 49
}

今天介紹到這裡,感謝收看,若內容有誤,麻煩各位大大通知我 <(_ _)>