为什么最终在C#中使用?
不pipefinally块里面的东西总是被执行(几乎),那么封装代码或者封闭代码有什么区别呢?
无论是否存在exception,finally块中的代码都会被执行。 当需要像closures连接一样运行某些内务pipe理function时,这非常方便。
现在,我猜你的问题是为什么你应该这样做:
try { doSomething(); } catch { catchSomething(); } finally { alwaysDoThis(); }
当你可以做到这一点:
try { doSomething(); } catch { catchSomething(); } alwaysDoThis();
答案是很多时候你的catch语句中的代码会重新抛出一个exception或者脱离当前的函数。 用后面的代码,“alwaysDoThis();” 调用将不会执行,如果catch语句内的代码发出一个返回或抛出一个新的exception。
使用try-finally的最大好处已经被指出,但是我想我会添加这个:
try { // Code here that might throw an exception... if (arbitraryCondition) { return true; } // Code here that might throw an exception... } finally { // Code here gets executed regardless of whether "return true;" was called within the try block (ie regardless of the value of arbitraryCondition). }
这种行为使得它在各种情况下非常有用,特别是当你需要执行清理(处置资源)时,尽pipe在这种情况下使用块通常更好。
因为即使不处理catch块中的exception,最终也会执行。
任何时候你使用非托pipe代码请求,如stream读取器,数据库请求等; 你想捕捉exception,然后最后使用try catch,最后closuresstream,数据读取器等,如果你没有错误的时候连接没有closures,这对数据库请求
SqlConnection myConn = new SqlConnection("Connectionstring"); try { myConn.Open(); //make na DB Request } catch (Exception DBException) { //do somehting with exception } finally { myConn.Close(); myConn.Dispose(); }
如果你不想赶上错误,那么使用
using (SqlConnection myConn = new SqlConnection("Connectionstring")) { myConn.Open(); //make na DB Request myConn.Close(); }
如果出现错误,连接对象将自动处理,但不会捕获错误
finally
,如下:
try { // do something risky } catch (Exception ex) { // handle an exception } finally { // do any required cleanup }
是try..catch
块后执行代码的保证机会,无论您的try块是否抛出exception。
这使得它非常适合于释放资源,数据库连接,文件句柄等。
最后,语句可以在返回之后执行。
private int myfun() { int a = 100; //any number int b = 0; try { a = (5 / b); return a; } catch (Exception ex) { Response.Write(ex.Message); return a; } // Response.Write("Statement after return before finally"); -->this will give error "Syntax error, 'try' expected" finally { Response.Write("Statement after return in finally"); // --> This will execute , even after having return code above } Response.Write("Statement after return after finally"); // -->Unreachable code }
假设您需要将光标移回默认指针,而不是等待(沙漏)光标。 如果在设置游标之前引发exception,并且不彻底崩溃应用程序,则可能会留下一个容易混淆的游标。
有时你不想处理一个exception(没有catch块),但是你想要执行一些清理代码。
例如:
try { // exception (or not) } finally { // clean up always }
finally块对于清理try块中分配的任何资源以及运行任何即使存在exception也必须执行的代码都是很有价值的。 无论try块如何退出,控制总是传递给finally块。
通过使用finally
块,您可以清除try
块中分配的任何资源,即使try
块中发生exception,也可以运行代码。 通常情况下,控制离开try语句时finally
语句运行。 控制转移可能由于正常执行,执行break, continue, goto, or return
语句或者try
语句外的exception传播而发生。
在处理的exception中,相关的finally
块将保证运行。 但是,如果exception未处理, finally
块的执行取决于如何触发exception展开操作。 这又取决于你的计算机是如何build立的。 有关更多信息,请参阅CLR中的未处理的exception处理 。
通常,当一个未处理的exception结束一个应用程序时,是否运行finally
块并不重要。 但是,如果在这种情况下必须运行的finally
块中有语句,则一种解决scheme是将try-finally
块添加到try-finally
语句中。 或者,您可以捕获可能在调用堆栈上方try-finally
语句的try
块中抛出的exception。 也就是说,您可以在调用包含try-finally
语句的方法或调用该方法的方法中或调用堆栈中的任何方法中捕获exception。 如果没有捕获exception, finally
块的执行取决于操作系统是否select触发exception展开操作。
public class ThrowTestA { static void Main() { int i = 123; string s = "Some string"; object obj = s; try { // Invalid conversion; obj contains a string, not a numeric type. i = (int)obj; // The following statement is not run. Console.WriteLine("WriteLine at the end of the try block."); } finally { // To run the program in Visual Studio, type CTRL+F5. Then // click Cancel in the error dialog. Console.WriteLine("\nExecution of the finally block after an unhandled\n" + "error depends on how the exception unwind operation is triggered."); Console.WriteLine("i = {0}", i); } } // Output: // Unhandled Exception: System.InvalidCastException: Specified cast is not valid. // // Execution of the finally block after an unhandled // error depends on how the exception unwind operation is triggered. // i = 123 }
在下面的示例中,TryCast方法的exception在调用堆栈上方的方法中捕获。 C#
public class ThrowTestB { static void Main() { try { // TryCast produces an unhandled exception. TryCast(); } catch (Exception ex) { // Catch the exception that is unhandled in TryCast. Console.WriteLine ("Catching the {0} exception triggers the finally block.", ex.GetType()); // Restore the original unhandled exception. You might not // know what exception to expect, or how to handle it, so pass // it on. throw; } } public static void TryCast() { int i = 123; string s = "Some string"; object obj = s; try { // Invalid conversion; obj contains a string, not a numeric type. i = (int)obj; // The following statement is not run. Console.WriteLine("WriteLine at the end of the try block."); } finally { // Report that the finally block is run, and show that the value of // i has not been changed. Console.WriteLine("\nIn the finally block in TryCast, i = {0}.\n", i); } } // Output: // In the finally block in TryCast, i = 123. // Catching the System.InvalidCastException exception triggers the finally block. // Unhandled Exception: System.InvalidCastException: Specified cast is not valid. }
啊…我想我明白你在说什么了! 花了我一会儿…你想知道“为什么把它放在finally块中,而不是在finally块之后,完全在try-catch-finally之外”。
举个例子,这可能是因为如果抛出一个错误,你正在停止执行,但是你仍然要清理资源,比如打开文件,数据库连接等。
最后阻止
如果在退出Try
结构之前必须运行一个或多个语句, Try
使用Finally
块。 Finally
块对于运行即使有exception也必须执行的代码是很有用的。 无论Try
… Catch
块如何退出,控制都被传递给Finally
块。 控制权在传递出Try
… Catch
结构之前传递给Finally
块。 即使Try
结构中的任何地方出现exception,情况也是如此。 即使您的代码在Try
或Catch
块中遇到Return
语句,也会运行Finally
块中的代码。
将执行显式传送到Finally
块是无效的。
从Finally
一个块中移出执行是无效的,除非通过例外。
最后一个块的控制stream程是在Try或Catch块之后。
[1. First Code] [2. Try] [3. Catch] [4. Finally] [5. After Code]
如果3具有返回语句1> 2> 3> 4,则例外1> 2> 3> 4> 5
没有例外1> 2> 4> 5如果2有返回语句1> 2> 4