lamda表達式有了參數捕獲這個功能,讓Action這個委托變得無所不能。Action委托就是無參數,無返回值的一個代理類型。
它只能對應於下面這種類型的函數聲明。
public void Function() { //Do something }
public void Function2() { //Do something }
public void Function3() { //Do something }
假設我們定義一個共通的執行函數
public void Execute(Action action) { try { action.Invoke(); } catch (Exception ex) { //Log Debug.WriteLine(ex); } finally { } }
那么,調用上面的三個函數,就是這個樣子。
Execute(Function);
Execute(Function2);
Execute(Function3);
這么做的好處是,可以將一些共通的處理,例如異常捕獲等放到Execute函數里,而其他的被調用函數不用寫這部分代碼。
但是這樣會引申出一個問題,我們的函數不可能都是些無返回值,無參數的函數,例如:
public bool Edit(Account account) { bool result = false; //Todo result = true; return result; }
那么上面的Excute函數就不適用了,難道我們又要定義一個類似於下面這樣的委托嗎?
public delegate bool EditDelegate(Account accout);
在項目中往往有很多的函數原型,如何一一這樣聲明,早就累死了。能不能有一種共通的方式來統一處理所有的函數呢?
Lamda的參數捕獲出場了。看看下面這段代碼:
Account account = new Account(); AccountService accountService = new AccountService(); bool result = false; Execute(() => { result = accountService.Edit(account); });
我們依然共用了我們先前定義的Exeute函數,但卻調用一個有參數,有返回值的函數。這要全歸功於Lamda表達式,主要有以下兩點:
1,()=>{} 這句Lamda表達式代表了一個無參數,無返回值的委托,也就是和Action委托簽名一致,Execute函數也就能調用。
2,這一點最關鍵,result和account是在Lamda表達式外部定義的變量,被Lamda表達式捕獲,作為參數傳遞和返回值使用。並且,Lamda表達式和外部變量是同步的,也就是Lamda的返回值會改變result的值。這一點當時我也沒有想明白,按理說result是bool型,是一個值類型,應該是按值傳遞的,結果不會被改變。但是Lamda表達式對於所有捕獲的外部變量,都是按引用傳遞的,這一點要謹記!也正是有了這個特點,讓我們可以在Lamda表達式的內部利用參數捕獲的這個特性來調用任意的函數。而Lamda本身只要和Action委托一致就行了。
我只能說,這個功能真是太酷了。如果你用的好,就可以大大的簡化編程。