2

デリゲートを使用すること、System.Actionまたは従来のパターンSystem.Funcの代わりにEventDelegatesとして使用することに反対するものEventHandler。したがって、問題が発生しますか?

private bool disposed;

public event Action<IUnitOfWork, IContext> Disposing;

public void Dispose()
{
    if (this.disposed)
    {
        return;
    }

    if (null != this.Disposing)
    {
        this.Disposing(this, this.AttachedContext);
    }

    this.disposed = true;
}

使用法:

unitOfWorkInstance.Disposing += (u, c) => c.Rollback(u); // in my opinion more readable than
unitOfWorkInstance.Disposing += (sender, args) => args.AttachedContext.Rollback(sender as IUnitOfWork);
4

3 に答える 3

6

さて、あなたがそこに与えたコードはスレッドセーフではありません-誰かがあなたのnullityテストの後そしてあなたの呼び出しの前にeventhandlerから退会するかもしれませんthis.Disposing

しかし、一般的には、問題なく動作するはずです。欠点は、EventHandler規則に従わないことにより、サブスクライブできるものがわずかに制限されることです。

たとえば、非常に一般的なイベントハンドラメソッドがあるとします。

public void LogEvent(object sender, EventArgs e)
{
    Console.WriteLine("Event raised");
}

これを使用して、通常の規則に従って任意のイベントをサブスクライブできますが、イベントではサブスクライブできません。

ただし、これはかなり小さな欠点です。潜在的に大きなものは、従来のイベント署名を見ることを期待している他の開発者を混乱させる可能性があることだと思います。

編集:他のいくつかのライブラリが従来のイベント署名を期待する可能性があることを思い出しました-たとえば、ReactiveExtensionsはそうします。IIRC、他のイベントを購読することは不可能ではありませんが、少し難しいです。

于 2011-05-24T09:03:33.360 に答える
2

「コード作業を行う」という観点からは、これらのデリゲートタイプをイベントに使用することはまったく問題ありません。

これを行う際の問題は、デリゲートがであるイベントの一般的なパターンに従っていないことですEventHandler<TEventArgs>。TEventArgsは、イベントのパラメーターを含むカスタムタイプです。このパターンに従うことの利点は次のとおりです。

  • コードの読みやすさ
  • イベントにパラメーターを追加する必要がある場合は、イベントサブスクライバーを変更する必要はありません(カスタムイベント引数クラスにパラメーターを追加するだけなので)。
于 2011-05-24T09:04:46.590 に答える
1

一般に:

Actionイベントハンドラーとして使用しても問題ありません。それは言語によってサポートされているので、それを使用してください:)

私が考えることができる唯一のケースは、リフレクションを介してイベントを見つけようとするコードです。しかし、そのコードがデリゲートをイベントタイプとして処理できない場合、それらのコードはバグがあり、あなたのコードではないと思います。

あなたの特定の例:

使用しているパターンの問題は、メソッド内で実際にオブジェクトを使用するべきではないということですDispose。安全な場合もありますが、間違えやすいでしょう。

たとえば、Disposeメソッドがイベントを発生させる前にリソースを破棄した場合、オブジェクトは使用できない状態になります。

これは、メンテナンスプログラマーがメソッドを編集するときに正しく理解するのが難しい場合があります(コメントと強力なコードレビューがない場合)Dispose

于 2011-05-24T09:05:59.483 に答える