国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

.Net邊學邊講(三)

2019-11-18 20:40:42
字體:
供稿:網(wǎng)友
談到event,就不能不先說一下callback和delegate
如果你使用過C的話,你應該知道有一個函數(shù)叫qsort,是用來給數(shù)組排序的。但這個函數(shù)顯然不能承擔廣泛意義上的比較,因此你需要傳遞一個指針,他指向具有比較功能的函數(shù)。qsort在每次要比較數(shù)組元素時都要調(diào)用這個函數(shù)。這就是callback的概念,在.Net里也可以實現(xiàn)回調(diào),方法是創(chuàng)建一個接口,實現(xiàn)他,傳遞一個實現(xiàn)此接口的對象的引用。delegate呢,你可以將他理解成一個安全的函數(shù)指針。
Notifications跟callback有點類似,但比簡單的回調(diào)要復雜的多。callback意味著要調(diào)用的callback方法被調(diào)用的同時要調(diào)用的建立callback的方法。這是一個很緊密的耦合。而Notification則要松散一些,你可以注冊將來某段時間會或者不會發(fā)生的Notification,只當他們發(fā)生時處理,否則不用。
你也許想讓你寫的組件當一些事情發(fā)生時通知其他組件,例如,你想寫一個按鈕組件,當你Click的時候你可能想通知其他組件,而其他組件將不得不準備向你請求Notification,你就要提供一個方法告訴他們你已經(jīng)有一個可用的Notification。另一方面,你可能也是當其它組件的一些事情發(fā)生時希望被通知的人。這時你就需要找到那個特定組件可以提供什么Notification。
在.Net中event是一個你用來廣播、引發(fā)、處理Notification的機制。大致是這樣的,可以引發(fā)事件的組件聲明這一事件。而希望處理某一特定組件的某一特定事件的組件通過傳遞一個方法的delegate向引發(fā)事件的組件注冊。這樣,當事件發(fā)生時引發(fā)事件的組件就會調(diào)用每個已注冊的方法。通過delegate和event我們可以實現(xiàn)異步調(diào)用的功能。在C#中是這樣聲明一個代理的:public delegate void LogHandler(String message);代理在處理這種回調(diào)時已經(jīng)是很強大了。但是當我們需要代理被存儲以便以后的Notification,就有一點麻煩了。比如說我們有一個對象Button,有一個Click事件。我們可以聲明一個ClickHandler 的代理類型用于處理Click事件,在我們的Button的Class中聲明一個ClickHandler的public實例,這樣其他組件希望Click發(fā)生時被通知,就可以簡單的把他的代理加到Click代理中去。myButton.Click += new ClickHandler(MyMethod);
看上去著好像沒什么問題。但是這里卻存在一個大問題,我們聲明Click代理是public,這違反了我們以前說過的data fields永遠不要聲明成public,這會有一系列麻煩。解決的辦法是聲明成PRivate或protected,然后用屬性解決讀寫。這樣我們可以private聲明Click,在寫一對public方法去增加一個listener及減少一個listener。當然在.Net中,當你聲明一個event時,.Net已經(jīng)為你做好這一切了。聲明一個事件:
class AlarmTimer {
public event EventHandler Alarm;
// ...
}
這段代碼說明AlarmTimer可以向所有其它對象廣播它可以引發(fā)一個叫Alarm的事件。Alarm事件用的是EventHandler代理類型。EventHandler:無返回值、接受兩個參數(shù)(Object:指向事件的發(fā)送者,EventArgs:包含關于事件的數(shù)據(jù))
看一個例子:
class AlarmTimer {
public event EventHandler Alarm;
private Timer myTimer;
public AlarmTimer() {
myTimer = new Timer();
myTimer.Tick += new EventHandler(OnTick);
}
public void Set(Double seconds) {
myTimer.Interval = (Int32)(seconds * 1000);
myTimer.Start();
}
protected void OnTick(Object sender, EventArgs e) {
myTimer.Stop();
if (Alarm != null) Alarm(this, EventArgs.Empty);
}
public void ReEnable() {
myTimer.Enabled = true;
}
}
注意AlarmTimer既引發(fā)事件(Alarm)又處理事件(Timer中的Tick事件)
static AlarmTimer myAlarm = new AlarmTimer();
public static void TestEvent() {
myAlarm.Alarm += new EventHandler(TimerEventProcessor);
myAlarm.Set(2);
Console.WriteLine("Timer is set; alarm will go off in two seconds");
application.Run();
}
//處理事件
private static void TimerEventProcessor(
Object myObject, EventArgs myEventArgs) {
if (MessageBox.Show("Wake up! Continue ringing?",
"Count is: " + alarmCounter,
MessageBox.YesNo) == DialogResult.Yes) {
alarmCounter += 1;
myAlarm.ReEnable();
}
else {
Application.Exit();
}
}
注意:Object和EventArgs不是必需的參數(shù),只是這是一個好的寫法模式而已
關于event還有好多沒有說,留著以后慢慢說吧。



發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 明溪县| 开平市| 松江区| 获嘉县| 海门市| 军事| 东源县| 肇庆市| 毕节市| 平罗县| 东丰县| 辉县市| 姜堰市| 海盐县| 信阳市| 呼玛县| 吴忠市| 芦溪县| 浙江省| 泸溪县| 唐山市| 津市市| 东至县| 裕民县| 镶黄旗| 昌邑市| 四川省| 昂仁县| 志丹县| 基隆市| 恭城| 泾源县| 孟津县| 临安市| 澜沧| 尼木县| 淳安县| 库伦旗| 闵行区| 阳曲县| 黔西|