小光跟著大頭從最基礎的基本語法學習到方法以及物件導向,那接下來要怎麼讓開發的速度更快更便捷呢,所以大家就接下來看看本篇文章吧。
「前輩,除了物件導向之外還有甚麼方法可以讓開發速度變快的阿。」
小光一早就興沖沖的跑來跟大頭請教關於開發的方法,但是大頭今天似乎桌上的需求文件堆得異常的高,不過大頭過了幾分鐘後就抬起頭來回應小光的問題。
「其實除了物件導向之外還有另外一個函式語言程式設計的方法,他的做法更簡單不會處理到物件之間的關係,所以有另一個面向的加快開發速度的方法。」
聽到又有新的東西可以學讓小光的眼睛一整個亮了起來,看到小光的表情後大頭繼續慢慢的說下去。
「這個函式語言程式設計的概念跟昨天學的物件導向的概念不同的地方是在函式內沒有狀態與資料的概念,所以對於處理方法時只有輸入跟輸出而已,而且輸入的內容相同時輸出的內容也會一致。」
講到了這邊,大頭拿個水杯喝了一大口水,並接著繼續講下去。
「提到C#對於函式語言程式設計的開發方式就不能不提到C#的委派了,所以接下來我先說明一下如何使用委派。」
昨天提到的ReferenceType除了class之外還有另一個就是delegate,所謂的delegate簡單說明就是宣告一個特定輸入的參數以及返還的結果,然後接下來用這個delegate宣告的變數就可以承接與此delegate簽章相符以及返還值相同的方法,並且在方法中使用,所以實際的例子可以看以下範例。
// 宣告一個委派
public delegate void DoSomethingDelegate(string message);
// 實作
public void Print(string message)
{
Console.WriteLine(message);
}
// 宣告個變數放實作的方法
DoSomethingDelegate handler = Print;
// 呼叫執行該變數
handler("Hello World!");
好的,上述例子就是簡單的委派宣告到使用,除了可以如此使用之外剛剛提到委派是個ReferenceType的變數,因此他也可以當作一個變數傳到方法內,所以大家再看看下列例子。
// 接續上面例子
public void Add(int a, int b, DoSomethingDelegate handle)
{
handle($"result: {a + b}");
}
雖然委派好用不過要先宣告一個型別很麻煩而且很累贅,所以在後續又有Action、func、Predicate的產生,所以接下來依序說明。
Action其實只是簡化委派的寫法而已,因為對委派來說Action只是不須特別宣告只要透過泛型方法來定義輸入參數,而且沒有返還值的delegate
,接下來來看一下Action的範例。
public void Add(int a, int b, Action<string> handle)
{
handle($"result: {a + b}");
}
不過問題來了,如果說還需要返還值的delegate
該怎麼辦呢,請看下列Func
。
看完Action
如果說我們的方法需要一個返還值該如何處理呢,這時候就需要Func
出馬了,先說明一下Func
跟Action
不同的是其泛型的最後一個參數是返還值,所以接下來我們看看Func
的例子。
public int Add(int a, int b)
{
return a + b;
}
public int Operator(int a, int b, Func<int, int, int> handle)
{
return handle(a, b);
}
public void DoSomeThing()
{
var a = 1;
var b = 2;
var c = Operator(a, b, Add);
}
好了,到這邊關於delegate
已經說明的差不多了,接下來說明一個弱化版的delegate
。
接下來要說明的是Predicate
,這個是輸入一個參數然後只有一個返還的布林值,所以先看看下列的範例。
public void Check(int a, Predicate<int> handle)
{
if (handle(a))
{
// Do someting
}
}
相信大家看到這個範例一定會覺得這Predicate
好難用,不過其實這個最常用,只是大家都沒有發現到,晚一點的時候在跟大家說明。所以除了上述的delegate
之外接下來會說明匿名的delegate
前面都說明完delegate
的功用,剩下的只是如何宣告的差別而已了,接下來要說明的就是匿名的delegate
的寫法,請大家看一下下列範例。
// Lambda (intput) => function
Func<int, int, int> multi = (a, b) => a * b;
var a = 2;
var b = 3;
var c = multi(a, b);
看到這裡讀者們應該會覺得奇怪為什麼要提到Lambda
,他跟delegate
好像沒關係,因為接下來要說明一個跟delegate
沒有直接關係但是會很常用到的東西。
「前輩我常常聽到Linq
,究竟這個是什麼。」
在聽完大頭介紹完Lambda
所提到的東西引起小光的注意。
「Linq我同常都會拿維基百科的語言整合查詢來說明,舉個例子就是說將SQL的表達式用在C#的資料結構上,不過我們習慣的是寫API的寫法而不是SQL語法,可以參考一下Linq的說明。」
聽完大頭這樣說明小光一副似懂非懂的樣子,所以大頭就在補充說明。
「試著想看看如果說你要在整數序列中找到大於10的整數,你是不是腦袋中浮現foreach
」
小光聽到大頭的題目後思考了一下就點點頭表示同意,看到小光同意的表現大頭繼續說下去。
「不過除了foreach
的方式還有下面的寫法讓你參考一下。」
var list = new List<int> {1,12,39,58,76,1,3,7};
var moreThanTen = list.Where(x => x > 10);
「哇,這樣寫真的好簡潔啊」
看到小光欽佩的眼神大頭得意的點點頭並接續說下去。
「剛剛Where
中接的參數就是剛剛說到的Predicate
,然後方法的部分則是剛剛講的Lambda
,所以是不是剛剛說的都用到了。」
「前輩,我頭又開始暈了」
在說明完delegate
跟Linq
之後小光對大頭這麼說。
「沒關係,頭暈是正常的,因為我也曾經暈過,不過這個你會常常練習到所以不用怕。」
所以小光的這一天就在委派跟Linq
度過了。