/*事件*/
public delegate void timeeventhandler(string s);//委託宣告
class mytime}}
class processtime
! the time is now", s, datetime.now);}}
class testtime
}/*委託*/
delegate void timedelegate(string s);//委託宣告
class mytime
! the time is now", s, datetime.now);
}public static void goodbyetime(string s)
! the time is now", s, datetime.now);
}public void saytime(string s)
! the time is now", s, datetime.now);}}
class testdelegate
}一、委託
委託類似於函式指標,但函式指標只能引用靜態方法,而委託既能引用靜態方法,也能引用例項方法。
委託使用分三步:1、委託宣告。2、委託例項化。3、委託呼叫。
例程一:
using system;
namespace 委託
private int add(int num1,int num2)}}
例中,委託numope引用了方法add。
委託宣告了以後,就可以象類一樣進行例項化,例項化時把要引用的方法(如:add)做為引數,這樣
委託和方法就關聯了起來,就可以用委託來引用方法了。
委託和所引用的方法必須保持一致:
1、引數個數、型別、順序必須完全一致。
2、返回值必須一致。
二、事件
事件有很多,比如說滑鼠的事件:mousermove,mouserdown等,鍵盤的事件:keyup,keydown,keypress
有事件,就會有對事件進行處理的方法,而事件和處理方法之間是怎麼聯絡起來的呢?委託就是他們中
間的橋梁,事件發生時,委託會知道,然後將事件傳遞給處理方法,處理方法進行相應處理。
比如在winform中最常見的是按鈕的click事件,它是這樣委託的:this.button1.click += new
system.eventhandler(this.button1_click);按按鈕後就會出發button1_click方法進行處理。
eventhandler就是系統類庫里已經宣告的乙個委託。
三、自定義事件及其處理
eventhandler以及其它自定義的事件委託都是一類特殊的委託,他們有相同的形式:
delegate void 事件委託名(object sender,eventargs e);
object用來傳遞事件的發生者,比如二中的button控制項就是乙個事件發生者;eventargs用來傳遞事件
的細節。
例程二:
using system;
namespace 最簡單的自定義事件}}
}///
/// 事件接收類
///
class class2
private static void c1_onuserrequest(object sender, eventargs e)}}
例程三:
using system;
namespace 帶事件資料的事件
set}
}///
/// 事件傳送類
///
class class1}}
}///
/// 事件接收類
///
class class2
private static void c1_onuserrequest(object sender, onuserrequesteventargs e)}}
例程三跟例程二唯一的差別在於自定義了乙個類onuserrequesteventargs,從eventargs繼承。
女兒想吃棒冰了,但又不想自己頂著太陽出去買(買棒冰是乙個method),所以她叫他倒霉的老爸去買
(delegate),最後女兒吃到了棒冰。
這就是乙個委託的過程。
接下去,讓我們看看一些對委託的解釋:
委託是用來處理其他語言(如 c++、pascal 和 modula)需用函式指標來處理的情況的。不過與 c++
函式指標不同,委託是完全面對物件的;另外,c++ 指標僅指向成員函式,而委託同時封裝了物件例項
和方法。
委託例項的乙個有趣且有用的屬性是:它不知道也不關心它所封裝的方法所屬的類;它所關心的僅限於
這些方法必須與委託的型別相容(第 15.1 節)。這使委託非常適合於「匿名」呼叫。——《c#語言規
範》scott wiltamuth 和 anders hejlsberg
這些解釋看起來都是比較艱澀難懂的,讓我們用乙個例子來充分理解乙個簡單的委託吧。
首先,建立乙個father類,擁有2個shared方法(c#為static,即靜態方法):
opentv
buytoys
天下的所有父親都有幫女兒開電視和買玩具的義務,哈哈
public class father
public shared sub opentv(byval msg as string)
console.writeline("mission:" & msg)
console.writeline("mission is completed!")
end sub
public shared sub buytoys(byval msg as string)
console.writeline("mission:" & msg)
console.writeline("mission is completed!")
end sub
end class
值得注意的是,這2個方法都有乙個string的引數,等會兒定義委託的時候也需要相似的引數,這個後
面再講。
然後我們要建立委託。需要注意的是,委託是個類,我們要和對待其他類一樣對待他,建立委託需要2
道手續:
1,定義乙個delegate類,這個類應當與你想要傳遞的方法具有相同的引數和返回值型別。
對應上面的說明,我們建立的類如下:
public delegate sub delegatebyfather(byval msg as string)
c#**:
public delegate void delegatebyfather(string msg);
2,生成乙個delegate物件,並將你想要傳遞的方法作為引數傳入(就是把你想讓這個委託做的事情傳
遞進取)。
對應上門的說明,我們建立的物件如下:
dim mydelegate as delegatebyfather
mydelegate = new delegatebyfather(addressof father.buytoys)
c#**:
delegatebyfather mydelegate;
mydelegate=new delegatebyfather(father.buytoys);
這2行**我們可以理解成:女兒和老爸簽訂了乙個委託協議(xx條約?),協議的內容是,老爸去做
buytoys這件事情。
然後,女兒就可以通過mydelegate這個委託的物件(xx條約),來給老爸發號施令了,**如下:
mydelegate.invoke("buy many toys!")
老爸去買玩具吧!
這裡我們顯式呼叫了delegate類的invoke方法,我們也可以隱式呼叫:
mydelegate("buy many toys!")
隱式呼叫看上去就像是乙個函式,其實,編譯器會在il**中自動加上invoke的。
至於c#,只能使用隱式呼叫,用顯式會報錯,c#**如下:
mydelegate("buy many toys!")
這樣,乙個簡單的委託過程就結束了,讓我們貼一下完整的主程式吧:
module module1
sub main()
dim mydelegate as delegatebyfather
mydelegate = new delegatebyfather(addressof father.buytoys)
mydelegate.invoke("buy many toys!")
end sub
public delegate sub delegatebyfather(byval msg as string)
end module
執行的結果如下:
mission:buy many toys!
mission is completed!
事件與委託例項
委託的語法和方法比較相似,只是比方法多了乙個關鍵字delegate 我們都知道方法就是將型別引數化,所謂的型別引數化就是說該方法接受乙個引數,而該引數是某種型別的引數,比如int string等等 而委託是將方 法引數化,說了上面的那個型別引數化之後,相信你也能猜到方法引數化的意思了,對,就是將方法...
委託與事件(淺度分析) 委託
前言 對於委託和事件,初次接觸是在 大話設計模式 這本書中,但是裡面只是說明了一下委託和事件是如何使用的,並沒有詳細的講解委託和事件是什麼,所以不甚理解。因為不清楚委託和事件,所以每次想到它心裡就很不舒服,總有乙個解不開的結。現在對於它們稍微理解了一點兒,心裡的石頭也可以暫時放一放了。委託由來 先說...
委託例項(delegate例項 事件委託通知)
delegate例項 delegate是c 中的一種型別,它實際上是乙個能夠持有對某個方法的引用的類。與其它的類不同,delegate類能夠擁有乙個簽名 signature 並且它只能持有與它的簽名相匹配的方法的引用。它所實現的功能與c c 中的函式指標十分相似。它允許你傳遞乙個類a的方法m 給另乙...