一次性用品,使用和尝试/捕捉块

今天有一个心理障碍,需要一只手validation我的逻辑并不是很好的。

传统上我会做类似这样的文件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块来处理文件流,但我不确定using和try / catch之间的协同作用。

这就是我想要实现上述内容的方式:

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

但是,我担心使用块中的过早退出(通过抛出exception)可能不允许使用块完成执行并清理它的对象。 我只是偏执狂,还是会按照我打算的方式运作?

你只是偏执狂它会以你想要的方式工作:)

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) { ... } 

 public void DoStuffWithFile(string fileName) { using(FileStream fs = File.Open(fileName,...)) { // Do Stuff } } 

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

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

第二段代码被翻译成这个

使用块将完全按照您所说的转换使用块实际上正常工作

 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 。 他们执行相同的操作。

如果您不相信,请将Reflector指向assembly体并比较生成的代码。