C# 一次性使用、使用和维护;试块/抓块

C# 一次性使用、使用和维护;试块/抓块,c#,.net,using-statement,C#,.net,Using Statement,今天有精神障碍,需要一只手来验证我的逻辑是否正确 传统上,我会执行与以下类似的文件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)

今天有精神障碍,需要一只手来验证我的逻辑是否正确

传统上,我会执行与以下类似的文件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块完成执行并清理其对象。我只是偏执狂,还是这真的会像我想的那样起作用?

你只是偏执狂,它会像你想的那样起作用:)

using语句相当于try/finally块,不管它是否在try/catch中

因此,您的代码类似于:

try
{
   FileStream fs = null;
   try
   {
       fs = File.Open("Foo.txt", FileMode.Open);
       // Do stuff
   }
   finally
   {
       if (fs != null)
       {
           fs.Dispose();
       }
   }
}
catch(Exception)
{
   /// Handle Stuff
}

别担心,它会像预期的那样干净,比你原来的更干净

事实上,在业务逻辑中使用try/finally-aka-using语句,在UI层或物理层边界的顶级处理程序中使用try/catch更为常见。比如:

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


这将起作用-在内部,using语句的编译方式与try-finally块的编译方式相同

    try
    {
        FileStream fs = null;
        try
        {
           fs = File.Open("Foo.txt", FileMode.Open);

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

第二段代码被翻译成这个

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
}

如果您有
using()
,则不需要
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
}