2

私は現在、このようなコード、asyncメソッドを持っています:

MyEventHandler handler = (sender, e) => ...

Foo.My += handler;

await Foo.Bar();  // Fires event `My` 

Foo.My -= handler;

usingステートメントを使用して、このコードの前後の性質を処理したいと考えています。おそらく次のようなものです:

using (ListenUntilDispose(Foo.My, handler))
{
    await Foo.Bar();
}

しかし、私は書くことを理解できませんListenTemporarily

これを行う方法はありますか?

4

1 に答える 1

1

はい、ありますが、残念ながら、イベントは C# で具体化されていないため、これを一般的に行うのは簡単ではありません。つまり、イベントへの参照を渡すことはできません。

Reactive Extensions では、これはリフレクションを使用して回避されるため、イベントが定義されているオブジェクトとイベントの名前を文字列として渡すことで、イベントを関数に渡します。

using(ListenUntilDispose(Foo, "My", handler))
{
    await Foo.Bar();
}

ただし、私のreflection-fuはそれほど強力ではなく、静的型の安全性も失われます。つまり、コンパイラは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();
}

免責事項:編集ボックスに書かれているので、テストされていません:)

于 2013-10-28T20:49:33.197 に答える