2011-02-25 38 views
1

如果我喜歡寫東西匿名代表何時從事件中刪除?

myDataModel.ContentLoaded += (o,e) => { DoSomething(); } 

當(如果有的話)是匿名委託從活動中移除?

作爲一個簡單的例子,我可以爲我按「確認」鍵多次爲

Hello! 

Hello! 
Hello! 

Hello! 
Hello! 
Hello! 

Hello! 
Hello! 
Hello! 
Hello! 

...等等編寫這個程序

class Program 
{ 
    public event EventHandler<EventArgs> MyEvent = delegate { }; 

    static void Main(string[] args) 
    { 
     Program p = new Program(); 
     while(true) 
     { 
      p.MyEvent += (o, e) => Console.WriteLine("Hello!"); 

      Console.ReadLine(); 
      p.Foo(); 
     } 
    } 

    void Foo() 
    { 
     MyEvent(this, EventArgs.Empty); 
    } 
} 

和輸出。我可以添加行

p.MyEvent -= (o, e) => Console.WriteLine("Hello!"); 

p.Foo()後,但當然沒有任何影響,因爲我刪除一個完全不同的匿名委託。

那麼這是怎麼回事呢?有什麼辦法可以刪除這些匿名代表嗎?例如,對於使用表達式抽取數據的異步Silverlight應用程序有什麼影響?

_myDataContext.Load(myQuery, loadOperation => 
    { 
     // do stuff with the data here 
    }, null); 

?我假設這些回調函數並沒有使用事件來實現,但當然不可能(?)告訴。

如果不仔細考慮匿名代表是否危險?

回答

1

沒有(簡單)的方法來消除代表們說,你沒有第一assing任何變量。它們是否是匿名的並不重要。您可以匿名委託分配給一個變量,後來將其刪除:

EventHandler eh = (src, e) => Console.WriteLine("Hello"); 
form.Click += eh; 
// At some later point 
form.Click -= eh; 

同樣,沒有(容易)的方式,如果你用它註冊刪除委託:

form.Click += new EventHandler(foo); 

與事件的問題是當它們附加到的對象被垃圾收集時(即使它們使用的目標對象沒有從程序的任何其他部分引用,因此它們不能執行任何有用的工作),它們只是垃圾收集。

這可以使用weak events來解決。你不用明確地刪除它們,而是使用一些允許GC自動處理它們的機制。