2010-06-02 123 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