2012-03-06 11 views
1

私が理解している限り、try/catch/finallyのようなものを使用すると、例外を使用するステートメントで発生した場合、それは捕まえられることが予想されます(これはちょっと奇妙です。静かに食べた)。 usingステートメントは例外をキャッチし、Disposeメソッドを呼び出す必要がありますが、それは起こっていません。私はこの問題を実証するための簡単なテストを考案しました。私が使用して文の内部で発生した例外を強制するのはここtry/catch/finallyのように動作すると思われる場合、なぜ例外をスローしますか?

は次のとおりです。

using (TcpClient client = new TcpClient()) 
{ 
    // Why does this throw when the using statement is supposed to be a try/catch/finally? 
    client.Connect(null); 
} 

例外は(それが使用する文によってか、再スローされたことをキャッチされていなかったことを意味する)client.Connect()で投げています:Disposeメソッドがスローした場合

System.ArgumentNullException: Value cannot be null. 
Parameter name: remoteEP 
    at System.Net.Sockets.TcpClient.Connect(IPEndPoint remoteEP) 
    at DotNETSandbox.Program.Main(String[] args) in C:\path\to\Sandbox\Program.cs:line 42 

a Microsoft article on the topicによると、usingステートメントは投げるかもしれません。

私が使用してパターンを以下のよしかし、Disposeメソッドがスローしないことは明らかである:

TcpClient c2 = new TcpClient(); 
try 
{ 
    c2.Connect(null);    
} 
catch (Exception e) 
{ 
    // We caught the null ref exception 
    try 
    { 
     // Try to dispose: works fine, does not throw! 
     ((IDisposable)c2).Dispose(); 
    } 
    catch (Exception e2) 
    { 
     Console.WriteLine(e2.ToString()); 
    } 
    Console.WriteLine(e.ToString()); 
} 

私は試してみるように振る舞うようにusingを期待していたので、私は、少し混乱しています/キャッチ。誰がなぜこれが起こっているのか説明できますか?使用

+3

を失敗した場合、ApplicationExceptionをを使用してブロックの外に見たことがないが、最終的にブロックして、最終的にはキャッチしないでください。例外は、依然としてusingブロックから捨てられます。 –

+3

なぜ_what_が起きていますか?あなたは 'using'ステートメントが静かに例外を食べると期待していますか? – SLaks

+0

何らかの理由で私は「使用する」にcatchステートメントがあるという印象が残っていましたが、今までそれについてあまり考えすぎたことはありませんでした。私はいつも例外をキャッチし、それは本当に私を心配することはありませんでしたが、記事を読んだ後、私は何かが不足していることに気付きました。 – Kiril

答えて

8

try 
{ 
} 
finally 
{ 
} 

だけです!

キャッチはありません!あなたは例外をキャッチするために持っていけない.NETで

...とすぐにスコープを残すようDisposeメソッドを呼び出します

そのわずかメカニズム。それで全部です。

P.S. : "私のオブジェクトを使用して使用することができますか?

答え:心配はいりません - コンパイル時にエラーが表示されます。

+0

私は見る... OK、それは今意味があります! – Kiril

+0

さらに、IDisposableインターフェイスを実装している場合、オブジェクトがuseを使用できるかどうかを知ることができます –

5

usingは、を除いたtry/finallyの詳細です。

コントロールは、使用しているオブジェクトを廃棄せずにブロックを離れることはできません。は、それがです。
ブロック内からスローされた例外(Disposing後)は、通常どおりに渡されます。

編集:呼び出されてIEnumerableを実装し、あなたが処分()せずにブロックを残すために言うことができusingのうち、降伏の特別な場合には、私自身の答えにニットをピッキングしていますが、よ列挙を継続する場合もう一度内側に戻る。

3

usingはtry/catch/finallyのように動作しません。 try/finallyのように動作します。

最初の例では、例外をスローしても、TcpClientを適切に廃棄します。

2

ステートメントを使用するとtry、try、catch、finallyブロックではなくfinallyブロックのように動作します。

例外は、依然として使用ブロックから捨てられます。

0

多くの人が、usingステートメントは例外をキャッチしないと言っています。しかし、私はこの記事からあなたの混乱を見ることができます。

IF Dispose()が失敗すると、使用ブロック内にスローされたエラーを隠すことができます。

のDispose()は「最終的には」ブロックの内部で発生するのでのDispose()は、文は試してみるように振る舞う使用

関連する問題