XNGOI L
· Phát sinh và bt gi ngoi l
· Câu lnh throw
· Câu lnh catch
· Câu lnh finally
· Nhng đối tượng ngoi l
· To riêng các ngoi l
· Phát sinh li ngoi l
· Câu hi & bài tp
Ngôn ng C# cũng ging như bt c ngôn ng hướng đối tượng khác, cho
phép x lý nhng li và các điu kin không bình thường vi nhng ngoi l. Ngoi
l là mt đối tượng đóng gói nhng thông tin v s c ca mt chương trình không
bình thường.
Mt điu quan trng để phân chia gia bug, li, và ngoi l. Mt bug là mt li lp
trìnhth được sa cha trước khi mã ngun được chuyn giao. Nhng ngoi l
thì không được bo v và tương phn vi nhng bug. Mc dù mt bug có th
nguyên nhân sinh ra ngoi l, chúng ta cũng không da vào nhng ngoi l để x
nhng bug trong chương trình, tt hơn
là chúng ta nên sa cha nhng bug này.
Mt li có nguyên nhân là do phía hành động ca người s dng. Ví d, người
s dng nhp vào mt s nhưng h li nhp vào ký t ch cái. Mt ln na, li có
th làm xut hin ngoi l, nhưng chúng ta th ngăn nga điu này bng cách
bt gi li vi hp l. Nhng li có th được đoán trước và được ngăn nga.
Thm chí nếu chúng ta xóa tt c nhng bug và d đoán tt c các li ca người
dùng, chúng ta cũng có th gp phi nhng vn đề không mong đợi, như xut
hin trng ti thiếu b nh (out of memory), thiếu tài nguyên h thng,... nhng
nguyên nhân này có th do các chương trành khác cùng hot động nh hưởng đến.
Chúng ta không th ngăn nga các ngoi l này, nhưng chúng ta có th x lý chúng
để chúng không th làm tn hi đến chương trình.
Khi mt chương trình gp mt tình hung ngoi l, như là thiếu b nh thì nó s
to mt ngoi l. Khi mt ngoi l được to ra, vic thc thi ca các chc năng hin
hành s b treo cho đến khi nào vic x lý ngoi l tương ng được tìm thy.
Điu này có nghĩa rng nếu chc năng hot động hin hành không thc hin
vic xngoi l, thì chc năng này s b chm dt và hàm gi s nhn s thay
đổi đến vic xngoi l. Nếu hàm gi này không thc hin vic x lý ngoi l,
ngoi l s được x lý sm bi CLR, điu này dn đến chương trình ca chúng ta s
kết thúc.
Mt trình xngoi l là mt khi lnh chương trình được thiết kế x lý các
ngoi l mà chương trình phát sinh. X lý ngoi l được thc thi trong trong câu lnh
catch. Mt cách lý tưởng thì nếu mt ngoi l được bt và được x lý, thì chương
trình có th sa cha được vn đề và tiếp tc thc hin hot động. Thm chí nếu
chương trình không tiếp tc, bng vic bt
gi ngoi l chúng ta có cơ hi để in ra nhng thông đip có ý nghĩa và kết thúc chương
trình mt cách rõ ràng.
Nếu đon chương trình ca chúng ta thc hin mà không quan tâm đến bt c
ngoi l nào mà chúng ta có th gp (như khi gii phóng tài nguyên mà chương trình
được cp phát), chúng ta có th đặt đon mã này trong khi finally, khi đó nó s chc
chn s được thc hin thm chí ngay c khi có mt ngoi l xut hin.
Phát sinh và bt gi ngoi l
Trong ngôn ng C#, chúng ta ch có th phát sinh (throw) nhng đối tượng các
kiu d liu System.Exception, hay nhng đối tượng được dn xut t kiu
d liu này. Namespace System ca CLR cha mt sc kiu d liu x lý ngoi
l mà chúng ta có th s dng trong chương trình. Nhng kiu d liu ngoi l
này bao gm ArgumentNull- Exception, InValidCastException, và
OverflowException, cũng như nhiu lp khác na.
Câu lnh throw
Để phát tín hiu mt s không bình thường trong mt lp ca ngôn ng C#, chúng ta
phát sinh mt ngoi l. Đểm được điu này, chúng ta s dng t khóa throw. Dòng
lnh sau to
ra mt th hin mi ca System.Exception và sau đó throw nó:
throw new System.Exception();
Khi phát sinh ngoi l thì ngay tc khc s làm ngng vic thc thi trong khi CLR
s tìm kiếm mt trình x lý ngoi l. Nếu mt trình x ngoi l không được
tìm thy trong phương thc hin thi, thì CLR tiếp tc tìm trong phương thc gi
cho đến khi nào tìm thy. Nếu CLR tr v lp Main() mà không tìm thy bt c trình
x lý ngoi l nào, thì nó s kết thúc chương trình.
Ví d 13.1: Throw ngoi l.
-----------------------------------------------------------------------------
namespace Programming_CSharp
{
using System;
public class
Test
{
public static void Main()
{
Console.WriteLine(“Enter
Main....”); Test t = new Test();
t.Func1();
Console.WriteLine(“Exit Main...”);
}
public void Func1()
{
Console.WriteLine(“Enter
Func1...”); Func2();
Console.WriteLine(“Exit Func1...”);
}
public void Func2()
{
Console.WriteLine(“Enter
Func2...”); throw new
System.Exception();
Console.WriteLine(“Exit Func2...”);
}
}
}
-----------------------------------------------------------------------------
Kết qu:
Enter Main....
Enter Func1...
Enter Func2...
Exception occurred: System.Exception: An exception of type System.Exception was
throw.
at Programming_CSharp.Test.Func2() in ... exception01.cs:line 26 at
Programming_CSharp.Test.Func1() in ... exception01.cs:line 20 at
Programming_CSharp.Test.Main() in ... exception01.cs:line 12
-----------------------------------------------------------------------------
Ví d minh ha đơn gin này viết ra màn hình console thông tin khi nó nhp vào
trong mt hàm và chun b đi ra t mt hàm. Hàm Main() to th hin mi ca kiu
Test và sau đó gi m Func1(). Sau khi in thông đip “Enter Func1”,m Func1()
này gi hàm Func2(). Hàm Func2() in ra thông đip đầu tiên và phát sinh mt ngoi l
kiu System.Exception. Vic thc
thi s ngưng ngay tc khc, và CLR sm kiếm trình xngoi l trong hàm Func2().
Do không tìm thy đây, CLR tiếp tc vào stack ly hàm đã gi trước tc là Func1 và
tìm kiếm trình x lý ngoi l. Mt ln na trong Func1 cũng không có đon xngoi
l. Và CLR tr v hàm Main. Ti hàm Main cũng không có, nên CLR s gi trình mc
định xngoi l, vic này đơn gin là xut ra mt thông đip li.
Câu lnh catch
Trong C#, mt trình xngoi l hay mt đon chương trình x lý các ngoi l được
gi là mt khi catch được to ra vi t khóa catch.
Trong ví d 13.2 sau, câu lnh throw đưc thc thi bên trong khi try, và mt khi
catch
được s dng để công b rng mt li đã được x lý.
Ví d 13.2: bt gi ngoi l.
-----------------------------------------------------------------------------
namespace Programming_CSharp
{
using System;
public class Test
{
public static void Main()
{
Console.WriteLine(“Enter
Main...”); Test t = new Test();
t.Func1();
Console.WriteLine(“Exit Main...”);
}
public void Func1()
{
Console.WriteLine(“Enter
Func1...”); Func2();
Console.WriteLine(“Exit Func1...”);
}
public void Func2()
{