事件的理解:
在skyline項目的開發中,遇到了一個新的知識:事件。
在程序中,我希望實現一個功能,當視點坐標移動的時候可以實時的得到視點的坐標。這里就需要使用事件這個概念:當坐標發生移動,則觸發了一個特定的事件,他可以發出一個信號,而用戶可以自定義一個函數(參數必須與事件委托的參數相同,這個后面解釋),當他發出一個信號,我就可以執行這個函數。
比方說:甲和乙是朋友,上午見面了,乙和甲說,今天中午吃完飯叫我一聲,我帶你去網吧玩。
在這個情景中,甲吃飯這件事情是乙沒有辦法控制的。他只可以等甲吃完飯以后發一個信號,才可以做帶甲去網版的這個方法。當然乙可以蹲在甲的家門口一直看着甲,等甲吃完飯然后就可以帶他去網吧,但是這樣的話,是不是很浪費乙的時間呢。
同樣的,skyline的項目中,我們也可以做一個無限的循環,隨時記錄這視點坐標的參數,然后在循環的下一次得到視點坐標參數再和剛剛那一次做比較,如果不同的話就執行希望運行的那個函數。而這樣的話對於程序來說會形成一個死循環,是沒有意義的。
下面寫一個小程序來具體化一下這個甲和乙的小故事:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Sample001 { public delegate void InformHandle(object sender); public class JIA { public event InformHandle EatOver; public void eat() { Console.WriteLine("吃飯中......"); System.Threading.Thread.Sleep(2000); //吃飯事件兩秒 OnEating(); //這個相當於是一個信號,當運行這個函數的時候會發出一個信號。 } public virtual void OnEating() { if (EatOver != null) { EatOver(this); } } } public class YI { public void TakeJiaToWangBa(object sender) { Console.WriteLine("帶"+sender.ToString()+"去網吧!"); } } class Program { static void Main(string[] args) { JIA jia1 = new JIA(); YI yi1 = new YI(); jia1.EatOver += new InformHandle(yi1.TakeJiaToWangBa); Console.WriteLine("空閑中"); Console.WriteLine("現在甲不知道在干什么"); jia1.eat(); Console.WriteLine("去了網吧通宵一個晚上到了第二天中午"); jia1.eat(); Console.ReadKey(); } } }
運行結果如圖:
這個代碼的意義在於說明,乙的TakeJiaToWangBa的方法只會在甲吃完飯這個事件發生的時候才會執行。當我們在Main方法中寫入了
jia1.EatOver += new InformHandle(yi1.TakeJiaToWangBa);
這行語句,就表名了:當甲觸發了EatOver事件的時候,就會發出一個信號,然后乙就開始執行TakeJiaToWangBa這個函數了。在后面的代碼中我們就不必去關心什么時候執行TakeJiaToWangBa方法了。
還有一個問題就是甲是如何觸發EatOver這個事件的呢,就是靠下面的這個代碼來完成,甲在運行eat方法的時候,會執行OnEating方法。我對下面這段代碼的原理也不是很理解。
public virtual void OnEating() { if (EatOver != null) { EatOver(this); } }
從功能上來說,當執行OnEatring方法時,就已經觸發了EatOver事件。EatOver(this)的信號就已經發出去了。而且這個信號中還包含着一個參數(這個實例本身)。如果別人希望當觸發這個事件之后運行自己希望運行的代碼的話,就需要定義一個方法,這個方法也必須有一個與這個事件相同類型的參數(在這段代碼中,他們的類型都是object),用戶定義的這個方法在運行的時候就可以訪問這個參數了。
這個參數的類型又是又什么決定的呢?是由委托來決定的!
public delegate void InformHandle(object sender);
感覺說的不是很清楚,大概意思就是這樣了,等我徹底搞清之后再對本文進行一下修改。如果大家對本文有什么疑問,或者想指點一下我的話可以發評論,我每天都會看的。謝謝啦!