一、基礎定義
老王想找老張的老婆出去耍,但是一看,老張還在廚房煮飯。於是老王就對老張隔壁的淑芬說:“等下老張吃完飯出去喝茶,你就把前門曬的苞谷收了,老張從左門出,你就收右邊的苞谷,我就知道從雞舍進來。老張從右門出,你就收左牆的苞谷,我就從側屋FQ進來”。
在這個過程中,
- 事件就是:”老張吃完飯去喝茶“
- 委托就是:“把前門的苞谷收了”
- 回調函數就是:“找老張的老婆去耍”
- sender就是:老張
- 事件句柄就是: 淑芬
- EventArgs就是事件參數 : 收左邊的苞谷還是右邊的苞谷
1.聲明格式:
——用關鍵字“delegate”修飾委托
——委托的返回類型和參數要和被委托的方法保持一致例如:
public class TestClass { public delegate int delegateAction(); public event delegateAction OnActionEvent; public delegateAction daNew; }
2.委托和方法關聯
在聲明了委托和定義好方法之后,我們需要將委托和方法進行關聯,這樣委托才能知道自己要調用的是哪個方法。
//委托和方法關聯
MyDelegate my = new MyDelegate(MyClass.Method1);
3. 委托調用方法
將委托和方法進行關聯之后,我們就可以直接操作委托實例來進行方法的調用,調用方式和直接調用方法差不多。
//實例化委托的實例方法
MyClass c = new MyClass(); My my2 = new My(c.Methods);
my("Hello"); my2("Hello");
4. 效果
有了上面的使用之后,我們會發現委托基本都是根據具體方法來聲明的,如果不同的方法有3個,4個或者更多的參數,顯然,我們需要分別聲明不同參數個數的委托,不經意間多了一道“聲明委托”的門檻。於是,在.Net Framework3.5版本之后發布了.Net自帶的內置委托Action和Func。我們不用再做“聲明委托”的工作,直接可以使用。
5.Action委托
Action委托提供無參數、有參數方法,但不提供返回類型,具有Action、Action、Action<t1,t2>、Action<t1,t2,t3>……Action<t1,……t16>多達16個參數的形式,其中傳入參數均采用泛型T,涵蓋了幾乎所有可能存在的無返回值的委托類型。<t1,t2><t1,t2,t3><t1,……t16>
6.Func委托
Func委托提供無參數、有參數方法,同時提供返回類型,具有Func、Func<t,tresult>……Func<t1,t2,t3……,tresult>17種類型重載,T1……T16為參數,Tresult為返回類型。
前面我們說,Action委托和Func委托不用再聲明,便可直接使用,除了這一點,它們還支持匿名函數、lamda表達式形式。
7.Action委托與Func委托區別
看出Func與Action是類似的,唯一的區別就是,Func必須指定返回值的類型,使用方式與委托咱們自己使用委托變量是一樣的,直接使用相應參數的Func或者Action聲明變量,=或者+=掛載函數(方法即可)
這兩個其實說白了就是系統定義好的Delegate,他有很多重載的方法,便於各種應用情況下的調用。他在系統的System命名空間下,因此全局可見。
二、匿名函數
如果你沒有暈的話,再來看一下匿名委托,其實這也是一種偷懶的小伎倆而已
看代碼說話:
//F = new Func<string>(HelloWorld1);
其實也可以簡寫成這樣:
F = HelloWorld1;
//F2 = new Func<DateTime, string>(HelloWorld2);
其實也可以簡寫成這樣
F2 = HelloWorld2;
方法直接賦值給委托,這二個類型不同吧???
沒錯,你會發現編譯一樣能通過,系統在編譯時在背后自動幫我們加上了類似 “= new Func<...>”的東東,所以我們能偷懶一下下,這個就是匿名委托。
如果你細心的話,會發現我們在定義Button的Click處理事件時,通常是這樣的:
this.button1.Click += new EventHandler(button1_Click);
但有時候我們也可以寫成這樣:
this.button1.Click += button1_Click;
這其實就是匿名委托的應用.
三、lamda表達式
//使用lambda 表達式
NoParameter noParameterNew1 = new NoParameter( () => Console.WriteLine("我是:無參無返回值方法") ); Parameter parameterNew1 = new Parameter( (Para) => Para );
四、Action委托實例
Action委托和Func委托的唯一區別就是沒有返回類型,其他用法都一樣,當不需要返回類型的時候,直接用Action委托。class Program
{ static void Main(string[] args) { string mid = ",mid"; Action<string> anonDel = delegate (string param) { param += mid; param += " and this."; Console.WriteLine(param); }; anonDel += delegate (string t) { Console.WriteLine(t + System.Guid.NewGuid().ToString()); }; anonDel("www.webczw.com"); Console.ReadKey(); } }
(1)服務器對象可以提供一個方法,客戶端對象調用該方法為特定的事件注冊回調方法。當事件發生時,服務器就會調用該回調函數。通常客戶端對象實例化引用回調函數的委托,並將該委托對象作為參數傳遞。
(2)當一個窗體中的數據變化時,與其關聯的另外一個窗體中相應數據需要實時改變,可以使用委托對象調用第二個窗體中的相關方法實現。
為了實現方法的參數化,提出了委托的概念,委托是一種引用方法的類型,即委托是方法的引用,一旦為委托分配了方法,委托將與該方法具有完全相同的行為。大家在看的同時一定也要動手實踐,這樣才能把知識變成自己的體系。希望能給一些朋友捋捋思緒,形成自己的知識體系。
往期精彩:
- C#掃盲篇(一):反射機制--情真意切的說
- C#掃盲篇(二)依賴倒置•控制反轉•依賴注入•面向接口編程--滿腹經綸的說
- 利用COM組件實現對WORD書簽各種操作大全,看這一篇就夠了
- Entity Framework 更新失敗,調試后發現是AsNoTracking的原因
- “生如螻蟻,當立鴻鵠之志”|2020年終總結
首發自:【程序員不帥哥 】公眾號
原文鏈接:https://mp.weixin.qq.com/s/LCPLjBmmbJwXBDWdi3SU1g
掃碼關注,更多精彩內容及時獲取,一起提高,一起加油