Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 11 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
11
Dung lượng
181,76 KB
Nội dung
Kết quả:
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.v
n”;
Khi ngoạilệ đượ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ạilệ chung được khai báo bên trong
namespace
System.
CÁC LỚP NGOẠI
LỆ
Tên ngoạilệ 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ạilệ thường xuất hiện
Tạo riêng các ngoạilệ
CLR cung cấp những kiểu dữ liệungoạilệ cơ bản, trong ví dụ trước chúng ta đã tạo một
vài các kiểu ngoạilệ 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ạilệ đượ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ạilệ mà chúng ta tạo ra. Chúng ta dễ dàng tạo ra các ngoạilệ riêng, hay còn gọi
là các ngoạilệ tùy chọn (custom exception), điều bắt buộc với các ngoạilệ 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ạilệ riêng.
Ví dụ: Tạo một ngoạilệ riêng.
namespace Programming_CSharp
{
using System;
// tạo ngoạilệ 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ạilệ
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 = “http://www.hcmunc.edu.v
n”;
throw e;
}
if ( a == 0)
{
divisor”);
}
MyCustomException e = new MyCustomException(“Can’t have zero
e.HelpLink = “http://www.hcmuns.edu.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ạilệ ArithmeticException thì tốt hơn là ngoạilệ 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ạilệ
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ạilệ 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ạilệ hay phát sinh lại các ngoạilệ khác. Nếu
phát sinh ra ngoạilệ khác, chúng ta có thể
phải nhúng ngoạilệ 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ạilệ ban đầu.
Bởi vì InnerException cũng là một ngoại lệ, nên nó cũng có một ngoạilệ bên trong.
Do vậy, toàn bộ dây chuyền ngoạilệ là một sự đóng tổ (nest) củ
a một ngoạilệ này với
một ngoạilệ 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ạilệ & ngoạilệ inner.
namespace Programming_CSharp
{
using System;
// tạo ngoạilệ 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ạilệ
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();
. 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ệ. 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