try {
// Do stuff
}
catch (Exception e) {
throw;
}
finally {
// Clean up
}
Trong khối trên, khối cuối cùng được gọi là khi nào? Trước khi ném e hay cuối cùng cũng được gọi rồi bắt?
try {
// Do stuff
}
catch (Exception e) {
throw;
}
finally {
// Clean up
}
Trong khối trên, khối cuối cùng được gọi là khi nào? Trước khi ném e hay cuối cùng cũng được gọi rồi bắt?
Câu trả lời:
Nó sẽ được gọi sau khi e được ném lại (tức là sau khi khối bắt được thực thi)
chỉnh sửa 7 năm sau - một lưu ý quan trọng là nếu e
không bị chặn bởi một khối thử / bắt tiếp tục lên ngăn xếp cuộc gọi hoặc được xử lý bởi một trình xử lý ngoại lệ toàn cầu, thì finally
khối đó có thể không bao giờ thực hiện được.
finally
là không thực thi nếu ngoại lệ ném vào trước catch
không bao giờ bắt gặp trong một bên ngoài try
- catch
khối!
Tại sao không thử nó:
outer try
inner try
inner catch
inner finally
outer catch
outer finally
với mã (được định dạng cho không gian dọc):
static void Main() {
try {
Console.WriteLine("outer try");
DoIt();
} catch {
Console.WriteLine("outer catch");
// swallow
} finally {
Console.WriteLine("outer finally");
}
}
static void DoIt() {
try {
Console.WriteLine("inner try");
int i = 0;
Console.WriteLine(12 / i); // oops
} catch (Exception e) {
Console.WriteLine("inner catch");
throw e; // or "throw", or "throw anything"
} finally {
Console.WriteLine("inner finally");
}
}
outer try
inner try
inner catch
Unhandled Exception: System.DivideByZeroException...
Sau khi đọc tất cả các câu trả lời ở đây, có vẻ như câu trả lời cuối cùng là tùy thuộc vào :
Nếu bạn ném lại một ngoại lệ trong khối bắt và ngoại lệ đó được bắt vào bên trong một khối bắt khác, mọi thứ sẽ thực thi theo tài liệu.
Tuy nhiên, nếu ngoại lệ trown lại được xử lý, cuối cùng không bao giờ thực thi.
Tôi đã thử nghiệm mẫu mã này trong VS2010 w / C # 4.0
static void Main()
{
Console.WriteLine("Example 1: re-throw inside of another try block:");
try
{
Console.WriteLine("--outer try");
try
{
Console.WriteLine("----inner try");
throw new Exception();
}
catch
{
Console.WriteLine("----inner catch");
throw;
}
finally
{
Console.WriteLine("----inner finally");
}
}
catch
{
Console.WriteLine("--outer catch");
// swallow
}
finally
{
Console.WriteLine("--outer finally");
}
Console.WriteLine("Huzzah!");
Console.WriteLine();
Console.WriteLine("Example 2: re-throw outside of another try block:");
try
{
Console.WriteLine("--try");
throw new Exception();
}
catch
{
Console.WriteLine("--catch");
throw;
}
finally
{
Console.WriteLine("--finally");
}
Console.ReadLine();
}
Đây là đầu ra:
Ví dụ 1: ném lại bên trong một khối thử khác:
- thử thử
---- thử
bên trong
---- bắt bên trong ---- cuối cùng bên trong -
bắt
đồ - cuối cùng là
Huzzah!Ví dụ 2: ném lại bên ngoài khối thử khác:
--try
--catchNgoại lệ chưa được xử lý: System.Exception: Ngoại lệ của loại 'System.Exception' đã bị ném.
tại ConsoleApplication1.Program.Main () trong C: \ local source \ ConsoleApplication1 \ Program.cs: dòng 53
Ví dụ của bạn sẽ hành xử giống hệt với mã này:
try {
try {
// Do stuff
} catch(Exception e) {
throw e;
}
} finally {
// Clean up
}
Như một lưu ý phụ, nếu bạn thực sự có ý nghĩa throw e;
( nghĩa là ném ngoại lệ giống như bạn vừa bắt), sẽ tốt hơn nhiều nếu chỉ throw;
giữ lại dấu vết ngăn xếp ban đầu thay vì tạo một dấu vết mới.
finally
khối trong thực tế sẽ chạy sau khi catch
khối (ngay cả khi khối catch rethrows ngoại trừ), đó là những gì đoạn tôi đang cố gắng để minh họa.
try
khối câu trả lời của tôi có một "thử bắt". Tôi đang cố gắng giải thích hành vi của cấu trúc 3 phần bằng cách sử dụng hai cấu trúc 2 phần. Tôi không thấy bất kỳ dấu hiệu nào của try
khối thứ hai trong câu hỏi ban đầu, vì vậy tôi không hiểu bạn đang lấy nó ở đâu.
Nếu có một ngoại lệ chưa được xử lý trong khối xử lý bắt, khối cuối cùng được gọi chính xác là 0 lần
static void Main(string[] args)
{
try
{
Console.WriteLine("in the try");
int d = 0;
int k = 0 / d;
}
catch (Exception e)
{
Console.WriteLine("in the catch");
throw;
}
finally
{
Console.WriteLine("In the finally");
}
}
Đầu ra:
C: \ users \ Administrator \ Documents \ TestExceptionNesting \ bin \ Release> TestExceptionNesting.exe
trong thử
trong cái bẫy
Ngoại lệ chưa được xử lý: System.DivideByZeroException: Đã cố chia cho số không. tại TestExceptionNesting.Program.Main (String [] args) trong C: \ users \ Administrator \ Documents \ TestExceptionNesting \ TestExceptionNesting.cs: dòng 22
C: \ users \ Administrator \ Documents \ TestExceptionNesting \ bin \ release>
Tôi đã được hỏi câu hỏi này ngày hôm nay tại một cuộc phỏng vấn và người phỏng vấn tiếp tục quay lại "bạn có chắc chắn cuối cùng không được gọi không?" Tôi không chắc đó có phải là một câu hỏi mẹo hay người phỏng vấn có ý định gì khác và đã viết mã sai để tôi gỡ lỗi nên tôi về nhà và thử nó (xây dựng và chạy, không tương tác với trình gỡ lỗi), chỉ để tôi suy nghĩ nghỉ ngơi.
Thử nghiệm với Ứng dụng Bảng điều khiển C #, mã cuối cùng đã được thực thi sau khi ném ngoại lệ: "Hộp thoại Lỗi ứng dụng" tồn tại và sau khi bạn chọn tùy chọn "Đóng chương trình", khối cuối cùng đã được thực thi trong cửa sổ bảng điều khiển đó. Nhưng thiết lập điểm phá vỡ bên trong khối mã cuối cùng, tôi không bao giờ có thể đánh nó. Trình gỡ lỗi tiếp tục dừng lại ở tuyên bố ném. Đây là mã kiểm tra của tôi:
class Program
{
static void Main(string[] args)
{
string msg;
Console.WriteLine(string.Format("GetRandomNuber returned: {0}{1}", GetRandomNumber(out msg), msg) == "" ? "" : "An error has occurred: " + msg);
}
static int GetRandomNumber(out string errorMessage)
{
int result = 0;
try
{
errorMessage = "";
int test = 0;
result = 3/test;
return result;
}
catch (Exception ex)
{
errorMessage = ex.Message;
throw ex;
}
finally
{
Console.WriteLine("finally block!");
}
}
}
Gỡ lỗi trong VS2010 - .NET Framework 4.0