Tải bản đầy đủ (.pdf) (11 trang)

Tài liệu XỬ LÝ NGOẠI LỆ phần 3 pptx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (181.76 KB, 11 trang )


Kết quả:

Open file here

DivideByZeroExceptión Msg: Attempted to divide by zero

HelpLink:


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 = “.v
n”;
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)
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Ệ
Tên ngoại lệ Mô tả
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
ArgumentException
Lỗi tham số đối mục
ArgumentNullException Đối mục Null, phương thức được truyền đối
mục null không được chấp nhận
A
r
i
t
hmeticException
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
Divi
d
eByZe
r
oExce
p

tion
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
InvalidCas
t
Exce
p
tion
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
No
t
FiniteNu
m
b
e
r
Exception
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.
NullRefe
r
enceExce

p
tion
Tham chiếu null không hợp lệ.
OutOfMe
m
o
r
yException
Out of memory
Ove
r
flowException
Lỗi tràn phép toán
StackOverflowExce
p
tion
Tràn stack
Ty
p
eInitializationExce
p
tion
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 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.
Ví dụ: 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);


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 = “.v
n”;

throw e;

}


if ( a == 0)

{



divisor”);




}



MyCustomException e = new MyCustomException(“Can’t have zero


e.HelpLink = “.v
n”;

throw e;

return a/b;

}

}




Lớp MyCustomException được dẫn xuất từ System.ApplicationException và lớp này
không
có thực thi hay khai báo gì ngoài một hàm khởi dựng. Hàm khởi dựng này lấy tham số là
một chuỗi và truyền cho lớp cơ sở. Trong trường hợp này, lợi ích của việc tạo ra ngoại
lệ là làm nổi bật điều mà chuơng trình muốn minh họa, tức là không cho phép số chia là
zero. Sử dụng ngoại lệ ArithmeticException thì tốt hơn là ngoại lệ chúng ta tạo ra.
Như
ng nó có thể làm nhầm lẫn cho những người lập trình khác vì phép chia với số chia
là zero không phải là lỗi số học.

Phát sinh lại ngoại lệ


Giả sử chúng ta muốn khối catch thực hiện một vài hành động đúng nào đó rồi
sau đó phát sinh lại ngoại lệ ra bên ngoài khối catch (trong một hàm gọi). Chúng ta
được phép phát sinh lại cùng một ngoại lệ hay phát sinh lại các ngoại lệ khác. Nếu
phát sinh ra ngoại lệ khác, chúng ta có thể
phải nhúng ngoại lệ ban đầu vào bên trong
ngoại lệ mới để phương thức gọi
có thể hiểu được lai lịch và nguồn gốc của ngoại lệ. Thuộc tính InnerException của
ngoại lệ mới cho phép truy cập ngoại lệ ban đầu.
Bởi vì InnerException cũng là một ngoại lệ, nên nó cũng có một ngoại lệ bên trong.
Do vậy, toàn bộ dây chuyền ngoại lệ là một sự đóng tổ (nest) củ
a một ngoại lệ này với
một ngoại lệ khác. Giống như là con lật đật, mỗi con chứa trong một con và đến lượt
con bên trong lại chứa
Ví dụ 13.8: Phát sinh lại ngoại lệ & ngoại lệ inner.


namespace Programming_CSharp
{


using System;

// tạo ngoại lệ riêng

public class MyCustomException : System.Exception

{


public MyCustomException( string message, Exception inner):


base(message, inner)

{




}

}


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

{


}





DangerousFunc1();

catch (MyCustomException e)

{


Console.WriteLine(“\n{0}”, e.Message);
Console.WriteLine(“Retrieving exception
history ”); Exception inner = e.InnerException;
while ( inner != null)

{



Console.WriteLine(“{0}”, inner.Message);

inner = inner.InnerException;

}

}

}


public void DangerousFunc1()

{


try

{


}





DangerousFunc2();


catch (System.Exception e)

{


MyCustomException ex = new

MyCustomException(“E3 – Custom Exception Situation”, e);

throw ex;

}

}


public void DangerousFunc2()

{


try

{





DangerousFunc3();


}


catch (System.DivideByZeroException e)

{


Exception ex = new Exception(“E2 - Func2 caught divide by zero”,
e);

throw ex;

}

}


public void DangerousFunc3()

{


try

{


}






DangerousFunc4();

catch (System.ArithmeticException)

{


throw;

}


catch (System.Exception)

{


Console.WriteLine(“Exception handled here.”);

}

}


public void DangerousFunc4()


{


throw new DivideByZeroException(“E1 – DivideByZero Exception”);

}

}

}


×