2013-02-16 64 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,这将是恼人的用户,至少可以说。