2013-02-16 26 views
1

有代碼示例關於關於C#中的書事件一章中:與事件一起工作。從局部變量提高

class CountDown 
{ 
    private uint _seconds; 
    public CountDown(uint seconds) 
    { 
     _seconds = seconds; 
    } 
    public void Start() 
    { 
     new Thread(() => 
     { 
      uint n = _seconds; 
      while (n > 0u) 
      { 
       var tick = Tick;    ///?????? 
       if (tick != null) 
        tick(n); 

       Thread.Sleep(1000); 
       n--; 
      } 
      var finished = Finished;   ///?????? 
      if (finished != null) 
       finished(); 
     }).Start(); 
    } 
} 
    public event Action<uint> Tick; 
    public event Action Finished; 

什麼是創建活動的本地副本的理由(勾選和成品),並通過提高它的事件嗎?這是常見的做法,有一些意義?我嘗試過,但無法從書中找到它。

回答

3

什麼是創建事件(打勾和完成)的本地副本並通過它提出事件的原因是什麼?

它避免了Tick成爲空的無效支票,但之前呼叫的可能性。如果您有:

if (Tick != null) 
{ 
    Tick(n); 
} 

...並最終聽者是退訂,當你已經陷入「如果」的身體,你會得到一個NullReferenceException

+0

事件的行爲就像一個值類型,因爲新的變量被複制。但它的行爲就像我們正在處理ref類型的兩個副本一樣的不可模擬的ref類型。不是不可變對象的這種不安全的行爲? – 2013-02-16 17:17:06

+0

不勾號=勾號意味着勾號指的是掛鉤到勾號的同一組方法,如果我空勾號勾號也變爲空? – Dork 2013-02-16 17:31:22

+2

@Dork - 不變'Tick'不會改變'tick'。一旦'tick'被分配給一個參考設置'Tick'給一個差分引用(甚至爲空)不會改變'tick'。它與'string s1 =「1234」完全相同;字符串s2 = s1; s1 = null;' - 最後's2'仍然是「1234」而不是空值。 – shf301 2013-02-16 17:37:42

0

這是因爲,你們之間nullchecking的事件,它被稱爲,東西可能已經退訂,使得事件null,這將拋出一個(可能未處理)NullReferenceException,這將是惱人的用戶,至少可以說。