2009-11-23 21 views

回答

7

這是一個暴露事件的類的簡單實現。

public class ChangeNotifier 
{ 
    // Local data 
    private int num; 

    // Ctor to assign data 
    public ChangeNotifier(int number) { this.num = number; } 

    // The event that can be subscribed to 
    public event EventHandler NumberChanged; 

    public int Number 
    { 
     get { return this.num; } 
     set 
     { 
      // If the value has changed... 
      if (this.num != value) 
      { 
       // Assign the new value to private storage 
       this.num = value; 

       // And raise the event 
       if (this.NumberChanged != null) 
        this.NumberChanged(this, EventArgs.Empty); 
      } 
     } 
    } 
} 

這個類可以使用類似如下:

public void SomeMethod() 
{ 
    ChangeNotifier notifier = new ChangeNotifier(10); 

    // Subscribe to the event and output the number when it fires. 
    notifier.NumberChanged += (s, e) => Console.Writeline(notifier.Number.ToString()); 

    notifier.Number = 10; // Does nothing, this is the same value 
    notifier.Number = 20; // Outputs "20" because the event is raised and the lambda runs. 
} 

關於控制流程中,執行流入SomeMethod()。我們創建一個新的ChangeNotifier,從而調用它的構造函數。這會將10的值分配給私人num成員。

然後,我們使用+=語法訂閱事件。這個操作符在右邊接受一個委託(在我們的例子中,這個委託是一個lambda),並將它添加到事件上的委託集合中。此操作不會執行我們在ChangeNotifier中編寫的任何代碼。如果您願意,可以通過該事件的addremove方法進行定製,但很少需要這樣做。

然後我們對Number屬性執行一些簡單的操作。首先我們分配10,它在Number屬性上運行set方法,value = 10。但num成員的價值已經爲10,所以最初的條件評估爲假,沒有任何反應。

然後我們用20做同樣的事情。這一次的價值是不同的,所以我們將新值分配給num並且觸發事件。首先我們驗證事件不是null。如果沒有訂閱它,它是空的。如果它不爲空(例如訂閱它),我們使用標準方法/委託語法來啓動它。我們只是用事件的參數來調用事件。這將調用訂閱了該事件的所有方法,包括將執行Console.WriteLine()的lambda。


亨裏克已經成功nitpicked存在,如果一個線程可以在Number的制定者,而另一個線程正在退訂的聽衆的潛在的競爭條件。我不認爲有人常見的情況下,誰還不明白事件是如何工作的,但如果你擔心這種可能性,修改這些行:

if (this.NumberChanged != null) 
    this.NumberChanged(this, EventArgs.Empty); 

是這樣的:

var tmp = this.NumberChanged; 
if (tmp != null) 
    tmp(this, EventArgs.Empty); 
+1

謝謝格雷格。我期待着這樣的答案。 – Babu

+1

!= null --line上的競爭條件,因爲NumberChanged可以被另一個線程取消訂閱,如果你有更多的話。 – Henrik

+1

+1爲所有信息。對不起,我是軟件開發新手,但是如何編輯3行與上面的2行代碼不同,後面3行代碼中的「this」是指什麼以及它如何解決線程問題?請你能詳細說明一下嗎?謝謝! –

0

如果您有C背景,您可以將委託視爲指向函數的指針。

+1

代表將不會是一個問題。但瞭解事件對我來說是真正的問題。 – Babu

+0

問題是關於事件。 – nawfal

2
class Program 
    { 
     static void Main(string[] args) 
     { 
      Parent p = new Parent(); 
     } 
    } 

    //////////////////////////////////////////// 

    public delegate void DelegateName(string data); 

    class Child 
    { 
     public event DelegateName delegateName; 

     public void call() 
     { 
      delegateName("Narottam"); 
     } 
    } 

    /////////////////////////////////////////// 

    class Parent 
    { 
     public Parent() 
     { 
      Child c = new Child(); 
      c.delegateName += new DelegateName(print); 
      //or like this 
      //c.delegateName += print; 
      c.call(); 
     } 

     public void print(string name) 
     { 
      Console.WriteLine("yes we got the name : " + name); 
     } 
    } 
1
Class A { 
    public delegate void EventHandler(); 

    public static event EventHandler workComplete(); 

    void doWork(){ 
     // DO WORK 
    } 

    void onWorkComplete(){ 
     // Raise event 
     workComplete(); 
    } 
} 

Class Main { 
    A a = new A(); 
    a.workComplete += new() -> { 
     // On Class Complete Work 
     Console.WriteLine("Work Complete"); 
    }; 
}