2010-04-28 50 views
7

今天有一个心理障碍,需要一个手来验证我的逻辑没有被fubar化。一次性使用&使用&try/catch块

传统,我会做文件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 
} 

但是,我担心在使用块中的过早退出(抛出通过除外)可能不允许使用块完成执行并清理它的对象。我只是偏执狂,还是会按照我的意图行事?

回答

17

你只是被偏执它一定会给你想要的方式来:)

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 
} 
0

别担心,它会清除如预期,并且比原来的更干净。

事实上,在您的业务逻辑中尝试/最终再次使用语句以及在UI层或物理层边界的顶级处理程序中尝试/捕获更为常见。喜欢的东西:

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

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

这将工作 - 内部using语句编译方法一样一个try-finally块

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

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

代码的第二件被翻译成这个

0

使用块将工作完全符合你所要翻译的使用块是真实的LY只是

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

你不需要try..finally如果你有一个using()。他们执行相同的操作。

如果您不确定,请在您的程序集中指向Reflector并比较生成的代码。