委托幹的活,大緻上就是C中函數指針忙活的東西,但使用起來比函數指針更安全和系統。
這裡先推薦一個大神寫的介紹委托的部落格。波哥2010大白話委托
寫的特好,透徹清晰。
本文一部分是從網上找到的資源,為了今後友善回顧,特地整合在本篇部落格。
下面先簡單介紹下委托
委托就是對一個方法映射,把方法名當參數來傳遞,類似JS中的在某個function的參數中把另一個function的名稱當參數來傳遞。
//定義委托原型
delegate void UpdateHandler(int id);
//定義符合委托原型的方法UpdateMember
void UpdateMember(int id)
{
//更新使用者邏輯
}
//定義符合委托原型的方法DeleteMember
void DeleteMember(int id)
{
//删除使用者邏輯
}
如何使用呢,如下:
//執行個體化委托對象,在構造函數中把方法名當參數來傳遞。指定了當執行委托時候實際工作的方法
UpdateHandler handler = new UpdateHandler(UpdateMember);
//執行委托對象
handler(某個使用者id); //id這個參數會傳遞給實際工作的方法,在事件+委托中,規範的參數是sender和e
handler(某個使用者id)就等價于
UpdateMember(某個使用者id)
也可以連接配接多個相同簽名的方法,組成一個委托鍊,當調用委托對象時,鍊上的方法,按映射的順序一次被執行。
如何使用呢,如下:
UpdateHandler handler = new UpdateHandler(UpdateMember);
handler += DeleteMember;
handler(某個使用者id);
handler(某個使用者id)就等價于
UpdateMember(某個使用者id)
DeleteMember(某個使用者id)
事件的話,看看設計模式中的觀察者模式。
被觀察對象中維護了一個觀察者清單,這些觀察者會對被觀察者某個“動作”,即事件,做出各自不同的反映。
常見的例子如下:
某一場景下有主人,貓,狗3個對象。
當主人“打開門”後,貓“跑開了”,狗“叫了”。
整個過程中,主人就是被觀察對象,貓和狗都是觀察者。
一旦主人觸發“打開門”這個事件的話,貓狗做出不同的反映,貓“跑開了”,狗“叫了”。
代碼如下:
public class Host
{
//定義委托原型
public delegate void OpenDoorEventHandler();
//定義委托類型的事件
public event GoHomeEventHandler OpenDoor;
//定義内部一個方法,在這個方法内判斷,OpenDoor事件是否被其他對象注冊,一旦注冊了,則調用執行事件。
protected void OnOpenDoor()
{
if(OpenDoor!=null)
{
OpenDoor();
}
}
public void GoHome()
{
OnOpenDoor();
}
}
public class Cat
{
public void Run()
{
//貓跑了
}
}
public class Dog
{
public void Bark()
{
//狗叫了
}
}
如何使用如下:
Host 主人 =new Host();
Cat 貓 = new Cat();
Dog 狗 = new Dog();
主人.OpenDoor += new 主人.OpenDoorEventHandler(貓.Run);
主人.OpenDoor += new 主人.OpenDoorEventHandler(狗.Back);
主人.GoHome就等價于
貓.Run();
狗.Back();
當被觀察者,做出某一特定“動作”(被觀察者的特定“動作”,注冊了N個不同對象的不同反映),觀察者對這個特定“動作”做出不懂的反映。
為什麼要使用委托
至于為什麼要使用委托呢,因為解耦。試想如果不使用委托,為了達到同樣的目的,必然要将被觀察者和觀察者寫到同一個類中,兩者高度耦合。
委托的好處很多,不一而足:
一 你可以先看設計模式裡的觀察者模式,在沒有委托這個模式的還是存在觀察者和被觀察者之間的耦合,而委托可以是兩者更大的解除耦合。在面向對象程式設計能接觸耦合就是最大的好處,委托也可以說是觀察者模式,這個模式的好處也可以說是委托的好處,它能使一個對象狀态的改變立即通知其他對象,而這個對象和其它的對象是完全分離的,就是互相不知道對方的存在,這樣在程式規模變大的情況下更加容易維護(每一個對象的修改不涉及另一個對象),更加容易擴充(理由同上),也更加靈活。一句話就是達到解耦的目的。
二 得益于解耦,使用委托使程式員可以将方法引用封裝在委托對象内,将所引用方法傳遞給調用委托對象的代碼,而不必在編譯時知道将調用哪個方法。與C或C++中的函數指針不同,委托是面向對象,而且是類型安全的。
把方法作為參數/屬性來指派或傳遞,事件是委托的一種具體應用,委托可以了解為一種接口,具體的方法實作這個接口,在開發階段隻需要關心委托的定義就可以調用,而不用關心它如何實作的或者在哪裡實作的。
三 在用線程的時候 直接調用方法或者改變控件的話會出錯,但是用委托就可以解決錯誤,可以實作異步更新.
通常使用的場合包括 設計一個通用的控件 等。