2013-05-04 61 views
0

A field-like-event是一種同時聲明委託變量和事件的方法。「場地般的事件」和「一般事件」的澄清?

所以像事件(public event EventHandler MyEvent;)字段可以轉化爲:(從here拍攝)

private EventHandler _myEvent; 

public event EventHandler MyEvent 
{ 
    add 
    { 
     lock (this) 
     { 
      _myEvent += value; 
     } 
    } 
    remove 
    { 
     lock (this) 
     { 
      _myEvent -= value; 
     } 
    }   
} 

通知私有備份領域。

然而,我被Jon評論部分)修正,即一般的事件doen't有備份領域。例如:

public event EventHandler MyEvent 
    { 
     add 
     { 
      Console.WriteLine ("add operation"); 
     } 

     remove 
     { 
      Console.WriteLine ("remove operation"); 
     } 
    }  

注意 - 沒有備份字段。

但隨後他說,WinForm的行爲是這樣的:

例如,在那裏有很多的活動,但只有一個 幾個可能被訂閱,你可以有從地圖的情況下一些關鍵 描述事件給當前處理它的委託。這是 Windows窗體所做的 - 這意味着您可以擁有大量的 事件,而不會浪費大量內存,其中 通常只有空值。

問:

  • 如何WinForm的使用地圖事情暴露事件,而
+1

我注意到你在C#1,2和3中顯示了類似於場的事件的代碼。在C#4中我們大大改進了這個代碼。有關詳細信息,請參閱http://blogs.msdn.com/b/cburrows/archive/2010/03/05/events-get-a-little-overhaul-in-c-4-part-i-locks.aspx。 – 2013-05-04 14:26:44

+0

@EricLippert事實上,「_add和remove call將有效地serial_」可以讓我們刪除鎖? (如果我正確地理解了文章...) – 2013-05-04 14:45:23

+1

鎖被替換爲一個無鎖原子測試集,它與鎖具有相同的效果,只要訪問序列化,但沒有鎖定的令人討厭的副作用'this'。鎖定'this'的問題在於*別人可以鎖定*,現在你已經使得事件處理鎖定的正確性和效率與鎖定'this'的其他人的正確性和效率緊密相關。這就是爲什麼鎖定'this'是一種糟糕的編程習慣。 – 2013-05-04 14:59:01

回答

2

首先這個「地圖的事」(的委託類型)的任何備份場只是一個Dictionary<object, EventHandler>。它本身就是類的一個字段,但是當它被創建時它將不包含任何元素,因此不會佔用太多內存(只是其內部結構會有一些開銷)。當事件訂閱時,代表被添加到字典中,我們開始使用更多的內存。

考慮一個有50個事件的類,我們只使用5個事件,在一個簡單的場景中,會爲每個類的每個實例創建50個代表。當使用字典進行存儲時,每個實例會有5個代表。

P.S.這與WPF中的依賴對象/屬性背後的原理相同。

+0

但是代碼(在我的第二部分)在文檔中仍然是50次...不是?你能否提供一個簡單的例子,這樣會更清楚? – 2013-05-04 08:30:50

+0

檢查喬恩的答案在這裏:http://stackoverflow.com/questions/5303595/what-are-some-cases-where-it-would-be-advantageous-to-use-an-event-without-havin – Slugart 2013-05-04 08:50:49

+0

哈哈 - 相同的報價 - 在主要問題。謝謝。:-) – 2013-05-04 08:52:52