委託與事件簡介
轉載於:點選開啟連結 (http://www.cnblogs.com/wangjiming/p/8300103.html)
本篇文章主要採用理論和程式碼例項相結合方式來論述委託和事件,涉及到一些邊界技術,如軟體架構的OCP原則(開-閉原則),
軟體架構解耦,設計模式(Sender-Order)和事件驅動模型,有一定難度和深度,不適合初級者。
第一部份 委託
關於委託內容,主要圍繞下圖來論述。
一 委託是什麼(what)
(一)委託產生的背景之一
1.我們先來假設這樣一個情景需求:
設計一個系統,使其滿足如下條件:
(1)當前,只有中國人和英國人使用該系統;
(2)向系統輸入使用者名稱和相應的語言,將產生相應語言的問候語;
(3)後期,可能會有其他國家語言加入該系統(系統變化的部分) ;
2.技術方案實現
關於技術方案實現,我們可以採用下圖中的三種方式之一。
為了更好地敘述委託,我們分別實現三種技術方案,並找出它們的關係。
2.1 一般實現
Code(控制檯程式)
View CodeResult
分析
2.2用介面實現
如上,我們分析了方案一中的問題,為了更好地解決方案一存在的問題,我們採用面向介面程式設計的形式來實現。
2.2.1 什麼是面向介面程式設計?
面向介面程式設計,主要是解決軟體架構設計中“動靜問題”,即封裝不變(靜),剝離變化(抽出變化)。
Code:
View Coderesult
分析:
(1)如上,我們將變化因子"語言"剝離出來,形成介面,以後只要每增加一個語言,只需實現介面即可,滿足了OCP原則,基本解決了方案一中存在的問題;
(2)如上程式碼只是為了演示面向介面程式設計這個功能,並不完善,感興趣的讀者,可自行完善(如將語言定義為列舉型別等);
方案二中的程式碼,細心的讀者會發現,Main方法中new了三個物件,假若以後系統有300門語言,那豈不New 300個類,這樣的話,也不利於程式碼維護呀,怎麼解決這個問題呢?(提示一下,採用設計模式抽象工廠即可解決該問題)
2.3 用委託實現
在這裡,沒接觸過委託的讀者,先跳過這部分,往下讀,看完(三)怎樣使用委託(How to use)後,再來看本部分。
Code
View CodeResult
2.3 分析上述三種實現方案的關係
通過上訴三種方式的比較,我們容易得出委託的如下結論:
(1)抽象方法,遮蔽方法細節,呼叫只需傳遞方法名字即可;
(2)能夠實現程式的解耦,鬆耦合(在方案一中,GetGreetingContens方法體內new了GreetToUsers物件,強耦合)
(3)委託一般扮演中間者的角色,這功能在委託事件中體現非常明顯(第二部分 事件 將詳細論述)
如我們在租房子時,可以直接找房東(技術實現的一般方法,強耦合,讓租房者和房東直接聯絡),也可找中介(技術實現的委託,鬆耦合,租房者通過中介來與房東聯絡)
2.4 委託背景概述
委託的重要產生背景,就是事件驅動模型(關於什麼是事件和事件驅動,在本文第二部份 事件 論述)。
(二) 委託定義
用delegate關鍵字定義委託(注意,委託是沒有方法體的,類似接口裡面的方法),在定義委託前,必須明確兩個問題:
1.委託將要繫結的方法;
2.委託的形參型別,形參個數和委託的返回值必須與將要繫結的方法的形參型別,形參個數和返回值一致;
(三)相關概念
委託涉及的相關概念有函式指標,型別安全性、事件、Lambda表示式等
1.函式指標:在C++中,指標的一個類別,主要指向函式(變數指標,主要指向變數地址),可以把C#中的委託理解為函式指標;
2.型別安全性:在C++中,我們都知道指標是型別不安全的(返回值,返回型別和什麼時候返回,這些都是未知的),而委託是型別安全的;
3.事件:可以把事件理解為委託的一種特例(在本文第二部份 事件 論述)
4.Lambda表示式:委託與Lambd表示式相結合,實現高效程式設計,與Jquery的“較少程式碼做更多的事”類似,委託與Lambda,Linq相結合,使較短程式碼就能實現比較複雜的功能(在本篇文章中不講解Lambda與Lambda樹,將在後續文章中講解)
(四)委託組成
大致分為兩部分:宣告委託和註冊方法(也叫繫結方法)
1.宣告委託
用delegate宣告;
2.繫結方法
繫結具體方法,傳遞方法名稱;
(五) 委託種類
委託種類,一般分為多播委託和單播委託
1.單播委託:繫結單個方法
2.繫結多個方法
(六) 委託操作
1.繫結方法
2.解綁方法
二 委託能解決什麼問題(Can do)
1.避免核心方法中存在大量的if....else....語句(或swich開關語句);
2.滿足程式設計的OCP原則;
3.使程式具有擴充套件性;
4.繫結事件;
5.結合Lambda表示式,簡化程式碼,高效程式設計;
6.實現程式的鬆耦合(解耦),這個在事件(event)中體現比較明顯;
三 怎麼使用委託(How to use)(本篇文章不談匿名委託,匿名委託具體內容,將在Lambda章節講解)
(一)委託的基本構成
通常地,使用委託的步驟與使用類的步驟是一樣的。大致分為兩步:定義委託和繫結方法(傳遞方法)
1.定義委託
用delegate關鍵字定義委託(注意,委託是沒有方法體的,類似接口裡面的方法),在定義委託前,必須明確兩個問題:
(1).委託將要繫結的方法;
(2).委託的形參型別,形參個數和委託的返回值必須與將要繫結的方法的形參型別,形參個數和返回值一致;
public delegate 委託返回型別 委託名(形參)
例子:如上我們委託將要表示系統輸出的問候語
a.委託將要繫結的方法
public string ChinesePeople(string UserName) { string GreetContents = "您好!" + UserName; return GreetContents; } //English People public string EnglishPeople(string UserName) { string GreetContents = "Hello," + UserName + "!"; return GreetContents; } //非英非漢 public string OtherPeople(string UserName) { return "Sorrry,當前系統只支援漢語與英語"; }
b.由如上方法可看出,方法的返回型別為string,方法有一個string型別的形參,在定義委託時,與其保持一致即可
//定義委託 public delegate string DelegateGetGreeting(string UserName);
2.繫結方法
使用委託時,將方法名字作為引數傳遞給委託即可
1 GreetToUsers greetToUsers = new GreetToUsers(); 2 GetGreetingContents(UserName, greetToUsers.ChinesePeople)
(二)委託繫結方法
1.繫結單個方法
繫結單個方法,將單個方法名字傳給委託即可
View Code另一種不太規範寫法:不用GetGreetingContents(string UserName,DelegateGetGreeting delegateGetGreeting)方法
View Code之所以不規範,主要是在專案中,不利於程式碼的模組化。
2.繫結多個方法(多播委託)
注意:繫結多個方法時,委託範圍型別必須為void型別,否則只返回最後一個繫結的值。
繫結多個方法,採用 += 繫結
View Code3.解綁方法
解載繫結的方法,採用 -= 解綁
View Code(三)委託機制
將如下程式碼通過反彙編工具.NET Reflector反彙編
View Code反彙編
分析:
1.三個核心方法:BeginInvoke,EndInvoke和Invoke
(1)使用Invoke完成一個委託方法的封送,就類似於使用SendMessage方法來給介面執行緒傳送訊息,是一個同步方法。也就是說在Invoke封送的方法被執行完畢前,Invoke方法不會返回,從而呼叫者執行緒將被阻塞。
(2使用BeginInvoke方法封送一個委託方法,類似於使用PostMessage進行通訊,這是一個非同步方法。也就是該方法封送完畢後馬上返回,不會等待委託方法的執行結束,呼叫者執行緒將不會被阻塞。但是呼叫者也
可以使用EndInvoke方法或者其它類似WaitHandle機制等待非同步操作的完成。
總結:但是在內部實現上,Invoke和BeginInvoke都是用了PostMessage方法,從而避免了SendMessage帶來的問題。而Invoke方法的同步阻塞是靠WaitHandle機制來完成的。
提示:
最近瀏覽一篇文章,也講得不錯:http://blog.csdn.net/goodshot/article/details/6157529
要想深入瞭解,請參照《CLR Via C#》,
第二部分 事件
關於事件(event),將會從如下四個角度來分析.
1.什麼是事件
2.事件能解決什麼問題
3.怎麼使用事件
4.事件機制
一 什麼是事件
談到委託,必提事件,事件本質是對委託的封裝,對外提供add_EventName(對應+=)和remove_EventName(對應-=)訪問,從而實現類的封裝性。
1.種類
強型別事件和弱型別事件
2.一些用處
(1)WebForm控制元件的Click事件。做過WebForm開發的朋友,可能對事件是非常熟悉的,如拖一個Button,雙擊,就自動在後臺生成Button的Click事件,如下圖所示。
原理:在Windows運用程式中,Button類提供了Click事件,其本質就是委託,當我們觸發Click事件時,呼叫的處理程式方法需要引數,其引數就是由委託型別來定義的。
(2)設計模式釋出/訂閱。事件是基於委託的,為委託提供了一種釋出/訂閱機制。
二 事件能解決哪些問題
1.將公有的委託變數定義為私有變數,從而滿足類的封裝性原則;
2.具有委託具有的作用;
三 如何使用事件
1.宣告委託
public delegate void DelegateGetGreeting(string UserName);
2.宣告事件
與委託宣告一樣,只不過多了一個關鍵字event
public event DelegateGetGreeting EventGreet;
3.時間註冊方法
事件註冊方法與委託註冊方法是一樣的。
1 DelegateGreet DG= new DelegateGreet(); 2 //DG.delegateGetGreeting = GTU.ChinesePeople;//註冊方法 3 DG.EventGreet+= GTU.ChinesePeople; 4 DG.EventGreet += GTU.EnglishPeople;
4.呼叫事件
呼叫定義事件的方法
DG.GreetUser("小王");
完整程式碼如下:
View Code四 事件機制
事件的本質就是委託,向外提供兩個訪問方法add_EventName(對應+=)和remove-EventName(對應-=),我們通過.NET Reflector反彙編工具來檢視,到底是不是這樣的。
相關推薦
委託與事件簡介
轉載於:點選開啟連結 (http://www.cnblogs.com/wangjiming/p/8300103.html)本篇文章主要採用理論和程式碼例項相結合方式來論述委託和事件,涉及到一些邊界技術,如軟體架構的OCP原則(開-閉原則),軟體架構解耦,設計模式(Sender
C#委託與事件學習筆記
委託事件學習筆記 本文是學習委託和事件的筆記,水平有限,如有錯漏之處,還望大神不吝賜教。 什麼是委託?從字面意思來解釋,就是把一個動作交給別人去執行。在實際開發中最常用的就是使一個方法可以當做一個引數傳遞,以便在方法中可以根據實際情況實現不同的功能。 什麼是事件?事件就是發生的事情,例如點選了一
Unity之C#——委託與事件,觀察者模式,貓和老鼠事例
委託與事件,觀察者模式,貓和老鼠事例 在Unity遊戲開發中,我們經常需要在一個類中,呼叫另一個類中的方法,比如,當玩家進入到某個地方,敵人就開始攻擊玩家。這時就需要利用委託與事件,設計觀察者模式。 此處我們利用貓和老鼠來簡單描述: 程式碼如下: Ca
委託與事件聯合使用
1、建立委託 /// <summary> /// 顧客走進飯店 /// 把選單給顧客 /// </summary> /// <param name="cusobj">顧客<
C#中委託與事件的學習小結(一)
最近又學習了一些C#的小知識點,在此釋出部落格記錄一下。 一、委託 C#中的委託的關鍵字是delegate,我們可以使用委託型別來將已有的方法例項化出來,也可以將我們自己定義的方法作為引數來傳遞。 例如: private delegate string GetAStri
基礎知識篇:委託與事件
委託是對函式的封裝,可以當做給方法的特徵指定一個名稱。而事件則是委託的一種特殊形式,當發生有意義的事的時候,事件物件 處理通知過程。 注意 1.委託是一種引用方法的型別。一旦為委託分配了方法,委託就與該方法具有完全相同的行為。 2.事件是在發生其它類或物件關注的事情的時
C#委託與事件之----委託
C#委託與事件之委託 整理了一下委託的幾種使用方法,都在程式碼裡面了 using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst
基於委託與事件的有限狀態機設計與實現(Unity3d)
有限狀態機設計與實現 前言 最近看到一句話,就是優秀是一種習慣,所以突然就總想寫點什麼,當作是遊戲開發這條路上的學習筆記吧,另外也時刻提醒自己需要不斷努力。 什麼是狀態機? 先貼百度百科的概念內容吧: 有限狀態機,(英語:Finite-state machine
菜鳥教程C#高階教程部分理解(一)委託與事件
委託與事件 委託 Delegate 所有的委託(Delegate)都派生自 System.Delegate 類。 定義一個委託,該委託可用於引用帶有完全相同引數和返回型別的方法。 委託的多播(也叫組播、委託鏈):一個委託變數可以同時繫結多個方法,每一個委託(
大白話系列之C#委託與事件講解(一)
從序言中,大家應該對委託和事件的重要性有點了解了吧,雖然說我們現在還是能模糊,但是從我的大白話系列中,我會把這些概念說的通俗易懂的。首先,我們還是先說說委託吧,從字面上理解,只要是中國人應該都知道這個意思,除非委託2箇中文字不認識,舉個例子,小明委託小張去買車票。 &nbs
大白話系列之C#委託與事件講解大結局
今天是大白話系列之C#委託與事件講解的大結局,也是我們最關心的,在日常的MES系統程式設計中到底怎樣使用這樣的利器,其實我們每天都在使用事件,一個窗體,一個按鈕都包含這事件,只是很少用到自己寫的委託和事件,說白了不知道如何下手,也不知道在什麼樣的場景下應用。 用到事件的地方有很多,這次講解就ME
大白話系列之C#委託與事件講解(二)
什麼是事件?EVENT?點選事件?載入事件?一連串的模糊的概念衝擊著我們弱小的腦袋 那我們首先來看一下比較正統的感念吧: 事件是類在發生其關注的事情時用來提供通知的一種方式。 事件的發生一般都牽扯2個角色 事件發行者(Publisher):一個事件的發行者,也稱作是傳送者(sende
C#的委託與事件
c#委託與事件 引言 委託 和 事件在 .Net Framework中的應用非常廣泛,然而,較好地理解委託和事件對很多接觸C#時間不長的人來說並不容易。它們就像是一道檻兒,過了這個檻的人,覺得真是太容易了,而沒有過去的人每次見到委託和事件就覺得心裡別(biè)得慌,混身不自在。本文中,我
對委託與事件的深入理解
一、委託的理解 委託是一種型別(與列舉是一樣的):特殊的地方是它指向一個方法 二、委託的使用場景:將一個方法抽象出來作為引數傳遞 class Program { static void Main(string[] args) { //MyDelegate md = (s) => {
多播委託與觀察者模式聯合使用,以及委託與事件的區別
首先我們先看一下多播委託: 使用委託時,首先我們宣告委託,委託語法一共有四種類型,分別時有參,無參,以及有無引數返回值。 1 public class DelegateShow //: System.MulticastDelegate,多播委託 2 { 3 public del
委託與事件(1)
原創連結 網上講C#委託和事件的博文已經非常多了,其中也不乏一些深入淺出、條理清晰的文章。我之所以還是繼續寫,主要是藉機整理學習筆記、歸納總結從而理解更透徹,當然能夠以自己的理解和思路給其他人講明白更好。 另
通過委託與事件監聽狀態改變來更新UI
該博文涵蓋的知識點 1. C# 委託 2. 如何利用委託監聽事件以此更新顯示 所要完成目標 我們剛開始做好的部分UI介面如下圖所示: 觀察左邊的紅色方框,我們先做了例項的姓名,頭像,slider,和Label等,在運行遊戲時候需要更新相應的屬性。 在下面的指令碼中,我們分
詳解Unity中的委託與事件
回到目錄 0x00 前言 由於工作繁忙所以距離上一篇部落格已經過去一個多月的時間了,因此決心這個週末無論如何也得寫點東西出來,既是總結也是分享。那麼本文主要的內容集中在了委託的使用以及內部結構(當然還有事件了,但是受制於篇幅故分為兩篇文章)以及結合一部分Unity3D的設計思考。當然由於時間倉促,文中難免
CSharp學習筆記之十二 委託與事件(續)
尼瑪,當把剛才的文章給儲存發表之後,想看看其他方面你的文章,這時候又看到了另外的一個比較不錯的文章,名字與本題同名,正覺得納悶呢,仔細一看,原來是同一作者的東西,頓時有一種被騙的感覺。這些都不重要,真心的不重要,重要的是這些東西我們都能夠學到比較多的東西。所以,這裡就又將那
快速理解C#中的委託與事件
以下內容只是個人理解,僅供參考。 什麼是委託? 先看最簡單的委託例子: namespace DelegateTest { public delegate void MessageDelegate(string name); class Program