Yes, there is, but unfortunately it's not straightforward to do this generically, because events are not reified in C# - what I mean is, you can't pass around a reference to an event.
In the Reactive Extensions, this is worked around by using reflection, so you pass an event to a function by passing the object it is defined on, and the name of the event as a string:
using(ListenUntilDispose(Foo, "My", handler))
{
await Foo.Bar();
}
However, my reflection-fu is not terribly strong, and you also lose static type safety, meaning that the compiler can't check if handler
really matches up with Foo.My
. Here's another suggestion that is not as comfortable but might also suit you, if your goal really is "I want to use using
" and not necessarily "I want the most easily readable solution":
class DelegateDisposable : IDisposable
{
private readonly Action m_dispose;
public DelegateDisposable(Action onDispose)
{
m_dispose = onDispose;
}
public void Dispose()
{
m_dispose();
}
}
Usage would be:
Foo.My += handler;
using(new DelegateDisposable(() => Foo.My -= handler))
{
await Foo.Bar();
}
Disclaimer: Written in the edit box, so untested :)