2010-06-02 62 views
2

我正在使用EventAgregator模式來訂閱和發佈事件。如果用戶使用lambda表達式訂閱事件,則它們必須使用強引用,而不是弱引用,否則可以在發佈執行之前對錶達式進行垃圾收集。如何判斷某個操作是否爲lambda表達式?

我想在DelegateReference中添加一個簡單的檢查,以便如果程序員傳入一個lambda表達式並使用弱引用,則拋出一個參數異常。這是爲了幫助「警察」編碼。

例子:

eventAggregator.GetEvent<RuleScheduler.JobExecutedEvent>().Subscribe 
     (
      e => resetEvent.Set(), 
      ThreadOption.PublisherThread, 
      false, 
      // filter event, only interested in the job that this object started 
      e => e.Value1.JobDetail.Name == jobName 
     ); 


public DelegateReference(Delegate @delegate, bool keepReferenceAlive) 
    { 
     if (@delegate == null) 
      throw new ArgumentNullException("delegate"); 

     if (keepReferenceAlive) 
     { 
      this._delegate = @delegate; 
     } 
     else 
     { 
      //TODO: throw exception if target is a lambda expression 
      _weakReference = new WeakReference(@delegate.Target); 
      _method = @delegate.Method; 
      _delegateType = @delegate.GetType(); 
     } 
    } 

什麼想法? 我以爲我可以檢查@ delegate.Method.IsStatic,但我不相信,工程...(是每個lambda表達式靜態?)

回答

1

不,不是每個拉姆達產生的代表是一個靜態方法。如果有捕獲的變量,它可以是一個實例。但最終,基於lambda的委託,基於匿名方法的委託和顯式委託之間幾乎沒有區別。我不會做任何額外的邏輯 - 只是把它當作一個委託(我會完全刪除WeakReference的代碼)。

+0

所以現在有辦法來判斷委託人是否是匿名的?就我個人而言,我並不特別喜歡WeakReference代碼,因爲在您的類生命期結束後,如果您不取消訂閱,您的方法可能會反覆在後臺調用(或者至少是過濾器方法)。但這是微軟的「最佳實踐」。 :) 我相信,使用這種模式的silverlight會拋出一個異常,如果你試圖對匿名委託使用弱引用...所以我認爲它應該是可行的。 – Keith 2010-06-02 19:48:42

+0

@Keith - 如果一個'new'被優化了,我會感到驚訝。 – 2010-06-03 10:00:25