2010-06-02 4 views
2

Я использую шаблон EventAgregator для подписки и публикации событий. Если пользователь подписывается на событие с использованием выражения лямбда, они должны использовать сильную ссылку, а не слабую ссылку, иначе выражение может быть собрано в мусор, прежде чем публикация будет выполнена.Как определить, является ли действие выражением лямбда?

Я хотел бы добавить простую проверку в делететом делегирования, чтобы, если программист проходит в выражении лямбда и использует слабую ссылку, я бросаю исключение аргумента. Это поможет «полицейскому» коду.

Пример:

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, но я не считаю, что работает ... (есть ли каждое лямбда-выражение статическое?)

ответ

1

Нет, не каждый генерируемый лямбда делегат является статическим методом. Если есть захваченные переменные, это может быть экземпляр. Но в конечном счете очень мало различий между делегатом на основе лямбда, делегатом на основе анонимного метода и явным делегатом. Я бы не сделал никакой дополнительной логики - просто рассматривайте ее как делегата (я полностью удалю код WeakReference).

+0

так что теперь можно узнать, является ли делегат анонимным? Лично я не очень похож на код WeakReference, потому что после того, как срок жизни вашего класса закончен, если вы не отмените подписку, ваш метод может быть вызван в фоновом режиме несколько раз (или, по крайней мере, методом фильтра). Но это Microsoft «Best Practices». :) Я считаю, что silverlight, использующий этот шаблон, будет генерировать исключение, если вы попытаетесь использовать слабую ссылку с анонимным делегатом ... поэтому я думал, что это должно быть выполнено. – Keith

+0

@ Keith - Я был бы удивлен, если бы «новый» был оптимизирован. –

Смежные вопросы