3

C# での障害処理を改善するためにネットを閲覧したところ、次のような実装戦略を見つけました。最初のものは私にとって自然ですが、他の実装はその利点が何であるか確信が持てませんか?

1)

static void Fault(Action protectedBlock, Action faultHandler)
{ 
    try
    {
        protectedBlock();
    }
    catch
    {
        faultHandler();
        throw;
    }
}

2)

static Action Fault(Action protectedBlock, Action faultHandler)
{
    return () =>
    {
        try
        {
            protectedBlock();
        }
        catch
        {
            faultHandler();
            throw;
        }
    };
}

C# で高次関数を開発する場合、2) は優先される戦略ですか?

そして、あるアプローチが他のアプローチよりも効率的かどうか疑問に思っています。

4

3 に答える 3

5

2 番目のケースは、Faultable Action Factory のようなものです。やりたいことのデリゲート と、が発生protectedBlockしたときに何をするかのデリゲートを渡す場所。アクションは、集計として try/catch 構造にラップされて返されます。これらの両方の方法に関する私の問題は、実際にはキャッチされていないため、スローをキャッチしようとしている人は、どのアクションを実行すべきかについての情報がないことです。ExceptionfaultHandlerActionException

2つの実行の違いは、実際に実行するときです。1 つ目は、呼び出されたときに実行されます。Action2番目は、返されたが呼び出されるたびに実行されます。効率の違いはそれほど大きくないと思います。

于 2010-10-27T13:47:04.723 に答える
4

(2)はさらに構成できますが、(1)は実行するだけです。しかし、関数ではないため、どちらも正確には「機能的」でActionはありません ( と比較してくださいFunc<A, R>)。

したがって、(2)を使用すると、次のことができます。

Fault(someAction, Fault(firstTryFaultHandler, lastDitchFaultHandler))();

...そして、期待される動作を取得します。それは(1)では機能しません

于 2010-10-27T13:38:24.810 に答える
1

C# では、アプローチ 2 は混乱を招く可能性があります。呼び出し元は "Fault(a, b);" を使用する場合があります。a および場合によっては b が呼び出されることを期待しています。代わりに、ラムダが作成され、返され、破棄されます。つまり、何も行われません。

効率に関しては、ほとんどの呼び出しが "Fault(a,b)();" の形式である場合、つまりラムダをすぐに呼び出す場合、アプローチ 2 は少し無駄です。この状況では、ラムダは必要ありません。

これらの理由から、アプローチ 1 をお勧めします。実行を延期する必要がある場合は、明示的に "() => Fault(a, b)" というラムダを導入できます。

于 2010-10-27T13:57:40.937 に答える