一次性用品,使用和尝试/捕捉块
今天有一个心理障碍,需要一只手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体并比较生成的代码。