Передача события в качестве аргумента в метод - PullRequest
4 голосов
/ 11 февраля 2010

Я хочу передать событие в метод. У меня есть следующий код, но что я могу поставить для типа «XXX»?

internal class Retriever<TEventArgs> where TEventArgs : EventArgs
{
    public Retriever( XXX event, EventHandler<TEventArgs> handler )
    {
        _event = event;
        _handler = handler;

        _event += handler;
    }

    XXX _event;
    EventHandler<TEventArgs> _handler;
}

Редактировать : Разработка вопроса. Я пытаюсь написать универсальную защиту событий, на которую подписывается событие до наступления события и отписывается после того, как событие произошло. Этот класс будет выглядеть так:

internal class EventGuard<TEventArgs> : IDisposable where TEventArgs : EventArgs 
{
    public Retriever( XXX event, EventHandler<TEventArgs> handler )
    {
        _event = event;
        _handler = handler;

        _event += handler;
    }

    XXX _event;
    EventHandler<TEventArgs> _handler;

    public void Dispose()
    {
        _event -= _handler;
    }
}

и я бы использовал его следующим образом. Proxy.RetrieveAsync - это веб-метод, который после завершения вызовет событие Proxy.RetrieveCompleted. Тело обработчика завершения HandleRetrieveCompleted, которое не показано, вызовет Set () для ManualResetEvent (переданного как объект UserState).

using ( new EventGuard<EventArgs>( Proxy.RetrieveCompleted, new  EventHandler<EventArgs>( HandleRetrieveCompleted) ) )
{
    ManualResetEvent resetEvent = new ManualResetEvent();
    Proxy.RetrieveAsync(resetEvent);
    resetEvent.WaitOne();

}

1 Ответ

6 голосов
/ 11 февраля 2010

Вы не делаете - событие похоже на свойство, это просто синтаксический сахар вокруг пары методов (добавление / удаление вместо получения / установки свойства).F # на самом деле действительно выставляет события как первоклассные граждане, но C # не делает: (

Хотя есть несколько вариантов:

  • Pass inделегат «подписчик на событие», который вы вызываете с помощью нового обработчика, который вы хотите добавить (и, возможно, также делегат от события отписчика). Примерно так:

    new Receiver(handler => button.Click += handler, ...)
    
  • Передать EventInfo и подпишитесь с отражением (urgh)

  • Изучите инфраструктуру Reactive Extensions, которая имеет различные способы работы с событиями (используя отражение, но это означает, что Microsoft работает над отражением, а не вы :)

Мы могли бы дать лучший совет, если бы знали более широкую картину - не могли бы сообщить нам больше?

РЕДАКТИРОВАТЬ: Хорошо, в этом случае вам нужно будет сдать обакод подписки и отписки:

using (new EventGuard<EventArgs>(h => Proxy.RetrieveCompleted += h, 
          h => Proxy.RetrieveCompleted -= h,
          HandleRetrieveCompleted))
{
    ...
}

Это довольно неприятно, по общему признанию. Вы можете найти что-то более приятное в Reactive Extensions , но это по крайней мере сработает ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...