0

Java では、catch 句によって例外がキャッチされ、その catch ブロックが例外をスローした場合、スレッドが終了する前に、関連する finally ブロック (存在する場合) を制御がスローすることを知っています。ただし、これは C# には当てはまらないようです。

C# でこの動作をほぼ反映することは、例外をスローする catch ブロックを含む try-catch ステートメントの try ブロック内に try-finally ステートメントを配置することによって可能ですが、たとえば、finally がブロックには、例外をログに記録することになっている Stream Writer を破棄するコードが含まれていると想定されています。

C# で java のような try-catch-finally 例外処理動作を実現するクリーンな方法はありますか?

リクエストされたサンプル コードの更新は次のとおりです。

StreamWriter writer = new StreamWriter("C:\\log.txt");
try
{
    throw new Exception();
}
catch (Exception e)
{
    writer.WriteLine(e.Message);
    throw e;
}
finally
{
    if (writer != null)
    {
       writer.Dispose();
    }
}

そのコードをコンソール アプリケーションに追加して実行し、再スローされた例外を未処理のままにし、C:\log.txt の削除を試みます。制御が finally ブロックを通過したことがないため、それはできません。また、finally ブロック内のある行にブレークポイントを追加すると、ヒットしないことがわかります。(私はVS2005を使用しています)。

私の知る限り、コントロールが finally ブロックを通過するようにする唯一の方法は、再スローされた例外が外側の try ブロックの catch ブロックによって処理される場合です (上記のコードを try ブロック内に配置した場合)。別の try-catch ステートメントの)。

私が提供したサンプル コードのように、例外がキャッチされず、アプリケーションを終了できる場合、制御は finally ブロックを通過しません。

Javaではそうです。C# では、少なくとも私が見たものに基づくと、そうではありません。

4

4 に答える 4

2

いいえ、これは正しくありません。finallyC# は、ブロックから例外がスロー/再スローされた後でも、常にブロックを実行しcatchます。catch ブロックから例外をスローした場合、最終的に実行されるのはいつですか? を参照してください。.

于 2013-10-08T00:04:28.287 に答える
1

finally.NET Framework では、例外が発生すると、ブロックが実行される前に、システムがその例外をキャッチするかどうかを判断します。さまざまなアプリケーションの設定によっては、キャッチされない例外をスローしようとすると、finallyブロック (またはその他のもの) を実行する機会を与えずに、アプリケーションを即座に強制終了する可能性があります。

Mainメソッドと各スレッドをラップすると、

try
{
  ...
}
catch
{
  throw;
}

tryブロック内でスローされた例外はすべてキャッチされます。すぐに再スローされますが、ネストされたfinallyブロックはcatch. これが望ましい動作である場合もあります。たとえば、例外がキャッチされない場合に特別なログを実行したい場合があります (場合によっては、ログに記録したい情報が破棄される可能性があります)。finallyブロックは最初に実行するチャンスを得ます)。C# 内では、例外がキャッチされるかどうかに基づいてアクションを変更する方法はありませんが、VB.NET ではそれを行う方法がいくつかあります。C# コードへの呼び出しを行う VB.NET アセンブリは、内部メソッドによってスローされた例外がキャッチされることなく vb.net ラッパーに伝播するかどうかを知る方法をそのコードに与えることができます。

于 2013-12-13T18:27:31.817 に答える
0

ただし、これは C# には当てはまらないようです。

これはあなたが探しているものですか。

于 2013-10-08T00:03:44.093 に答える