天天看點

深入了解C#中的委托

委托幹的活,大緻上就是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++中的函數指針不同,委托是面向對象,而且是類型安全的。

把方法作為參數/屬性來指派或傳遞,事件是委托的一種具體應用,委托可以了解為一種接口,具體的方法實作這個接口,在開發階段隻需要關心委托的定義就可以調用,而不用關心它如何實作的或者在哪裡實作的。

三 在用線程的時候 直接調用方法或者改變控件的話會出錯,但是用委托就可以解決錯誤,可以實作異步更新.

通常使用的場合包括 設計一個通用的控件 等。

c#