Lamda表達式的參數捕獲,太酷了


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委托一致就行了。

我只能說,這個功能真是太酷了。如果你用的好,就可以大大的簡化編程。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM