一、基礎定義
老王想找老張的老婆出去耍,但是一看,老張還在廚房煮飯。於是老王就對老張隔壁的淑芬說:“等下老張吃完飯出去喝茶,你就把前門曬的苞谷收了,老張從左門出,你就收右邊的苞谷,我就知道從雞舍進來。老張從右門出,你就收左牆的苞谷,我就從側屋翻牆進來”。
在這個過程中,
- 事件就是:”老張吃完飯去喝茶“
- 委託就是:“把前門的苞谷收了”
- 回撥函式就是:“找老張的老婆去耍”
- 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
掃碼關注,更多精彩內容及時獲取,一起提高,一起加油