委托與事件以及應(yīng)用
因?yàn)樽罱賻蓚€(gè)實(shí)習(xí)的朋友~ 他們?cè)诶斫馕羞@塊 不明白能用來(lái)做什么 對(duì)這塊理解的不好 更不用說(shuō)委托擴(kuò)展來(lái)的 拉姆達(dá)表達(dá)式 事件等了~ 但是這些很重要 在MVC EF4.1 里 都會(huì)有很多拉姆達(dá)表達(dá)式的影子 在做組件開(kāi)發(fā) 用戶控件開(kāi)發(fā) 事件的運(yùn)用 一定也是少不了的 稍微深入點(diǎn)兒的說(shuō) 用于兩個(gè)對(duì)象之間的通訊 用來(lái)解耦 用委托事件 是很不錯(cuò)的選擇 而設(shè)計(jì)模式里的觀察者模式 也是基于委托事件的應(yīng)用 還有做winform 開(kāi)發(fā)的 里的線程 WPF SL 的異步調(diào)用等 都是有這委托的影子的 所以 這個(gè)還是很重要的。也是一定要掌握的~ 希望通過(guò)這篇文章 能讓大家更加了解委托以及如何運(yùn)用~
一.委托以及延伸
先看下MSDN 的介紹吧~------ delegate
通俗的說(shuō) 委托就是可以實(shí)現(xiàn) 把方法做為變量來(lái)傳遞
1.先寫(xiě)個(gè)最簡(jiǎn)單的委托的用法
靜態(tài)的和非靜態(tài)方法的

結(jié)果會(huì)輸出
您好 wlf
Hello wlf
這是最原始的委托
2. 進(jìn)化為匿名方法
聲明完委托后 還要聲明方法 是不是很麻煩 如果不聲明方法 用匿名方法 可以幫我們 看 代碼減少了很多吧~

3.再進(jìn)化為拉姆達(dá)表達(dá)式
上面的雖然簡(jiǎn)單了不少 但是 還能更簡(jiǎn)單的 用拉姆達(dá)表達(dá)式~

看 這就是拉姆達(dá)表達(dá)式的演變 一定要會(huì)這個(gè)~ 因?yàn)樵贓F LINQ 等 有很多用拉姆達(dá)表達(dá)式的~
4.用Action 和Func繼續(xù)簡(jiǎn)化
上面的代碼以及很簡(jiǎn)單了 但是還有個(gè)很不爽的一點(diǎn)~ 要聲明委托! 可以不聲明么?當(dāng)然可以~
通俗的講 這兩個(gè)都是用來(lái)幫你聲明委托
Action 用于幫你聲明沒(méi)用返回值的委托 Func則是有返回值的 最后一個(gè)參數(shù)為返回值

看~ 以前的版本 總是要聲明一個(gè)HelloWorld 的委托 現(xiàn)在只有兩行代碼就可以了 下面順便掩飾了有返回值的 func 的例子。第一個(gè)參數(shù) 是傳遞
參數(shù)的類(lèi)型 第二個(gè)是返回值的類(lèi)型 ~ 這里說(shuō)下 這倆函數(shù)都有16個(gè)重載~ 所以多個(gè)參數(shù)是沒(méi)問(wèn)題的~
5.說(shuō)說(shuō)委托的好處
委托的好處 應(yīng)用 文章開(kāi)始已經(jīng)說(shuō)了很多了 這里就拿文章開(kāi)頭的例子 體會(huì)下委托的好處

當(dāng)我們?cè)俣嘁环N語(yǔ)言來(lái)問(wèn)好時(shí) 只需增加一種Action 即可 而不需要改動(dòng) sayHello 方法 否則 這里將充滿了 if else 的判斷
6.工作里的應(yīng)用
再 LINQ 或EF 里 都有 個(gè)很重要的 數(shù)據(jù)刷選的功能 WHERE 它的參數(shù)就是 Func 直接上代碼 自己看注釋~

看 可以很輕松的實(shí)現(xiàn) 數(shù)據(jù)過(guò)濾~ 喜歡這種函數(shù)式風(fēng)格的編程方式 我們可以點(diǎn) 順便介紹工作中的 Action

嗯 有圖有真相~ 這個(gè)ForEach 的參數(shù) 正是Action 以后遇到這幾個(gè) 新手們就不用再陌生了~

實(shí)現(xiàn)把集合里 大于4的打印出來(lái)的 這個(gè)功能 全部都是點(diǎn)兒出來(lái)的~
提示:盡量不要再ForEach 里進(jìn)行集合的操作 比如 移除集合里的元素等~ 否則會(huì)出來(lái)不希望出現(xiàn)的結(jié)果~ 出來(lái)的結(jié)果為 2 4 6

原因 反編譯 我們發(fā)現(xiàn)是 for 按索引刪除

上面的話題扯遠(yuǎn)了~ 回歸主題
二 .事件以及應(yīng)用
1.先用委托來(lái)實(shí)現(xiàn)一個(gè)常見(jiàn)的工作場(chǎng)景(委托代替事件)
webForm 用戶控件 我們?cè)趯?shí)際工作中 用的都是非常多的 說(shuō)一個(gè)場(chǎng)景 一個(gè)用戶控件 里面一個(gè)textbox 一個(gè)button 一個(gè)頁(yè)面引用了
這個(gè)用戶控件 這個(gè)頁(yè)面里有一個(gè)label 我希望 點(diǎn)擊 用戶控件里的 button改變 把 textbox 里的值 綁定到 label 上 這就是一個(gè)典型的委托事件的
應(yīng)用

1.直接上代碼 先上用戶控件的

聲明一個(gè)委托 當(dāng)點(diǎn)擊按鈕時(shí) 調(diào)用
2. 引用用戶控件的頁(yè)的代碼

當(dāng)然 我們會(huì)了拉姆達(dá)表達(dá)式 完全可以寫(xiě)成

這里主要說(shuō)的是 委托的注冊(cè) 記得要寫(xiě)到 !IsPostBack 外面
大概順序是這樣的 先執(zhí)行 用戶控件的外部變量賦值 => 再執(zhí)行父頁(yè)面的用外部變量賦值(本例子中沒(méi)有)=> 再執(zhí)行父頁(yè)面的pageload=>用戶控件的pageload
如果不寫(xiě)到 !IsPostBack 外面 點(diǎn)擊按鈕后 先執(zhí)行 用戶控件的外部變量賦值(以前被賦值的委托會(huì)又為空,所以這時(shí)需要在頁(yè)面pageload 里 重新注冊(cè) 而不能寫(xiě)到!IsPostBack) 里面~
3 只用委托的缺點(diǎn)
功能雖然實(shí)現(xiàn)了 但是我們想 我們可以在 父頁(yè)面 給 Puchange.onChangevent 賦值為null 或者篡改為別的 而我希望我們?cè)谝脮r(shí) 只能添加 或移除 這樣就更
完美了 所以 事件就出來(lái)了~
2.使用事件重新實(shí)現(xiàn)上面的代碼
1.用戶控件里的

2.父頁(yè)面

3.winform 或Silverlight 里盡量使用委托和事件 來(lái)通訊
這樣可以更好的降低耦合 避免了 子窗體中出現(xiàn)父窗體對(duì)象 降低耦合
三.委托的其他資料
四.總結(jié)
文章比較入門(mén) 希望新手能對(duì)委托事件有更好的了解 平且能把委托擴(kuò)展來(lái)的東西 熟練運(yùn)用到工作中 來(lái)簡(jiǎn)化代碼~ 并且能把事件熟練運(yùn)用~文章的目的也達(dá)到了
浙公網(wǎng)安備 33010602011771號(hào)