是的,有,但不幸的是,一般来说这样做并不简单,因为事件在 C# 中没有具体化——我的意思是,你不能传递对事件的引用。
在 Reactive Extensions 中,这是通过使用反射来解决的,因此您可以通过传递定义事件的对象并将事件名称作为字符串传递给函数:
using(ListenUntilDispose(Foo, "My", handler))
{
await Foo.Bar();
}
但是,我的反射符并不是很强大,而且你也失去了静态类型安全性,这意味着编译器无法检查是否handler
真的匹配Foo.My
. 如果您的目标确实是“我想使用using
”而不一定是“我想要最容易阅读的解决方案”,那么这里还有一个不太舒服但也可能适合您的建议:
class DelegateDisposable : IDisposable
{
private readonly Action m_dispose;
public DelegateDisposable(Action onDispose)
{
m_dispose = onDispose;
}
public void Dispose()
{
m_dispose();
}
}
用法是:
Foo.My += handler;
using(new DelegateDisposable(() => Foo.My -= handler))
{
await Foo.Bar();
}
免责声明:写在编辑框中,所以未经测试:)