1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Giáo trình hướng dẫn tìm hiểu phương thức DoDivide trong hệ thống CLR phần 1 pot

9 302 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 9
Dung lượng 1,38 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Trong toán học việc lấ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 ta khô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ệ Arit

Trang 1

}

DivideByZeroException caught!

-Trong ví dụ này, phương thức DoDivide() sẽ không cho phép chúng ta chia cho zero bở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ượng của

Divide-ByzeroException nếu chúng ta thực hiện chia với zero Trong toán học việc lấ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 ta khô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.7142857142857143

Như chúng ta mong muốn, không có ngoại lệ được phát sinh Tuy nhiên, khi chúng ta thay

đổ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 đến ngoại

lệ DivideByZeroException

DivideByZero-Exception được dẫn xuất từ ArithmeticException Nếu chúng ta đảo thứ tự của câu lệnh

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ủa thự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ương thứ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ức B 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ùng phương thức D gọi phương thức E Phương thức

E ở mức độ sâu nhất trong chương trì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ước phương thức E có thể phát sinh ra ngoại lệ, chúng ta có thể tạo ra

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 cao

trong trường hợp những ngoại lệ không đoán trước được

Giáo trình hướng dẫn tìm hiểu phương

thức DoDivide trong hệ thống CLR

Trang 2

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ài nguyê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óng bộ nhớ đệm mà

chương trình đã chiếm giữ trướ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ại

lệ được phát sinh ra, như việc đóng một tập tin, chúng ta có hai chiến lược để lựa chọ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 try và sau đó thực hiện

việc đóng tập tin trong cả hai khối catch try Tuy nhiên, điều này gây ra đoạn chương

trình không được đẹp do sử dụng trùng lắp lệnh Ngôn ngữ C# cung cấp một sự thay thế tốt

hơn trong khối finally

Đoạn chương trình bên trong khối catch được đảm bảo thực thi mà không quan tâm đến việc khi nào thì một ngoại lệ được phát sinh Phương thức TestFunc() trong ví dụ 13.5 minh

họa việc mở một tập tin như là hành động đầu tiên của nó, sau đó phương thức thực hiện một

vài các phép toán toán học, và sau đó là tập tin được đóng Có thể trong quá trình mở tập tin

cho đến khi đóng tập tin chương trình phát sinh ra một ngoại lệ Nếu xuất hiện ngoại lệ, và

khi đó tập tin vẫn còn mở Người phát triển biết rằng không có chuyện gì xảy ra, và cuối của

phương thức này thì tập tin sẽ được đóng Do chức năng đóng tập tin được di chuyển vào

trong khối finally, ở đây nó sẽ được thực thi mà không cần quan tâm đến việc có phát sinh

hay không một ngoại lệ trong chương trình

-namespace Programming_CSharp

{

using System;

public class Test {

public static void Main() {

Test t = new Test();

t.TestFunc();

} // chia hai số và xử lý ngoại lệ nếu có public void TestFunc()

{ try

Trang 3

Console.WriteLine(“Open file here”);

double a = 5;

double b = 0;

Console.WriteLine(“{0} /{1} = {2}”, a, b, DoDivide(a,b));

Console.WriteLine(“This line may or not print”);

} catch (System.DivideByZeroException) {

Console.WriteLine(“DivideByZeroException caught!”);

} catch {

Console.WriteLine(“Unknown exception caught”);

} finally {

Console.WriteLine(“Close file here.”);

} } // thực hiện chia nếu 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;

} }

}

Trang 4

DivideByZeroException caught!

Close file here.

Kết quả trong trường hợp b = 12

Open file here

5/ 12 = 0.416666666666

Close file here

-Trong ví dụ này một khối catch được loại bỏ và thêm vào khối finally Bất cứ khi một ngoại

lệ có được phát sinh ra hay không thì khối lệnh bên trong finally cũng được thực thi Do vậy

nên trong cả hai trường hợp ta cũng thấy xuất hiện thông điệp “Close file here”.

Những đối tượng ngoại lệ

Cho đến lúc này thì chúng ta có thể sử dụng tốt các ngoại lệ cũng như cách xử lý khắc phục các ngoại lệ này Trong phần này chúng ta sẽ tiến hành việc tìm hiểu các đối tượng được

xây dựng cho việc xử lý ngoại lệ Đối tượng System.Exception cung cấp một số các phương

thức và thuộc tính hữu dụng Thuộc tính Message cung cấp thông tin về ngoại lệ, như là lý do

tại sao ngoại lệ được phát sinh Thuộc tính Message là thuộc tính chỉ đọc, đoạn chương trình

phát sinh ngoại lệ có thể thiết lập thuộc tính Message như là một đối mục cho bộ khởi dựng

của ngoại lệ Thuộc tính HelpLink cung cấp một liên kết để trợ giúp cho các tập tin liên quan

đến các ngoại lệ Đây là thuộc tính chỉ đọc Thuộc tính StackTrace cũng là thuộc tính chỉ đọc

và được thiết lập bởi CLR Trong ví dụ 13.6 thuộc tính Exception.HelpLink được thiết lập và

truy cập để cung cấp thông tin cho người sử dụng về ngoại lệ DivideBy-ZeroException

Thuộc tính StackTrace của ngoại lệ được sử dụng để cung cấp thông tin stack cho câu lệnh

lỗi Một thông tin stack cung cấp hàng loạt các cuộc gọi stack của phương thức gọi mà dẫn

đến những ngoại lệ được phát sinh

-namespace Programming_CSharp

{ using System;

public class Test {

public static void Main() {

Test t = new Test();

t.TestFunc();

} // chia hai số và xử lý ngoại lệ

Trang 5

public void TestFunc() {

try { Console.WriteLine(“Open file here”);

double a = 12;

double b = 0;

Console.WriteLine(“{0} /{1} = {2}”, a, b, DoDivide(a,b));

Console.WriteLine(“This line may or not print”);

} catch (System.DivideByZeroException e) {

Console.WriteLine(“\nDivideByZeroException! Msg: {0}”, e.Message);

Console.WriteLine(“\nHelpLink: {0}”, e.HelpLink);

Console.WriteLine(“\nHere’s a stack trace: {0}\n”, e.StackTrace);

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

{ DivideByZeroException e = new DivideByZeroException();

e.HelpLink = “http://www.hcmunc.edu.vn”;

throw e;

}

if ( a == 0) {

throw new ArithmeticException();

} return a/b;

} } }

Trang 6

Open file here

DivideByZeroExceptión Msg: Attempted to divide by zero

HelpLink: http://www.hcmuns.edu.vn

Here’s a stack trace:

at Programming_CSharp.Test.DoDivide(Double c, Double b)

in c:\ exception06.cs: line 56

at Programming_CSharp.Test.TestFunc() in exception06.cs: line 22.

Close file here

-Trong đoạn kết quả trên, danh sách trace của stack được hiển thị theo thứ tự ngược lại thứ tự

gọi Nó hiển thị một lỗi trong phương thức DoDivde(), phương thức này được gọi từ phương

thức TestFunc() Khi các phương thức gọi lồng nhau nhiều cấp, thông tin stack có thể giúp

chúng ta hiểu thứ tự của các phương thức được gọi

Trong ví dụ này, hơn là việc đơn giản phát sinh một DidiveByZeroException, chúng ta tạo

một thể hện mới của ngoại lệ:

DivideByZeroException e = new DivideByZeroException();

Chúng ta không truyền vào thông điệp của chúng ta, nên thông điệp mặc định sẽ được in ra:

DivideByZeroException! Msg: Attemped to divide by zero.

Ở đây chúng ta có thể bổ sung như dòng lệnh bên dưới để truyền vào thông điệp của chúng ta

tùy chọn như sau:

new DivideByZeroException(“You tried to divide by zero which is not meaningful”);

Trước khi phát sinh ra ngoại lệ, chúng ta thiết lập thuộc tính HelpLink như sau:

e.HelpLink = “http://www.hcmunc.edu.vn”;

Khi ngoại lệ được bắt giữ, chương trình sẽ in thông điệp và HelpLink ra màn hình:

catch (System.DivideByZeroException e) {

Console.WriteLine(“\nDivideByZeroException! Msg: {0}”, e.Message);

Console.WriteLine(“\nHelpLink: {0}”, e.HelpLink);

}

Việc làm này cho phép chúng ta cung cấp những thông tin hữu ích cho người sử dụng Thêm

vào đó thông tin stack cũng được đưa ra bằng cách sử dụng thuộc tính StackTrace của đối

tượng ngoại lệ:

Console.WriteLine(“\n Here’s a stack trace: {0}\n”, e.StackTrace);

Kết quả là các vết trong stack sẽ được xuất ra:

Here’s a stack trace:

at Programming_CSharp.Test.DoDivide(Double c, Double b)

Trang 7

in c:\ exception06.cs: line 56

at Programming_CSharp.Test.TestFunc() in exception06.cs: line 22.

Lưu ý rằng, phần đường dẫn được viết tắt, do đó kết quả của bạn có thể hơi khác một tí

Bảng 13.1 sau mô tả một số các lớp ngoại lệ chung được khai báo bên trong namespace

System.

CÁC LỚP NGOẠI LỆ

MethodAccessException Lỗi truy cập, do truy cập đến thành viên hay

phương thức không được truy cập

ArgumentNullException Đối mục Null, phương thức được truyền đối mục

null không được chấp nhận

ArithmeticException Lỗi liên quan đến các phép toán

ArrayTypeMismatchException Kiểu mảng không hợp, khi cố lưu trữ kiểu không

thích hợp vào mảng

DivideByZeroException Lỗi chia zero

FormatException Định dạng không chính xác một đối mục nào đó

IndexOutOfRangeException Chỉ số truy cập mảng không hợp lệ, dùng nhỏ hơn

chỉ số nhỏ nhất hay lớn hơn chỉ số lớn nhất của mảng

InvalidCastException Phép gán không hợp lệ

MulticastNotSupportedException Multicast không được hỗ trợ, do việc kết hợp hai

delegate không đúng

NotFiniteNumberException Không phải số hữu hạn, số không hợp lệ

NotSupportedException Phương thức không hỗ trợ, khi gọi một phương

thức không tồn tại bên trong lớp

NullReferenceException Tham chiếu null không hợp lệ

OutOfMemoryException Out of memory

OverflowException Lỗi tràn phép toán

StackOverflowException Tràn stack TypeInitializationException Kiểu khởi tạo sai, khi bộ khởi dựng tĩnh có lỗi

Bảng 13.1 : Các ngoại lệ thường xuất hiện.

Tạo riêng các ngoại lệ

CLR cung cấp những kiểu dữ liệu ngoại lệ cơ bản, trong ví dụ trước chúng ta đã tạo một vài các kiểu ngoại lệ riêng Thông thường chúng ta cần thiết phải cung cấp các thông tin mở

rộng cho khối catch khi một ngoại lệ được phát sinh Tuy nhiên, có những lúc chúng ta

Trang 8

muốn cung cấp nhiều thông tin mở rộng hay là các khả năng đặc biệt cần thiết trong ngoại lệ

mà chúng ta tạo ra Chúng ta dễ dàng tạo ra các ngoại lệ riêng, hay còn gọi là các ngoại lệ tùy

chọn (custom exception), điều bắt buộc với các ngoại lệ này là chúng phải được dẫn xuất từ

System.ApplicationException Ví dụ 13.7 sau minh họa việc tạo một ngoại lệ riêng

-namespace Programming_CSharp

{

using System;

// tạo ngoại lệ riêng public class MyCustomException : System.ApplicationException {

public MyCustomException( string message): base(message) {

} }

public class Test {

public static void Main() {

Test t = new Test();

t.TestFunc();

} // chia hai số và xử lý ngoại lệ public void TestFunc()

{ try { Console.WriteLine(“Open file here”);

double a = 0;

double b = 5;

Console.WriteLine(“{0} /{1} = {2}”, a, b, DoDivide(a,b));

Console.WriteLine(“This line may or not print”);

} catch (System.DivideByZeroException e) {

Console.WriteLine(“\nDivideByZeroException! Msg: {0}”, e.Message);

Trang 9

Console.WriteLine(“\nHelpLink: {0}”, e.HelpLink);

} catch (MyCustomException e) {

Console.WriteLine(“\nMyCustomException! Msg: {0}”, e.Message);

Console.WriteLine(“\nHelpLink: {0}”, e.HelpLink);

} catch { Console.WriteLine(“Unknown excepiton caught”);

} finally { Console.WriteLine(“Close file here.”);

} } // thực hiện phép chia hợp lệ public double DoDivide( double a, double b) {

if ( b == 0)

{ DivideByZeroException e = new DivideByZeroException();

e.HelpLink = “http://www.hcmunc.edu.vn”;

throw e;

}

if ( a == 0) {

MyCustomException e = new MyCustomException(“Can’t have zero divisor”);

e.HelpLink = “http://www.hcmuns.edu.vn”;

throw e;

} return a/b;

} }

}

Ngày đăng: 14/08/2014, 17:20

HÌNH ẢNH LIÊN QUAN

Bảng 13.1 sau mô tả một số các lớp ngoại lệ chung được khai báo bên trong namespace - Giáo trình hướng dẫn tìm hiểu phương thức DoDivide trong hệ thống CLR phần 1 pot
Bảng 13.1 sau mô tả một số các lớp ngoại lệ chung được khai báo bên trong namespace (Trang 7)

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm