Подписка на событие на время использования блока
Я часто сталкиваюсь со следующим кодом:
myService.SomeEvent += listener;
myService.DoSomething();
myService.SomeEvent -= listener;
Это здорово, но было бы здорово, если бы мы могли сделать это более приятным способом. Я думал сделать что-то вроде:
using(EventScope.Start(myService.SomeEvent, listener)){
myService.DoSomething();
}
К сожалению, это запрещено C#, потому что myService.Некоторые события могут появляться только с левой стороны от a += или a -= (по уважительной причине). Мой вопрос в том, какие еще варианты у меня есть? В идеале я хотел бы, чтобы это было типобезопасно, что исключает рефлексию и выполнение следующего (что я уже сделал реализовано):
using(EventScope.Start(myService, "SomeEvent", listener){
myService.DoSomething();
}
Чтобы быть ясным, я не женат на использовании синтаксиса "using", и, возможно, вы могли бы сказать, что это извращение языка. Другие варианты были бы оценены!2 ответа:
Вероятно, есть способ сделать это с более чистым синтаксисом, но если у вас есть такая структура...
public struct ActionDisposable : IDisposable { private readonly Action _action; public ActionDisposable(Action action) { _action = action; } public void Dispose() { _action(); } }
...и метод, подобный этому:
public static IDisposable EventScope(Action subscribe, Action unsubscribe) { subscribe(); return new ActionDisposable(unsubscribe); }
Это позволит вам написать такой код:
using (EventScope(() => myService.SomeEvent += listener, () => myService.SomeEvent -= listener)) { myService.DoStuff(); }
Или вот так:
myService.SomeEvent += listener using (new ActionDisposable(() => myService.SomeEvent -= listener)) { myService.DoStuff(); }