XỬ LÝ NGOẠI LỆ phần 2
Số trang: 12
Loại file: pdf
Dung lượng: 188.42 KB
Lượt xem: 10
Lượt tải: 0
Xem trước 2 trang đầu tiên của tài liệu này:
Thông tin tài liệu:
Lúc này ngoại lệ không được xử lý bên trong hàm Func2(), mà nó được xử lý bên trong hàm Func1(). Khi hàm Func2() được gọi, nó in câu lệnh thông báo vào hàm rồi phát sinh một ngoại lệ. Việc thực hiện chương trình bị ngưng
Nội dung trích xuất từ tài liệu:
XỬ LÝ NGOẠI LỆ phần 2Lúc này ngoại lệ không được xử lý bên trong hàm Func2(), mà nó được xử lý bêntrong hàm Func1(). Khi hàm Func2() được gọi, nó in câu lệnh thông báo vào hàmrồi phát sinh một ngoại lệ. Việc thực hiện chương trình bị ngưng, CLR tìm kiếmphần xử lý ngoại lệ, nhưng trong hàm này không có và CLR vào stack lấy hàm gọitrong trường hợp này là Func1(). Câu lệnh catch sẽ được gọi, và việc thực thi tiếp tụcthực hiện bình thường sau câu lệnh catch.Hãy chắc chắn rằng chúng ta đã hiểu rõ tại sao câu lệnh “Exiting try block” và “ExitFunc2” không được in ra. Chúng ta có thể dùng cách cũ để kiểm tra việc này bằngcách dùng chương trình debug cho chương trình chạy từng bước để tìm hiểu rõ hơn. Tạo một khối catch xác định:Cho đến bây giờ chúng ta chỉ dùng khối catch tổng quát, tức là với bất cứ ngoại lệnào cũng được. Tuy nhiên chúng ta có thể tạo ra khối catch xác định để xử lý chỉ mộtvài các ngoại lệ chứ không phải toàn bộ ngoại lệ, dựa trên kiểu của ngoại lệ phátsinh. Ví dụ 13.4 minh họa cách xác định loại ngoại lệ mà chúng ta xử lý. Ví dụ13.4: Xác định ngoại lệ để bắt.-----------------------------------------------------------------------------namespace Programming_CSharp{ using System; public class Test{ public static void Main() { Test t = new Test(); t.TestFunc(); } // ta thử chia hai phần xử lý ngoại lệ riêng public void TestFunc() { try { double a = 5; double b = 0; Console.WriteLine(“{0} / {1} = {2}”, a, b, DoDivide(a,b)); } catch (System.DivideByZeroException) { Console.WriteLine(“DivideByZeroException caught!”); } catch (System.ArithmeticException) { Console.WriteLine(“ArithmeticException caught!”); } catch { Console.WriteLine(“Unknown exception caught”); } } } // thực hiện phép chia hợp lệ public double DoDivide(double a, double b) { if ( b == 0) throw new System.DivideByZeroException(); if ( a == 0) throw new System.ArithmeticException(); return a/b; }}----------------------------------------------------------------------------- Kết quả:DivideByZeroException caught!-----------------------------------------------------------------------------Trong ví dụ này, phương thức DoDivide() sẽ không cho phép chúng ta chia cho zerobởi một số khác, và cũng không cho phép chia số zero. Nó sẽ phát sinh một đối tượngcủa Divide- ByzeroException nếu chúng ta thực hiện chia với zero. Trong toán học việclấy zero chia cho một số khác là được phép, nhưng trong ví dụ minh họa của chúng takhông cho phép thực hiện việc này, nếu thực hiện sẽ phát sinh ra một ngoại lệArithmeticException.Khi một ngoại lệ được phát sinh, CLR sẽ kiểm tra mỗi khối xử lý ngoại lệ theo thứ tựvà sẽ lấy khối đầu tiên thích hợp. Khi chúng ta thực hiện với a=5 và b=7 thì kết quả nhưsau: 5 / 7 = 0.7142857142857143Như chúng ta mong muốn, không có ngoại lệ được phát sinh. Tuy nhiên, khi chúng tathay đổi giá trị của a là 0, thì kết quả là: ArithmeticException caught!Ngoại lệ được phát sinh, và CLR sẽ kiểm tra ngoại lệ đầu tiên:DivideByZeroException. Bởi vì không phù hợp, nên nó sẽ tiếp tục đi tìm và khối xử lýArithmeticException được chọn.Cuối cùng, giả sử chúng ta thay đổi giá trị của b là 0. Khi thực hiện điều này sẽ dẫn đếnngoạilệ DivideByZeroException. Ghi chú: Chúng ta phải cẩn thận thứ tự của câu lệnh catch, bởi vì DivideByZero- Exception được dẫn xuất từ ArithmeticException. Nếu chúng ta đảo thứ tự của câu lệnh catch, thì ngoại lệ DivideByZeroException sẽ được phù hợp với khối xử lý ngoại lệ Arith- meticException. Và việc xử lý ngoại lệ sẽ không bao giờ được giao cho khối xử lý DivideByZeroException. Thật vậy, nếu thứ tự này được đảo, nó sẽ không cho phép bất cứ ngoại lệ nào được xử lý bởi khối xử lý ngoại lệ DivideByZeroException. Trình biên dịch sẽ nhận ra rằng DivideByZeroException không được thực hiện bất cứ khi nào và nó sẽ thông báo một lỗi biên dịch.Chúng ta có thể phân phối câu lệnh try/ catch, bằng cách bắt giữ những ngoại lệxác định trong một hàm và nhiều ngoại lệ tổng quát trong nhiều hàm. Mục đích củathực hiện này là đưa ra các thiết kế đúng. Giả sử chúng ta có phương thức A, phươngthức này gọi một phương thức khác tên là phương thức B, đến lượt mình phương thứcB gọi phương thức C. Và phương thức C tiếp tục gọi phương thức D, cuối cùngphương thức D gọi phương thức E. Phương thức E ở mức độ sâu nhất trong chươngtrình của chúng ta, phương thức A, B ở mức độ cao hơn. Nếu chúng ta đoán trướcphương thức E có thể phát sinh ra ngoại lệ, chúng ta có thể tạo ra khối try/catch đểbắt giữ những ngoại lệ này ở chỗ gần nơi phát sinh ra ngoại lệ nhất. Chúng ta cũng cóthể tạo ra nhiều khối xử lý ngoại lệ chung ở trong đoạn chương trình ở mức caotrong trường hợp những ngoại lệ không đoán trước được.Câu lệnh finally Trong một số tình huống, việc phát sinh ngoại lệ và unwind stack có thể tạo ra một số vấnđề. Ví dụ như nếu chúng ta mở một tập tin hay trường hợp khác là xác nhận một tàinguyên, chúng ta có thể cần thiết một cơ hội để đóng một tập tin hay là giải phóngbộ nhớ đệm mà chương trình đã chiếm giữ trước đó. Ghi chú: Trong ngôn ngữ C#, vấn đề này ít xảy ra hơn do cơ chế thu dọn tự động của C# ngăn ngừa những ngoại lệ phát sinh từ việc thiếu bộ nhớ. Tuy nhiên, có một số hành động mà chúng ta cần phải quan tâm bất cứ khi nào một ngoạilệ được phát sinh ra, như việc đóng một tập tin, chúng ta có hai chiến lược để lựachọn thực hiện. Một hướng tiếp cận là đưa hành động nguy hiểm vào trong khối tryvà sau đó thực hiện việc đóng tập tin trong cả hai khối catch và try. Tuy nhiên,điều này gây ra đoạn chươn ...
Nội dung trích xuất từ tài liệu:
XỬ LÝ NGOẠI LỆ phần 2Lúc này ngoại lệ không được xử lý bên trong hàm Func2(), mà nó được xử lý bêntrong hàm Func1(). Khi hàm Func2() được gọi, nó in câu lệnh thông báo vào hàmrồi phát sinh một ngoại lệ. Việc thực hiện chương trình bị ngưng, CLR tìm kiếmphần xử lý ngoại lệ, nhưng trong hàm này không có và CLR vào stack lấy hàm gọitrong trường hợp này là Func1(). Câu lệnh catch sẽ được gọi, và việc thực thi tiếp tụcthực hiện bình thường sau câu lệnh catch.Hãy chắc chắn rằng chúng ta đã hiểu rõ tại sao câu lệnh “Exiting try block” và “ExitFunc2” không được in ra. Chúng ta có thể dùng cách cũ để kiểm tra việc này bằngcách dùng chương trình debug cho chương trình chạy từng bước để tìm hiểu rõ hơn. Tạo một khối catch xác định:Cho đến bây giờ chúng ta chỉ dùng khối catch tổng quát, tức là với bất cứ ngoại lệnào cũng được. Tuy nhiên chúng ta có thể tạo ra khối catch xác định để xử lý chỉ mộtvài các ngoại lệ chứ không phải toàn bộ ngoại lệ, dựa trên kiểu của ngoại lệ phátsinh. Ví dụ 13.4 minh họa cách xác định loại ngoại lệ mà chúng ta xử lý. Ví dụ13.4: Xác định ngoại lệ để bắt.-----------------------------------------------------------------------------namespace Programming_CSharp{ using System; public class Test{ public static void Main() { Test t = new Test(); t.TestFunc(); } // ta thử chia hai phần xử lý ngoại lệ riêng public void TestFunc() { try { double a = 5; double b = 0; Console.WriteLine(“{0} / {1} = {2}”, a, b, DoDivide(a,b)); } catch (System.DivideByZeroException) { Console.WriteLine(“DivideByZeroException caught!”); } catch (System.ArithmeticException) { Console.WriteLine(“ArithmeticException caught!”); } catch { Console.WriteLine(“Unknown exception caught”); } } } // thực hiện phép chia hợp lệ public double DoDivide(double a, double b) { if ( b == 0) throw new System.DivideByZeroException(); if ( a == 0) throw new System.ArithmeticException(); return a/b; }}----------------------------------------------------------------------------- Kết quả:DivideByZeroException caught!-----------------------------------------------------------------------------Trong ví dụ này, phương thức DoDivide() sẽ không cho phép chúng ta chia cho zerobởi một số khác, và cũng không cho phép chia số zero. Nó sẽ phát sinh một đối tượngcủa Divide- ByzeroException nếu chúng ta thực hiện chia với zero. Trong toán học việclấy zero chia cho một số khác là được phép, nhưng trong ví dụ minh họa của chúng takhông cho phép thực hiện việc này, nếu thực hiện sẽ phát sinh ra một ngoại lệArithmeticException.Khi một ngoại lệ được phát sinh, CLR sẽ kiểm tra mỗi khối xử lý ngoại lệ theo thứ tựvà sẽ lấy khối đầu tiên thích hợp. Khi chúng ta thực hiện với a=5 và b=7 thì kết quả nhưsau: 5 / 7 = 0.7142857142857143Như chúng ta mong muốn, không có ngoại lệ được phát sinh. Tuy nhiên, khi chúng tathay đổi giá trị của a là 0, thì kết quả là: ArithmeticException caught!Ngoại lệ được phát sinh, và CLR sẽ kiểm tra ngoại lệ đầu tiên:DivideByZeroException. Bởi vì không phù hợp, nên nó sẽ tiếp tục đi tìm và khối xử lýArithmeticException được chọn.Cuối cùng, giả sử chúng ta thay đổi giá trị của b là 0. Khi thực hiện điều này sẽ dẫn đếnngoạilệ DivideByZeroException. Ghi chú: Chúng ta phải cẩn thận thứ tự của câu lệnh catch, bởi vì DivideByZero- Exception được dẫn xuất từ ArithmeticException. Nếu chúng ta đảo thứ tự của câu lệnh catch, thì ngoại lệ DivideByZeroException sẽ được phù hợp với khối xử lý ngoại lệ Arith- meticException. Và việc xử lý ngoại lệ sẽ không bao giờ được giao cho khối xử lý DivideByZeroException. Thật vậy, nếu thứ tự này được đảo, nó sẽ không cho phép bất cứ ngoại lệ nào được xử lý bởi khối xử lý ngoại lệ DivideByZeroException. Trình biên dịch sẽ nhận ra rằng DivideByZeroException không được thực hiện bất cứ khi nào và nó sẽ thông báo một lỗi biên dịch.Chúng ta có thể phân phối câu lệnh try/ catch, bằng cách bắt giữ những ngoại lệxác định trong một hàm và nhiều ngoại lệ tổng quát trong nhiều hàm. Mục đích củathực hiện này là đưa ra các thiết kế đúng. Giả sử chúng ta có phương thức A, phươngthức này gọi một phương thức khác tên là phương thức B, đến lượt mình phương thứcB gọi phương thức C. Và phương thức C tiếp tục gọi phương thức D, cuối cùngphương thức D gọi phương thức E. Phương thức E ở mức độ sâu nhất trong chươngtrình của chúng ta, phương thức A, B ở mức độ cao hơn. Nếu chúng ta đoán trướcphương thức E có thể phát sinh ra ngoại lệ, chúng ta có thể tạo ra khối try/catch đểbắt giữ những ngoại lệ này ở chỗ gần nơi phát sinh ra ngoại lệ nhất. Chúng ta cũng cóthể tạo ra nhiều khối xử lý ngoại lệ chung ở trong đoạn chương trình ở mức caotrong trường hợp những ngoại lệ không đoán trước được.Câu lệnh finally Trong một số tình huống, việc phát sinh ngoại lệ và unwind stack có thể tạo ra một số vấnđề. Ví dụ như nếu chúng ta mở một tập tin hay trường hợp khác là xác nhận một tàinguyên, chúng ta có thể cần thiết một cơ hội để đóng một tập tin hay là giải phóngbộ nhớ đệm mà chương trình đã chiếm giữ trước đó. Ghi chú: Trong ngôn ngữ C#, vấn đề này ít xảy ra hơn do cơ chế thu dọn tự động của C# ngăn ngừa những ngoại lệ phát sinh từ việc thiếu bộ nhớ. Tuy nhiên, có một số hành động mà chúng ta cần phải quan tâm bất cứ khi nào một ngoạilệ được phát sinh ra, như việc đóng một tập tin, chúng ta có hai chiến lược để lựachọn thực hiện. Một hướng tiếp cận là đưa hành động nguy hiểm vào trong khối tryvà sau đó thực hiện việc đóng tập tin trong cả hai khối catch và try. Tuy nhiên,điều này gây ra đoạn chươn ...
Tìm kiếm theo từ khóa liên quan:
Công nghệ thông tin kỹ thuật lập trình ngôn ngữ lập trình ngôn ngữ C# C# XỬ LÝ NGOẠI LỆ phần 2Gợi ý tài liệu liên quan:
-
52 trang 429 1 0
-
Top 10 mẹo 'đơn giản nhưng hữu ích' trong nhiếp ảnh
11 trang 312 0 0 -
74 trang 294 0 0
-
96 trang 291 0 0
-
Báo cáo thực tập thực tế: Nghiên cứu và xây dựng website bằng Wordpress
24 trang 288 0 0 -
Đồ án tốt nghiệp: Xây dựng ứng dụng di động android quản lý khách hàng cắt tóc
81 trang 278 0 0 -
EBay - Internet và câu chuyện thần kỳ: Phần 1
143 trang 274 0 0 -
Giáo trình Lập trình hướng đối tượng: Phần 2
154 trang 271 0 0 -
Tài liệu dạy học môn Tin học trong chương trình đào tạo trình độ cao đẳng
348 trang 269 1 0 -
Bài thuyết trình Ngôn ngữ lập trình: Hệ điều hành Window Mobile
30 trang 263 0 0