7

今日メンタルブロックを持っているので、私の論理が混乱していないことを確認する手が必要です。

従来、私は次のようなファイルI/Oを実行していました。

FileStream fs = null; // So it's visible in the finally block
try
{
   fs = File.Open("Foo.txt", FileMode.Open);

   /// Do Stuff
}
catch(IOException)
{
   /// Handle Stuff
}
finally
{
   if (fs != null)
      fs.Close();
}

ただし、これはあまりエレガントではありません。

理想的には、usingブロックを使用してファイルストリームを破棄したいのですが、使用とtry/catchの相乗効果についてはよくわかりません。

これが私が上記を実装したい方法です:

try
{
   using(FileStream fs = File.Open("Foo.txt", FileMode.Open))
   {
      /// Do Stuff
   }
}
catch(Exception)
{
   /// Handle Stuff
}

ただし、usingブロック内からの(スローされた例外による)時期尚早な終了では、usingブロックが実行を完了してそのオブジェクトをクリーンアップできない可能性があるのではないかと心配しています。私はただの妄想ですか、それともこれは実際に私が意図したとおりに機能しますか?

4

6 に答える 6

17

あなたはただ妄想的であり、それはあなたが意図したように機能します:)

usingステートメントは、try / catch内にあるかどうかに関係なく、try/finallyブロックと同等です。

したがって、コードは次のようになります。

try
{
   FileStream fs = null;
   try
   {
       fs = File.Open("Foo.txt", FileMode.Open);
       // Do stuff
   }
   finally
   {
       if (fs != null)
       {
           fs.Dispose();
       }
   }
}
catch(Exception)
{
   /// Handle Stuff
}
于 2010-04-28T18:14:54.470 に答える
0

心配しないでください、それは期待通りにきれいになり、あなたのオリジナルよりきれいです。

実際、ビジネスロジックでtry / finalaka usingステートメントを使用し、UI層または物理層の境界でトップレベルハンドラーにtry/catchを使用する方がはるかに一般的です。何かのようなもの:

try
{
    DoStuffWithFile("foo.txt");
}
catch(Exception ex)
{
   ...
}

public void DoStuffWithFile(string fileName)
{
    using(FileStream fs = File.Open(fileName,...))
    {
        // Do Stuff
    }
}
于 2010-04-28T18:15:02.443 に答える
0

これは機能します-内部的には、usingステートメントはtry-finallyブロックと同じ方法でコンパイルされます

于 2010-04-28T18:15:40.193 に答える
0
    try
    {
        FileStream fs = null;
        try
        {
           fs = File.Open("Foo.txt", FileMode.Open);

        }
        finally
        {
           fs.Dispose();
        }
    }
    catch(Exception)
    {
       /// Handle Stuff
    }

2番目のコードはこれに変換されます

于 2010-04-28T18:15:55.647 に答える
0

usingブロックは、翻訳されたとおりに機能します。usingブロックは実際には

try
{
   FileStream fs = null;
   try
   {
        fs = File.Open("Foo.txt", FileMode.Open))
        //Do Stuff
   }
   finally
   {
      if(fs != null)
          fs.Dispose();
   }
}
catch(Exception)
{
   /// Handle Stuff
}
于 2010-04-28T18:16:20.983 に答える
0

try..finallyがある場合は必要ありませんusing()。それらは同じ操作を実行します。

確信が持てない場合は、Reflectorをアセンブリに向けて、生成されたコードを比較してください。

于 2010-04-28T18:16:33.017 に答える