C#的委託與事件搭配,便是觀察者模式的一種實現。函數
由於觀察者模式的原理很易懂,不做多講,本文純粹用於記錄語法。指針
//聲明沒有參數,沒有返回值的委託類型XXXX public delegate void XXXX();
聲明一個委託類型(相似typedef XXXX C++/C的函數類型)調試
注:不是產生一個對象。code
而後利用聲明出來的委託類型,咱們能夠利用它的對象,賦予其對應類型的函數。
從而實現出相似調用函數指針的效果。對象
//委託類型XXXX的對象 public XXXX delegateObj1; public void func1(){} public void func2(){} public void func3(int a){}
//可將某個一樣類型的函數賦給該對象 delegateObj1 = func1; //調用委託對象等同於調用它表明的函數 delegateObj1();//等價於func1(); delegateObj1 = func2; delegateObj1();//等價於func2(); delegateObj1 = func3;//類型不匹配,語法錯誤
單純用委託的話只能一對一調用(一次調用,一個函數觸發)。事件
而經過利用事件機制,咱們能夠實現一對多的調用(一次調用,多個相關事件(函數)觸發)。源碼
並且它添加/移除委託對象(至關於觀察者模式裏的觀察者)的操做十分方便,使用+=或-=便可。string
//先聲明一個委託類型 public delegate void XXXX(); //委託事件對象 public event XXXX EventObj1;//此處比通常委託多了個event
EventObj1 += func1; //添加 EventObj1 += func2; //添加 EventObj1(); //調用func1(),func2() EventObj1 -= func1; //移除 EventObj1(); //調用func2()
Action/Func主要是爲了簡化委託(delegate)語法,它們本質都是委託。io
//無返還值,不帶參數的委託對象 public delegate void XXXX(); public XXXX obj1;
在上面咱們看到委託語法,必須爲委託類型命名(聲明委託),才能使用該委託類型。event
可是使用Action/Func能夠無需聲明委託類型的語句,直接利用Action<...>/Func<...>來用本身想要的委託類型。
Action和Func的源碼底層實際也是delegate的封裝
//無返還值,不帶參數的委託對象 public Action obj3; //無返還值,帶int參數的委託對象 public Action<int> obj4; //double返還值,無參數的委託對象 public Func<double> obj5; //int返還值,帶string,double參數的委託對象 public Func<string,double,int> obj6; //將Action應用至事件 public event Action<int> EventObj1;
EventObj1 += obj4; EventObj1 += func1; EventObj1 += func2; EventObj1();//調用obj4(),func1(),func2()
Lambda表達式是用於簡便快速寫簡單函數的語法,並且這些函數每每要用於委託對象。
Lambda表達式基本形式:
(參數...) => { 函數內容... }
參數在它的類型可自動推導的狀況下,才能夠省略參數類型。若是謹慎起見,能夠不省略,從而避免隱式類型轉換。
Action obj1; obj1 = () => { Debug.Log("FGNB"); }; Action<int> obj2; obj2 = (int x) => { Debug.Log(x); }; obj2 = (x) => { Debug.Log(x+233); };//也能夠省略參數類型 Func<int,int> obj3 = (int x) => { return x; };