web-dev-qa-db-ja.com

C#の「使用」構文

を使用して例外をキャッチまたはスローしますか?つまり.

using (StreamReader rdr = File.OpenText("file.txt"))
{
 //do stuff
}

ストリームリーダーが例外をスローした場合、それを使用してキャッチしたりスローしたりして、呼び出し側の関数がそれを処理できるようにしますか?

45
Gordon Thompson

ステートメントの使用は例外を食べません。

"Using"が行うことは、オブジェクトのスコープをusingブロックに限定することであり、オブジェクトがブロックを離れると、オブジェクトのDispose()を自動的に呼び出します。

ただし、問題があります。スレッドが外部ソースによって強制的に中止された場合、Disposeが呼び出されない可能性があります。

31
FlySwat

Usingステートメントが表示されたら、次のコードについて考えてください。

StreadReader rdr = null;
try
{
    rdr = File.OpenText("file.txt");
    //do stuff
}
finally
{
    if (rdr != null)
        rdr.Dispose();
}

したがって、本当の答えは、usingブロックの本体でスローされた例外では何もしないということです。処理も再スローもしません。

62
jop

using 例外を煮詰めることができます。これはtry/finallyのように動作し、最終的には使用されたオブジェクトを破棄します。したがって、これはIDisposableを実装するオブジェクトにのみ適切/有用です。

16

それは例外をスローするので、包含メソッドはそれを処理するか、スタックに渡す必要があります。

try
{
    using (
        StreamReader rdr = File.OpenText("file.txt"))
    { //do stuff 
    }
}
catch (FileNotFoundException Ex)
{
    // The file didn't exist
}
catch (AccessViolationException Ex)
{
    // You don't have the permission to open this
}
catch (Exception Ex)
{
    // Something happened! 
}
5
stephenbayer

あなたの例では、File.OpenTextがスローすると、Disposenotが呼び出されます。

//do stuffで例外が発生した場合、Disposewillが呼び出されます。

どちらの場合も、usingステートメントがない場合と同様に、例外は通常、スコープの外に伝播されます。

3

Usingステートメントの初期化式でスローされたすべての例外は、期待どおりにメソッドスコープと呼び出しスタックに伝達されます。

ただし、初期化式で例外が発生した場合、式変数でDispose()メソッドが呼び出されないことに注意してください。実際に作成されなかったオブジェクトを破棄する必要がないので、これはほとんど常に望ましい動作です。ただし、複雑な状況では問題が発生する可能性があります。つまり、コンストラクター内に複数の初期化が埋め込まれていて、例外がスローされる前にいくつかが成功した場合、その時点でDispose呼び出しが発生しない可能性があります。ただし、コンストラクタは通常シンプルに保たれているため、これは通常問題にはなりません。

3

特に例外をキャッチしない場合は、何かが発生するまでスタックがスローされます

2
hometoast

使用は、スコープ内のものをクリーンアップすることを除いて、例外処理に干渉しません。

例外は処理しませんが、例外を通過させます。

2
tpower

using保証*例外がスローされても、作成されたオブジェクトはブロックの最後に配置されます。例外はnotです。ただし、自分でキャッチしようとする場合は、何をするかについて注意する必要があります。例外をキャッチするコードはusingステートメントで定義されたスコープブロックの外にあるため、オブジェクトはそのコードで使用できません。

*停電、核ホロコーストなどの通常の容疑者を除く

2
Joel Coehoorn

singは、catchブロックのないtry ... finallyブロックとして想像できます。 finallyブロックではIDisposable.Disposeが呼び出され、catchブロックがないため、例外がスタックにスローされます。

1
petr k.

"using"は例外をキャッチせず、未処理の例外が発生した場合にリソースを破棄するだけです。

おそらく問題は、宣言でエラーが発生した場合、括弧内に割り当てられたリソースを破棄することでしょうか?しかし、両方が起こっていることを想像するのは困難です。

0
harpo