2012年6月27日 星期三

[轉貼] C# Delegate/event 的簡單理解

看這篇前可以先看這篇文章瞭解Delegate的語法與使用方式
本篇原文=================
簡單來說就是增加一層間接層來實現晚綁定,從而獲得更為鬆散的耦合

為什麼要有Delegate? 
假設有兩個不同類實現的對象A和B,A和B分別有方法a和b。現在需要a方法以一觸發,便執行對象B的方法b。 不使用delegate,我們可以在設計A類的時候在將B類作為參數傳入a方法,這樣可以實現我們的要求。但是這樣做有明顯的缺陷:   
    1. 我們需要事先知道B類。   
    2. 如果還存在C類、D類等的方法需要一併執行,這樣必須重新修改A類的代碼。 如果有了  Delegate,我們可以事先設計一個函數指針,這樣當對象A執行a方法的時候,就可以根據該指針指向的,符合該函數指針法則的方法進行執行。這樣,我們就不需要在設計A類的時候知道B類,只需要知道B的b方法的參數和返回值就可以了。如果還有C類、D類方法需要一併執行,也可以添加到該指針指向的數據結構中。


示例代碼分析:
代碼
    class Program
{
static void Main(string[] args)
{
A a
= new A();
B b
= new B(a);
a.Method_A();
}
}


class A
{
public delegate void Delegate_A();
public event Delegate_A da;
public void Method_A()
{
da();
}
}

class B
{
public B(A a)
{
a.da
+= new A.Delegate_A(Method_B);
}
public void Method_B()
{
Console.WriteLine(
"B's method!");
}
}
1. 先看Class A中   
public delegate void Delegate_A(); 這個語句規定了函數指針指向的函數應該符合的規範:沒有返回值,沒有參數傳入。
2. 接著實例化了一個 Delegate_A的對象da,這裡使用event關鍵字表明它是一個事件。 
3. 再看Class B的的構造函數,可見B構造時,往對象a的事件中傳入了Method_B的函數地址(a.da += new A.Delegate_A(Method_B)
4. 在Main函數中執行A對象的Method_A時,觸發了事件da,而da指向了B的方法。這樣即便A對象對B對象一無所知,也同樣能執行B的方法Method_B。這就是Delegate的好處。

Event有什麼用:
實際上在上例中將Event關鍵字刪除程序同樣能執行。之所以要加上Event,是因為在程序編譯時,加上Event以後該Delegate的對象會成為該類的私有成員,這樣外界只能通過 += 和 -=來對Delegate的對象da進行操作,而不能直接進行賦值。

沒有留言:

張貼留言