
Những chủ đề tiến bộ trong C#
Lỗi và xử lí biệt lệ - Phần 2
Giả sử rằng người sử dụng gõ 1 số mà không nằm giữa 0 và 5 . điều này
được đón bởi câu lệnh if và 1 đối tượng IndexOutOfRangeExceptionsẽ được
khởi tạo và ném.vào lúc này máy tính sẽ ngay lập tức thoát khỏi khối try và
tìm khối catch mà xử lí IndexOutOfRangeException. khối catch đầu tiên mà
nó đến là khối này :
catch (IndexOutOfRangeException e)
{
Console.WriteLine(
"Exception: Number should be between 0 and 5." + e.Message);
}

Bởi vì khối catch này lấy 1 thông số của một lớp tương đương , điều này sẽ
được truyền qua 1 thể hiện của biệt lệ và thực thi.trong trường hợp này,
chúng ta trình bày,1 thông báo lỗi và thuộc tính exception.message (đáp lại
chuỗi mà chúng ta đã truyền đến hàm dựng của IndexOutOfRange).sau khi
thực thi khối catch này , điều khiển chuyển đến khối finally, như là không có
biệt lệ nào xuất hiện.
Chú ý rằng chúng ta cũng cung cấp một khối catch khác :
catch (Exception e)
{
Console.WriteLine("An exception was thrown. Message was: " +
e.Message);
}
Khối catch này cũng có khả năng xử lý IndexOutOfRangeException nếu
không có sự kiện rằng biệt lệ đã được đón bắt bởi khối catch trước- một sự
tham chiếu đến 1 lớp cơ sở có thể cũng chuyển đến bất kỳ 1 thể hiện của mộ
lớp dẫn xuất từ nó.và tất cả biệt lệ mà dẫn xuất từ system.exception . vậy tại
sao khối catch này không được thực thi? câu trả lời là máy tính chỉ thực thi
khối catch thích hợp đầu tiên mà nó tìm thấy. vậy tại sao khối catch thứ hai
này lại nằm ở đây ? thật ra thì không chỉ đoạn mã của ta mới được bao phủ

bởi khối try ,mà bên trong khối, chúng ta thực sự gọi những phương thức
riêng biệt nhau trong namspace system ( Console.ReadLine(),
Console.Write(), and Convert.ToInt32()), và bất kỳ phương thức nào trong
đây cũng có thể ném ra một biệt lệ.
Nếu chúng ta gõ một thứ gì không phải là số - say hoặc hello ,sau đó phương
thức convert.toin32() sẽ ném ra một biệt lệ của lớp
System.FormatException, để chỉ định chuỗi được truyền vào toin32() không
nằm trong định dạng mà có thể chuyển thành kiểu int. khi điều này xảy ra,
máy tính sẽ truy vết xuyên suốt phương thức gọi , tìm hàm xử lí mà có thể
xử lí biệt lệ này. khối catch đầu tiên của chúng ta ( cái mà bắt
IndexOutOfRangeException) sẽ không thực hiện.máy tính tìm đến cái thứ
hai.cái này sẽ thi hành bởi vì FormatException là một dẫn xuất từ exception,
vì vậy một thực thể FormatException có thể được truyền như là một thông
số ở đây.
Cấu trúc của ví dụ trên thực sự là kiểu tình huống đẹp với nhiều khối
catch.chúng ta sẽ bắt đầu với khối catch được thiết kế để bẫy trạng thái lỗi
cụ thể. sau đó, chúng ta hoàn thành với nhiều khối catch sẽ bao phủ bất kì lỗi
nào mà chúng ta không viết những hàm xử lí lỗi cụ thể.việc sắp xếp các khối
catch là quan trọng.nếu chúng ta viết tên 2 khối thứ tự ngược nhau , mã sẽ

không phiên dịch bởi vì khối catch thứ hai sẽ không bao giờ có thể được
tham chiếu đến ( khối catch exception có thể bắt tất cả các biệt lệ)
Tuy nhiên chúng ta cũng nhìn vào khối catch thứ ba:
catch
{
Console.WriteLine("Some other exception has occurred");
}
Đây là khối catch chung cho tất cả - nó không nhận bất kì thông số nào . lý
do của khối block này là bắt các biệt lệ được ném bởi những đoạn mã không
được viết trong C#, hoặc thậm chí không được quản lí trong C#. như bạn
thấy, đó là một sự đòi hỏi của ngôn ngữ C# mà chỉ thực thể của lớp được
dẫn xuất từ system.exception mới có thể ném như một biệt lệ.nhưng những
ngôn ngữ khác không có giới hạn này- ví dụ C++ cho phép bất kì một biến
nào được ném như là một biệt lệ.nếu mã của ta gọi trong thư viện hay những
tập hợp mà được viết trong những ngôn ngữ khác ,sau đó nó có thể tìm một
biệt lệ được ném mà không dẫn xuất từ system.exception , mặc dù trong
nhiều trường hợp , cơ chế của .NET sẽ bẫy những biệt lệ này và chuyển
chúng thành đối tượng biệt lệ .NET. tuy nhiên không có nhiều khối catch có

thể làm điều này, bởi vì chúng ta không biết những lớp biệt lệ nào có thể
trình bày .
Bây giờ ta sẽ chạy đoạn mã ví dụ mà ta đả phân tích .minh họa cho những
tình huống nhập khác nhau xảy ra.và cả việc IndexOutOfRangeException
và FormatException được ném:
SimpleExceptions
Input a number between 0 and 5 (or just hit return to exit)> 4
Your number was 4
Thank you
Input a number between 0 and 5 (or just hit return to exit)> 0
Your number was 0
Thank you
Input a number between 0 and 5 (or just hit return to exit)> 10
Exception: Number should be between 0 and 5. You typed in 10
Thank you
Input a number between 0 and 5 (or just hit return to exit)> hello
An exception was thrown. Message was: Input string was not in a correct
format.
Thank you
Input a number between 0 and 5 (or just hit return to exit)>

