You are on page 1of 281

TRNG I HC KHOA HC T NHIN KHOA CNG NGH THNG TIN B MN CNG NGH PHN MM

PHM VN VIT - TRNG LP V

TM HIU NGN NG C# V VIT MT NG DNG MINH HA

N TT NGIP

GIO VIN HNG DN NGUYN TN TRN MINH KHANG

TP. HCM 2002

TRNG I HC KHOA HC T NHIN KHOA CNG NGH THNG TIN B MN CNG NGH PHN MM

PHM VN VIT - TRNG LP V

TM HIU NGN NG C# V VIT MT NG DNG MINH HA

GIO VIN HNG DN NGUYN TN TRN MINH KHANG

TP. HCM 2002

Li cm n
c th hon tt c bi n ny, trc tin phi k n cng sc ca thy Nguyn Tn Trn Minh Khang. Chng em knh li cm n n thy tn tnh hng dn v gip trong thi gian thc hin n ny. Chng em xin t lng bit n su sc i vi gia nh ng vin, to iu kin thc hin tt bi n. Xin cm n cha, m, anh, ch, em! Chng em cng xin chn thnh cm n n cc thy c khoa Cng ngh thng tin trng i hc Khoa hc T nhin Thnh ph H Ch Minh truyn t nhng kin thc, kinh nghim qu bu cho chng em trong qu trnh hc tp ti trng. Chng em cng xin chn thnh cm n n cc bn b gip ti liu, trao i hc thut mi c th thc hin n ny. Xin gi li cm n n cc bn H Ngc Huy, Trn Th Anh, Bi Thanh Tun...

Thnh ph H Ch Minh, ngy 03 thng 8 nm 2002 Sinh vin Phm Vn Vit Trng Lp V

Mc lc
Li cm n.......................................................................................................................3 Mc lc ............................................................................................................................4 Tm tt.............................................................................................................................1 Phn 1 Tm hiu ngn ng C#.........................................................................................1 Chng 1 C# v .Net Framework................................................................................2 1.1 Nn tng ca .NET.............................................................................................2 1.2 .NET Framework ...............................................................................................3 1.3 Bin dch v ngn ng trung gian (MSIL).........................................................4 1.4 Ngn ng C# ......................................................................................................5 Chng 2 Khi u......................................................................................................6 2.1 Lp, i tng v kiu .......................................................................................6 2.2 Pht trin Hello World....................................................................................8 Chng 3 Nhng c s ca ngn ng C# .................................................................12 3.1 Cc kiu............................................................................................................12 3.2 Bin v hng.....................................................................................................14 3.3 Biu thc ..........................................................................................................16 3.4 Khong trng....................................................................................................16 3.5 Cu lnh ...........................................................................................................16 3.6 Ton t .............................................................................................................19 3.7 To vng tn.....................................................................................................21 3.8 Ch th tin x l ..............................................................................................22 Chng 4 Lp v i tng.......................................................................................24 4.1 nh ngha lp..................................................................................................24 4.2 To i tng ...................................................................................................25 4.3 S dng cc thnh vin tnh .............................................................................27 4.4 Hy i tng ..................................................................................................29 4.5 Truyn tham s.................................................................................................30 4.6 Np chng phng thc v hm dng .............................................................32 4.7 ng gi d liu vi property..........................................................................33 Chng 5 Tha k v a hnh...................................................................................35 5.1 c bit ho v tng qut ho..........................................................................35

5.2 S k tha.........................................................................................................35 5.3 a hnh .............................................................................................................37 5.4 Lp tru tng .................................................................................................38 5.5 Lp gc ca tt c cc lp: Object...................................................................39 5.6 Kiu Boxing v Unboxing ...............................................................................40 5.7 Lp lng ...........................................................................................................42 Chng 6 Np chng ton t.....................................................................................44 6.1 Cch dng t kho operator .............................................................................44 6.2 Cch h tr cc ngn ng .Net khc ................................................................44 6.3 S hu ch ca cc ton t ...............................................................................44 6.4 Cc ton t logic hai ngi ................................................................................45 6.5 Ton t so snh bng........................................................................................45 6.6 Ton t chuyn i kiu (p kiu) ...................................................................45 Chng 7 Cu trc.....................................................................................................48 7.1 nh ngha cu trc ..........................................................................................48 7.2 Cch to cu trc..............................................................................................49 Chng 8 Giao din...................................................................................................50 8.1 Ci t mt giao din .......................................................................................50 8.2 Truy xut phng thc ca giao din ..............................................................52 8.3 Np chng phn ci t giao din ....................................................................54 8.4 Thc hin giao din mt cch tng minh ......................................................55 Chng 9 Array, Indexer, and Collection .................................................................58 9.1 Mng (Array) ...................................................................................................58 9.2 Cu lnh foreach ..............................................................................................59 9.3 Indexers ............................................................................................................62 9.4 Cc giao din ti cha......................................................................................65 9.5 Array Lists........................................................................................................65 9.6 Hng i...........................................................................................................65 9.7 Stacks ...............................................................................................................66 9.8 Dictionary.........................................................................................................66 Chng 10 Chui.......................................................................................................67 10.1 To chui mi ................................................................................................67 10.2 Phng thc ToString() .................................................................................67 10.3 Thao tc chui ................................................................................................68 10.4 Thao tc chui ng.......................................................................................70 Chng 11 Qun l li...............................................................................................72 11.1 Nm v bt bit l ..........................................................................................73 11.2 i tng Exception ......................................................................................80 11.3 Cc bit l t to ............................................................................................82 11.4 Nm bit l ln na. .......................................................................................83

Chng 12 Delegate v Event ...................................................................................87 12.1 Delegate (y thc, y quyn) .........................................................................87 12.2 Event (S kin) ............................................................................................101 Chng 13 Lp trnh vi C#....................................................................................109 13.1 ng dng Windows vi Windows Form.....................................................109 Chng 14 Truy cp d liu vi ADO.NET ...........................................................144 14.1 C s d liu v ngn ng truy vn SQL ....................................................144 14.2 Mt s loi kt ni hin ang s dng .........................................................144 14.3 Kin trc ADO.NET ....................................................................................145 14.4 M hnh i tng ADO.NET .....................................................................146 14.5 Trnh cung cp d liu (.NET Data Providers)............................................148 14.6 Khi s vi ADO.NET ................................................................................148 14.7 S dng trnh cung cp d liu c qun l ..............................................151 14.8 Lm vic vi cc iu khin kt buc d liu .............................................152 14.9 Thay i cc bn ghi ca c s d liu........................................................161 Chng 15 ng dng Web vi Web Forms............................................................173 1.1 Tm hiu v Web Forms............................................................................173 15.1 Cc s kin ca Web Forms ........................................................................174 15.2 Hin th chui ln trang................................................................................175 15.3 iu khin xc nhn hp..............................................................................178 15.4 Mt s v d mu minh ha .........................................................................179 Chng 16 Cc dch v Web...................................................................................192 Chng 17 Assemblies v Versioning ....................................................................196 17.1 Tp tin PE.....................................................................................................196 17.2 Metadata.......................................................................................................196 17.3 Ranh gii an ninh .........................................................................................196 17.4 S hiu phin bn (Versioning) ...................................................................196 17.5 Manifest........................................................................................................196 17.6 a Module Assembly...................................................................................197 17.7 Assembly ni b (private assembly)............................................................198 17.8 Assembly chia s (shared assembly)............................................................198 Chng 18 Attributes v Reflection ........................................................................200 18.1 Attributes......................................................................................................200 18.2 Attribute mc nh (intrinsic attributes).......................................................200 18.3 Attribute do lp trnh vin to ra..................................................................201 18.4 Reflection .....................................................................................................203 Chng 19 Marshaling v Remoting.......................................................................204 19.1 Min ng Dng (Application Domains) .....................................................204 19.2 Context .........................................................................................................206 19.3 Remoting ......................................................................................................208

Chng 20 Thread v S ng B .........................................................................215 20.1 Thread ..........................................................................................................215 20.2 ng b ha (Synchronization) ...................................................................216 20.3 Race condition v DeadLock .......................................................................221 Chng 21 Lung d liu........................................................................................223 21.1 Tp tin v th mc .......................................................................................223 21.2 c v ghi d liu ........................................................................................230 21.3 Bt ng b nhp xut .................................................................................235 21.4 Serialization..................................................................................................238 21.5 Isolate Storage..............................................................................................244 Chng 22 Lp trnh .NET v COM .......................................................................246 22.1 P/Invoke .......................................................................................................246 22.2 Con tr..........................................................................................................248 Phn 2 Xy dng mt ng dng minh ha..................................................................250 Chng 23 Website dy hc ngn ng C# ..............................................................251 23.1 Hin trng v yu cu...................................................................................251 23.2 Phn tch hng i tng...........................................................................258 23.3 Thit k hng i tng.............................................................................262

Tm tt
ti ny tp trung tm hiu ton b cc khi nim lin quan n ngn ng C#. Bi v C# c Microsoft pht trin nh l mt thnh phn ca khung ng dng .NET Framework v hng Internet nn ti ny bao gm hai phn sau: Phn 1: Tm hiu v ngn ng C# Vic tm hiu bao gm c cc kin thc nn tng v cng ngh .NET Framework, chun b cho cc khi nim lin quan gia C# v .NET Framework. Sau tm hiu v b c php ca ngn ng ny, bao gm ton b tp lnh, t kha, khi nim v lp trnh hng i tng theo C#, cc h tr lp trnh hng component ... Sau cng l cch lp trnh C# vi ng dng Window cho my bn v C# vi cc cng ngh hin i nh ASP.NET. ADO.NET, XML cho lp trnh Web. Phn 2: Xy dng mt ng dng Phn ny l bo co v ng dng minh ha cho vic tm hiu trn. Tn ng dng l Xy dng mt Website dy hc C#. y l ng dng Web ci t bng ngn ng C# v ASP.NET. Trong ASP.NET c dng xy dng giao din tng tc vi ngi dng; cn C# l ngn ng lp trnh bn di. ng dng c thao tc c s d liu (Microsoft SQL Server) thng quan m hnh ADO.NET.

Phn 1 Tm hiu ngn ng C#

C# v .Net Framework

Gvhd: Nguyn Tn Trn Minh Khang

Chng 1 C# v .Net Framework


Mc tiu ca C# l cung cp mt ngn ng lp trnh n gin, an ton, hin i, hng i tng, t trng tm vo Internet, c kh nng thc thi cao cho mi trng .NET. C# l mt ngn ng mi, nhng tch hp trong n nhng tinh hoa ca ba thp k pht trin ca ngn ng lp trnh. Ta c th d dng thy trong C# c nhng c trng quen thuc ca Java, C++, Visual Basic, ti ny t trng tm gii thiu ngn ng C# v cch dng n nh l mt cng c lp trnh trn nn tng .NET. Vi ngn ng C++, khi hc n ta khng cn quan tm n mi trng thc thi. Vi ngn ng C#, ta hc to mt ng dng .NET, nu l l ny c th b l quan im chnh ca ngn ng ny. Do , trong ti ny xt C# tp trung trong ng cnh c th l nn tng .NET ca Microsoft v trong cc ng dng my tnh bn v ng dng Internet. Chng ny trnh by chung v hai phn l ngn ng C# v nn tng .NET, bao gm c khung ng dng .NET (.NET Framework)

1.1 Nn tng ca .NET


Khi Microsoft cng b C# vo thng 7 nm 2000, vic khnh thnh n ch l mt phn trong s rt nhiu s kin m nn tng .Net c cng cng b. Nn tng .Net l b khung pht trin ng dng mi, n cung cp mt giao din lp trnh ng dng (Application Programming Interface - API) mi m cho cc dch v v h iu hnh Windows, c th l Windows 2000, n cng mang li nhiu k thut khc ni bt ca Microsoft sut t nhng nm 90. Trong s c cc dch v COM+, cng ngh ASP, XML v thit k hng i tng, h tr cc giao thc dch v web mi nh SOAP, WSDL v UDDL vi trng tm l Internet, tt c c tch hp trong kin trc DNA. Nn tng .NET bao gm bn nhm sau: 1. Mt tp cc ngn ng, bao gm C# v Visual Basic .Net; mt tp cc cng c pht trin bao gm Visual Studio .Net; mt tp y cc th vin phc v cho vic xy dng cc ng dng web, cc dch v web v cc ng dng Windows; cn c CLR - Common Language Runtime: (ngn ng thc thi dng chung) thc thi cc i tng c xy dng trn b khung ny. 2. Mt tp cc Server X nghip .Net nh SQL Server 2000. Exchange 2000, BizTalk 2000, chng cung cp cc chc nng cho vic lu tr d liu quan h, th in t, thng mi in t B2B,

C# v .Net Framework

Gvhd: Nguyn Tn Trn Minh Khang

3. Cc dch v web thng mi min ph, va c cng b gn y nh l d n Hailstorm; nh pht trin c th dng cc dch v ny xy dng cc ng dng i hi tri thc v nh danh ngi dng 4. .NET cho cc thit b khng phi PC nh in thoi (cell phone), thit b game

1.2 .NET Framework


.Net h tr tch hp ngn ng, tc l ta c th k tha cc lp, bt cc bit l, a hnh thng qua nhiu ngn ng. .NET Framework thc hin c vic ny nh vo c t Common Type System - CTS (h thng kiu chung) m tt c cc thnh phn .Net u tun theo. V d, mi th trong .Net u l i tng, tha k t lp gc System.Object. Ngoi ra .Net cn bao gm Common Language Specification - CLS (c t ngn ng chung). N cung cp cc qui tc c bn m ngn ng mun tch hp phi tha mn. CLS ch ra cc yu cu ti thiu ca ngn ng h tr .Net. Trnh bin dch tun theo CLS s to cc i tng c th tng hp vi cc i tng khc. B th vin lp ca khung ng dng (Framework Class Library - FCL) c th c dng bi bt k ngn ng no tun theo CLS. .NET Framework nm tng trn ca h iu hnh (bt k h iu hnh no khng ch l Windows). .NET Framework bao bao gm: Bn ngn ng chnh thc: C#, VB.Net, C++, v Jscript.NET Common Language Runtime - CLR, nn tng hng i tng cho pht trin ng dng Windows v web m cc ngn ng c th chia s s dng. B th vin Framework Class Library - FCL.
Hnh 1-1 Kin trc khung ng dng .Net

C# v .Net Framework

Gvhd: Nguyn Tn Trn Minh Khang

Thnh phn quan trng nht ca .NET Framework l CLR, n cung cp mi trng cho ng dng thc thi, CLR l mt my o, tng t my o Java. CLR kch hot i tng, thc hin kim tra bo mt, cp pht b nh, thc thi v thu dn chng. Trong Hnh 1-1 tng trn ca CLR bao gm: Cc lp c s Cc lp d liu v XML Cc lp cho dch v web, web form, v Windows form. Cc lp ny c gi chung l FCL, Framework Class Library, cung cp API hng i tng cho tt c cc chc nng ca .NET Framework (hn 5000 lp). Cc lp c s tng t vi cc lp trong Java. Cc lp ny h tr cc thao tc nhp xut, thao tc chui, vn bn, qun l bo mt, truyn thng mng, qun l tiu trnh v cc chc nng tng hp khc Trn mc ny l lp d liu v XML. Lp d liu h tr vic thao tc cc d liu trn c s d liu. Cc lp ny bao gm cc lp SQL (Structure Query Language: ngn ng truy vn c cu trc) cho php ta thao tc d liu thng qua mt giao tip SQL chun. Ngoi ra cn mt tp cc lp gi l ADO.Net cng cho php thao tc d liu. Lp XML h tr thao tc d liu XML, tm kim v din dch XML. Trn lp d liu v XML l lp h tr xy dng cc ng dng Windows (Windows forms), ng dng Web (Web forms) v dch v Web (Web services).

1.3 Bin dch v ngn ng trung gian (MSIL)


Vi .NET chng trnh khng bin dch thnh tp tin thc thi, m bin dch thnh ngn ng trung gian (MSIL - Microsoft Intermediate Language, vit tt l IL), sau chng c CLR thc thi. Cc tp tin IL bin dch t C# ng nht vi cc tp tin IL bin dch t ngn ng .Net khc. Khi bin dch d n, m ngun C# c chuyn thnh tp tin IL lu trn a. Khi chy chng trnh th IL c bin dch (hay thng dch) mt ln na bng trnh Just In Time - JIT, khi ny kt qu l m my v b x l s thc thi. Trnh bin dch JIT ch chy khi c yu cu. Khi mt phng thc c gi, JIT phn tch IL v sinh ra m my ti u cho tng loi my. JIT c th nhn bit m ngun c bin dch cha, c th chy ngay ng dng hay phi bin dch li. CLS c ngha l cc ngn ng .Net cng sinh ra m IL. Cc i tng c to theo mt ngn ng no s c truy cp v tha k bi cc i tng ca ngn ng khc. V vy ta c th to c mt lp c s trong VB.Net v tha k n t C#.

C# v .Net Framework

Gvhd: Nguyn Tn Trn Minh Khang

1.4 Ngn ng C#
C# l mt ngn ng rt n gin, vi khong 80 t kho v hn mi kiu d liu dng sn, nhng C# c tnh din t cao. C# h tr lp trnh c cu trc, hng i tng, hng thnh phn (component oriented). Trng tm ca ngn ng hng i tng l lp. Lp nh ngha kiu d liu mi, cho php m rng ngn ng theo hng cn gii quyt. C# c nhng t kho dnh cho vic khai bo lp, phng thc, thuc tnh (property) mi. C# h tr y khi nim tr ct trong lp trnh hng i tng: ng gi, tha k, a hnh. nh ngha lp trong C# khng i hi tch ri tp tin tiu vi tp tin ci t nh C++. Hn th, C# h tr kiu su liu mi, cho php su liu trc tip trong tp tin m ngun. n khi bin dch s to tp tin su liu theo nh dng XML. C# h tr khi nim giao din, interfaces (tng t Java). Mt lp ch c th k tha duy nht mt lp cha nhng c th ci t nhiu giao din. C# c kiu cu trc, struct (khng ging C++). Cu trc l kiu hng nh v b gii hn.Cu trc khng th tha k lp hay c k tha nhng c th ci t giao din. C# cung cp nhng c trng lp trnh hng thnh phn nh property, s kin v dn hng khai bo (c gi l attribute). Lp trnh hng component c h tr bi CLR thng qua siu d liu (metadata). Siu d liu m t cc lp bao gm cc phng thc v thuc tnh, cc thng tin bo mt . Assembly l mt tp hp cc tp tin m theo cch nhn ca lp trnh vin l cc th vin lin kt ng (DLL) hay tp tin thc thi (EXE). Trong .NET mt assembly l mt on v ca vic ti s dng, xc nh phin bn, bo mt, v phn phi. CLR cung cp mt s cc lp thao tc vi assembly. C# cng cho truy cp trc tip b nh dng con tr kiu C++, nhng vng m c xem nh khng an ton. CLR s khng thc thi vic thu dn rc t ng cc i tng c tham chiu bi con tr cho n khi lp trnh vin t gii phng.

Khi u

Gvhd: Nguyn Tn Trn Minh Khang

Chng 2 Khi u
Chng ny ta s to, bin dch v chy chng trnh Hello World bng ngn ng C#. Phn tch ngn gn chng trnh gii thiu cc c trng chnh yu trong ngn ng C#.
V d 2-1 Chng trnh Hello World
class HelloWorld { static void Main( ) { // s dng i tng console ca h thng System.Console.WriteLine("Hello World"); } }

Sau khi bin dch v chy HelloWorld, kt qu l dng ch Hello World hin th trn mn hnh.

2.1 Lp, i tng v kiu


Bn cht ca lp trnh hng i tng l to ra cc kiu mi. Mt kiu biu din mt vt g . Ging vi cc ngn ng lp trnh hng i tng khc, mt kiu trong C# cng nh ngha bng t kho class (v c gi l lp) cn th hin ca lp c gi l i tng. Xem V d 2-1 ta thy cch khai bo mt lp HelloWorld. Ta thy ngay l cch khai bo v ni dung ca mt lp hon ton ging vi ngn ng Java v C++, ch c khc l cui khai bo lp khng cn du ;

2.1.1 Phng thc


Cc hnh vi ca mt lp c gi l cc phng thc thnh vin (gi tt l phng thc) ca lp . Mt phng thc l mt hm (phng thc thnh vin cn gi l hm thnh vin). Cc phng thc nh ngha nhng g m mt lp c th lm. Cch khai bo, ni dung v cch s dng cc phng thc ging hon ton vi Java v C++. Trong v d trn c mt phng thc c bit l phng thc Main() (nh hm main() trong C++) l phng thc bt u ca mt ng dng C#, c th tr v kiu void hay int. Mi mt chng trnh (assembly) c th c nhiu phng thc Main nhng khi phi ch nh phng thc Main() no s bt u chng trnh.

Khi u

Gvhd: Nguyn Tn Trn Minh Khang

2.1.2 Cc ghi ch
C# c ba kiu ghi ch trong c hai kiu rt quen thuc ca C++ l dng: "//" v "/* */". Ngoi ra cn mt kiu ghi ch na s trnh by cc chng k.
V d 2-2 Hai hnh thc ghi ch trong C#
class HelloWorld { static void Main( ) // y l ghi trn mt dng { /* Bt u ghi ch nhiu dng Vn cn trong ghi ch Kt thc ghi ch bng */ System.Console.WriteLine("Hello World"); } }

2.1.3 ng dng dng console


Hello World l mt ng dng console. Cc ng dng dng ny thng khng c giao din ngi dng ha Cc nhp xut u thng qua cc console chun (dng dng lnh nh DOS). Trong v d trn, phng thc Main() vit ra mn hnh dng Hello World. Do mn hnh qun l mt i tng Console, i tng ny c phng thc WriteLine() cho php t mt dng ch ln mn hnh. gi phng thc ny ta dng ton t ., nh sau: Console.WriteLine().

2.1.4 Namespaces - Vng tn


Console l mt trong rt nhiu (c ngn) lp trong b th vin .NET. Mi lp u c tn v nh vy c hng ngn tn m lp trnh vin phi nh hoc phi tra cu mi khi s dng. Vn l phi lm sao gim bt lng tn phi nh. Ngoi vn phi nh qu nhiu tn ra, cn mt nhn xt sau: mt s lp c mi lin h no v mt ng ngha, v d nh lp Stack, Queue, Hashtable l cc lp ci t cu trc d liu ti cha. Nh vy c th nhm nhng lp ny thnh mt nhm v thay v phi nh tn cc lp th lp trnh vin ch cn nh tn nhm, sau c th thc hin vic tra cu tn lp trong nhm nhanh chng hn. Nhm l mt vng tn trong C#. Mt vng tn c th c nhiu lp v vng tn khc. Nu vng tn A nm trong vng tn B, ta ni vng tn A l vng tn con ca vng tn B. Khi cc lp trong vng tn A c ghi nh sau: B.A.Tn_lp_trong_vng_tn_A System l vng tn cha nhiu lp hu ch cho vic giao tip vi h thng hoc cc lp cng dng chung nh lp Console, Math, Exception.Trong v d HelloWorld trn, i tng Console c dng nh sau:
System.Console.WriteLine("Hello World");

Khi u

Gvhd: Nguyn Tn Trn Minh Khang

2.1.5 Ton t chm .


Nh trong V d 2-1 ton t chm c dng truy sut d liu v phng thc mt lp (nh Console.WriteLine()), ng thi cng dng ch nh tn lp trong mt vng tn (nh System.Console). Ton t du chm cng c dng truy xut cc vng tn con ca mt vng tn
Vng_tn.Vng_tn_con.Vng_tn_con_con

2.1.6 T kho using


Nu chng trnh s dng nhiu ln phng thc Console.WriteLine, t System s phi vit nhiu ln. iu ny c th khin lp trnh vin nhm chn. Ta s khai bo rng chng trnh c s dng vng tn System, sau ta dng cc lp trong vng tn System m khng cn phi c t System i trc.
V d 2-3 T kha using
// Khai bo chng trnh c s dng vng tn System using System; class HelloWorld { static void Main( ) { // Console thuc vng tn System Console.WriteLine("Hello World"); } }

2.1.7 Phn bit hoa thng


Ngn ng C# cng phn bit ch hoa thng ging nh Java hay C++ (khng nh VB). V d nh WriteLine khc vi writeLine v c hai cng khc vi WRITELINE. Tn bin, hm, hng u phn bit ch hoa ch thng.

2.1.8 T kho static


Trong V d 2-1 phng thc Main() c khai bo kiu tr v l void v dng t kho static. T kho static cho bit l ta c th gi phng thc Main() m khng cn to mt i tng kiu HelloWorld.

2.2 Pht trin Hello World


C hai cch vit, bin dch v chy chng trnh HelloWorld l dng mi trng pht trin tch hp (IDE) Visual Studio .Net hay vit bng trnh son tho vn bn v bin dch bng dng lnh. IDE Vs.Net d dng hn. Do , trong ti ny ch trnh by theo hng lm vic trn IDE Visual Studio .Net.

Khi u

Gvhd: Nguyn Tn Trn Minh Khang

2.2.1 Son tho Hello World


to chng trnh Hello World trong IDE, ta chn Visual Studio .Net t thanh thc n. Tip theo trn mn hnh ca IDE chn File > New > Project t thanh thc n, theo xut hin mt ca s nh sau:

Hnh 2-1 To mt ng dng console trong VS.Net

to chng trnh Hello World ta chn Visual C# Project > Console Application, in HelloWorld trong Name, chn ng dn v nhn OK. Mt ca s son tho xut hin.

Khi u

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 2-2 Ca s son tho ni dung m ngun

Vs.Net t to mt s m, ta cn chnh sa cho ph hp vi chng trnh ca mnh.

2.2.2 Bin dch v chy Hello World


Sau khi y m ngun ta tin hnh bin dch chng trnh: nhn CtrlShift B hay chn Build > Build Solution. Kim tra xem chng trnh c li khng ca s Output cui mn hnh. Khi bin dch chng trnh n s lu li thnh tp tin .cs. Chy chng trnh bng CtrlF5 hay chn Debug > Start Without Debugging.

2.2.3 Trnh g ri ca Visual Studio .Net


Trnh g ri ca VS.Net rt mnh hu ch. Ba k nng chnh yu s dng ca trnh g ri l: Cch t im ngt (breakpoint) v lm sao chy cho n im ngt Lm th no chy tng bc v chy vt qua mt phng thc. Lm sao quan st v hiu chnh gi tr ca bin, d liu thnh vin, Cch n gin nht t im ngt l bm chut tri vo pha l tri, ti s hin ln mt chm .

10

Khi u

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 2-3 Minh ha mt im ngt

Cch dng trnh g ri hon ton ging vi trnh g ri trong VS 6.0. N cho php ta dng li mt v tr bt k, cho ta kim tra gi tr tc thi bng cch di chuyn chut n v tr bin. Ngoi ra, khi g ri ta cng c th xem gi tr cc bin thng qua ca s Watch v Local. chy trong ch g ri ta chn Debug Start hay nhn F5, mun chy tng bc ta bm F11 v chy vt qua mt phng thc ta bm F10.

11

Nhng c s ca ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Chng 3 Nhng c s ca ngn ng C#


Trong chng ny s trnh by v h thng kiu trong C#; phn bit kiu dng sn (int, long, bool, ) vi cc kiu do ngi dng nh ngha. Ngoi ra, chng ny cng s trnh by cch to v dng bin, hng; gii thiu kiu lit k, chui, kiu nh danh, biu thc, v cu lnh. Phn hai ca chng trnh by v cc cu trc iu kin v cc ton t logic, quan h, ton hc,

3.1 Cc kiu
C# buc phi khai bo kiu ca i tng c to. Khi kiu c khai bo r rng, trnh bin dch s gip ngn nga li bng cch kim tra d liu c gn cho i tng c hp l khng, ng thi cp pht ng kch thc b nh cho i tng. C# phn thnh hai loi: loai d liu dng sn v loi do ngi dng nh ngha. C# cng chia tp d liu thnh hai kiu: gi tr v tham chiu. Bin kiu gi tr c lu trong vng nh stack, cn bin kiu tham chiu c lu trong vng nh heap. C# cng h tr kiu con tr ca C++, nhng t khi c s dng. Thng thng con tr ch c s dng khi lm vic trc tip vi Win API hay cc i tng COM.

3.1.1 Loi d liu nh sn


C# c nhiu kiu d liu nh sn, mi kiu nh x n mt kiu c h tr bi CLS (Commom Language Specification), nh x m bo rng i tng c to trong C# khng khc g i tng c to trong cc ngn ng .NET khc Mi kiu c mt kch thc c nh c lit k trong bng sau
Bng 3-1 Cc kiu dng sn
Kiu byte char bool sbyte short ushort int Kch thc (byte) 1 1 1 1 2 2 4 Kiu .Net Byte Char Boolean Sbyte Int16 Uint16 Int32

M t - gi tr
Khng du (0..255) M k th Unicode true hay false C du (-128 .. 127) C du (-32768 .. 32767) Khng du (0 .. 65535) C du (-2147483647 .. 2147483647)

12

Nhng c s ca ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

uint float double decimal long ulong

4 4 8 8 8 8

Uint32 Single Double Decimal Int64 Uint64

Khng du (0 .. 4294967295) S thc ( 1.5*10-45 .. 3.4*1038) S thc ( 5.0*10-324 .. 1.7*10308) s c du chm tnh vi 28 k s v du chm S nguyn c du (- 9223372036854775808 .. 9223372036854775807) S nguyn khng du (0 .. 0xffffffffffffffff.)

3.1.1.1 Chn mt kiu nh sn


Tu vo tng gi tr mun lu tr m ta chn kiu cho ph hp. Nu chn kiu qu ln so vi cc gi tr cn lu s lm cho chng trnh i hi nhiu b nh v chy chm. Trong khi nu gi tr cn lu ln hn kiu thc lu s lm cho gi tr cc bin b sai v chng trnh cho kt qu sai. Kiu char biu din mt k t Unicode. V d \u0041 l k t A trn bng Unicode. Mt s k t c bit c biu din bng du \ trc mt k t khc.
Bng 3-2 Cc k t c bit thng dng
K t Ngha

\ \ \\ \0 \a \b \f \n \r \t \v

du nhy n du nhy i du cho ngc \ Null Alert li v sau Form feed xung dng v u dng Tab ngang Tab dc

3.1.1.2 Chuyn i kiu nh sn


Mt i tng c th chuyn t kiu ny sang kiu kia theo hai hnh thc: ngm hoc tng minh. Hnh thc ngm c chuyn t ng cn hnh thc tng minh cn s can thip trc tip ca ngi lp trnh (ging vi C++ v Java).
short x = 5; int y ; y = x; // chuyn kiu ngm nh - t ng x = y; // li, khng bin dch c x = (short) y; // OK

13

Nhng c s ca ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

3.2 Bin v hng


Bin dng lu tr d liu. Mi bin thuc v mt kiu d liu no .

3.2.1 Khi to trc khi dng


Trong C#, trc khi dng mt bin th bin phi c khi to nu khng trnh bin dch s bo li khi bin dch. Ta c th khai bo bin trc, sau khi to v s dng; hay khai bo bin v khi gn trong lc khai bo.
int x; // khai bo bin trc x = 5; // sau khi gn gi tr v s dng int y = x; // khai bo v khi gn cng lc

3.2.2 Hng
Hng l mt bin nhng gi tr khng thay i theo thi gian. Khi cn thao tc trn mt gi tr xc nh ta dng hng. Khai bo hng tng t khai bo bin v c thm t kha const trc. Hng mt khi khi ng xong khng th thay i c na.
const int HANG_SO = 100;

3.2.3 Kiu lit k


Enum l mt cch thc t tn cho cc tr nguyn (cc tr kiu s nguyn, theo ngha no tng t nh tp cc hng), lm cho chng trnh r rng, d hiu hn. Enum khng c hm thnh vin. V d to mt enum tn l Ngay nh sau:
enum Ngay {Hai, Ba, Tu, Nam, Sau, Bay, ChuNhat};

Theo cch khai bo ny enum ngy c by gi tr nguyn i t 0 = Hai, 1 = Ba, 2 = T 7 = ChuNhat.


V d 3-1 S dng enum Ngay
using System; public class EnumTest { enum Ngay {Hai, Ba, Tu, Nam, Sau, Bay, ChuNhat }; public static void Main() { int x = (int) Ngay.Hai; int y = (int) Ngay.Bay; Console.WriteLine("Thu Hai = {0}", x); Console.WriteLine("Thu Bay = {0}", y); } } Kt qu Thu Hai = 0 Thu Bay = 5

14

Nhng c s ca ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Mc nh enum gn gi tr u tin l 0 cc tr sau ln hn gi tr trc mt n v, v cc tr ny thuc kiu int. Nu mun thay i tr mc nh ny ta phi gn tr mong mun.
V d 3-2 S dng enum Ngay (2)
using System; namespace ConsoleApplication { enum Ngay: byte { Hai=2,Ba,Tu,Nam,Sau,Bay,ChuNhat=10 }; class EnumTest { static void Main(string[] args) { byte x = (byte)Ngay.Ba; byte y = (byte)Ngay.ChuNhat; Console.WriteLine("Thu Ba = {0}", x); Console.WriteLine("Chu Nhat = {0}", y); Console.Read(); } } } Kt qu: Thu Ba = 3 Chu Nhat = 10

Kiu enum ngy c vit li vi mt s thay i, gi tr cho Hai l 2, gi tr cho Ba l 3 (Hai + 1) , gi tr cho ChuNhat l 10, v cc gi tr ny s l kiu byte. C php chung cho khai bo mt kiu enum nh sau
[attributes] [modifiers] enum identifier [:base-type] { enumerator-list }; attributes (ty chn): cc thng tin thm ( cp sau) modifiers (ty chn): public, protected, internal, private (cc b t xc nh phm vi truy xut) identifer: tn ca enum base_type (ty chn): kiu s, ngoi tr char enumerator-list: danh sch cc thnh vin.

3.2.4 Chui
Chui l kiu dng sn trong C#, n l mt chui cc k t n l. Khi khai bo mt bin chui ta dng t kho string. V d khai bo mt bin string lu chui "Hello World"
string myString = "Hello World";

3.2.5 nh danh
nh danh l tn m ngi lp trnh chn i din mt kiu, phng thc, bin, hng, i tng ca h. nh danh phi bt u bng mt k t hay du _. nh danh khng c trng vi t kho C# v phn bit hoa thng.

15

Nhng c s ca ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

3.3 Biu thc


Bt k cu lnh nh lng gi tr c gi l mt biu thc (expression). Php gn sau cng c gi l mt biu thc v n nh lng gi tr c gn (l 32)
x = 32;

v vy php gn trn c th c gn mt ln na nh sau


y = x = 32;

Sau lnh ny y c gi tr ca biu thc x = 32 v v vy y = 32.

3.4 Khong trng


Trong C#, khong trng, du tab, du xung dng u c xem l khong trng (whitespace). Do , du cch d ln hay nh u nh nhau nn ta c:
x = 32;

cng nh
x = 32;

Ngoi tr khong trng trong chui k t th c ngha ring ca n.

3.5 Cu lnh
Cng nh trong C++ v Java mt ch th hon chnh th c gi l mt cu lnh (statement). Chng trnh gm nhiu cu lnh, mi cu lnh kt thc bng du ;. V d:
int x; // l mt cu lnh x = 23; // mt cu lnh khc

Ngoi cc cu lnh bnh thng nh trn, c cc cu lnh khc l: lnh r nhnh khng iu kin, r nhnh c iu kin v lnh lp.

3.5.1 Cc lnh r nhnh khng iu kin


C hai loi cu lnh r nhnh khng iu kin. Mt l lnh gi phng thc: khi trnh bin dch thy c li gi phng thc n s tm dng phng thc hin hnh v nhy n phng thc c gi cho n ht phng thc ny s tr v phng thc c.
V d 3-3 Gi mt phng thc
using System; class Functions { static void Main( ) { Console.WriteLine("In Main! Calling SomeMethod( )..."); SomeMethod( ); Console.WriteLine("Back in Main( )."); } static void SomeMethod( ) {

16

Nhng c s ca ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

} Kt qu: In Main! Calling SomeMethod( )... Greetings from SomeMethod! Back in Main( ).

Console.WriteLine("Greetings from SomeMethod!");

Cch th hai to cc cu lnh r nhnh khng iu kin l dng t kho: goto, break, continue, return, hay throw. Cch t kha ny s c gii thiu trong cc phn sau.

3.5.2 Lnh r nhnh c iu kin


Cc t kha if-else, while, do-while, for, switch-case, dng iu khin dng chy chng trnh. C# gi li tt c cc c php ca C++, ngoi tr switch c vi ci tin.

3.5.2.1 Lnh If .. else


C php:
if ( biu thc logic ) khi lnh;

hoc
if ( biu thc logic ) khi lnh 1; else khi lnh 2;

Ghi ch: Khi lnh l mt tp cc cu ln trong cp du {}. Bt k ni u c cu lnh th c th vit bng mt khi lnh. Biu thc logic l biu thc cho gi tr dng hoc sai (true hoc false). Nu biu thc logic cho gi tr ng th khi lnh hay khi lnh 1 s c thc thi, ngc li khi lnh 2 s thc thi. Mt im khc bit vi C++ l biu thc trong cu lnh if phi l biu thc logic, khng th l biu thc s.

3.5.2.2 Lnh switch


C php:
switch ( biu_thc_la_chn ) { case biu_thc_hng : khi lnh; lnh nhy; [ default : khi lnh; lnh nhy; ] }

Biu thc la chn l biu thc sinh ra tr nguyn hay chui. Switch s so snh biu_thc_la_chn vi cc biu_thc_hng bit phi thc hin vi khi lnh no. Lnh nhy nh break, goto thot khi cu switch v bt buc phi c.

17

Nhng c s ca ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

int nQuyen = 0; switch ( sQuyenTruyCap ) { case Administrator: nQuyen = 1; break; case Admin: goto case Administrator; default: nQuyen = 2; break; }

3.5.3 Lnh lp
C# cung cp cc lnh lp ging C++ nh for, while, do-while v lnh lp mi foreach. N cng h tr cc cu lnh nhy nh: goto, break, continue v return.

3.5.3.1 Lnh goto


Lnh goto c th dng to lnh nhy nhng nhiu nh lp trnh chuyn nghip khuyn khng nn dng cu lnh ny v n ph v tnh cu trc ca chng trnh. Cch dng cu lnh ny nh sau: (ging nh trong C++) 1. To mt nhn 2. goto n nhn .

3.5.3.2 Vng lp while


C php:
while ( biu_thc_logic ) khi_lnh;

Khi_lnh s c thc hin cho n khi no biu thc cn ng. Nu ngay t u biu thc sai, khi lnh s khng c thc thi.

3.5.3.3 Vng lp do while


C php:
do khi_lnh while ( biu_thc_logic )

Khc vi while khi lnh s c thc hin trc, sau biu thc c kim tra. Nu biu thc ng khi lnh li c thc hin.

3.5.3.4 Vng lp for


C php:
for ( [khi_to_bin_m]; [biu_thc]; [gia_tng_bin_m] ) khi lnh;

V d 3-4 Tnh tng cc s nguyn t a n b


int a = 10; int b = 100; int nTong = 0;

18

Nhng c s ca ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

for ( int i = a; i <= b; i++ ) { nTong += i; }

Cu lnh lp foreach s c trnh by cc chng sau.

3.5.3.5 Cu lnh break, continue, v return


C ba cu lnh break, continue, v return rt quen thuc trong C++ v Java, trong C#, ngha v cch s dng chng hon ton ging vi hai ngn ng ny.

3.6 Ton t
Cc php ton +, -, *, / l mt v d v ton t. p dng cc ton t ny ln cc bin kiu s ta c kt qu nh vic thc hin cc php ton thng thng.
int a = 10; int b = 20; int c = a + b; // c = 10 + 20 = 30

C# cung cp cp nhiu loi ton t khc nhau thao tc trn cc kiu bin d liu, c lit k trong bng sau theo tng nhm ng ngha.
Bng 3-3 Cc nhm ton t trong C#
Nhm ton t Ton hc Logic Ghp chui Tng, gim Dch bit Quan h Gn Ch s p kiu Indirection v Address Ton t + - * / % & | ^ ! ~ && || true false + ++, -<< >> == != < > <= >= = += -= *= /= %= &= |= ^= <<= >>= [] () * -> [] & dng cho con tr ngha cng , tr, nhn chia, ly phn d php ton logic v thao tc trn bit ghp ni 2 chui tng / gim ton hng ln / xung 1. ng trc hoc sau ton hng. dch tri, dch phi bng, khc, nh/ln hn, nh/ln hn hoc bng php gn cch truy xut phn t ca mng

3.6.1 Ton t gn (=)


Ton t ny cho php thay i cc gi tr ca bin bn phi ton t bng gi tr bn tri ton t.

19

Nhng c s ca ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

3.6.2 Nhm ton t ton hc


C# dng cc ton t s hc vi ngha theo ng tn ca chng nh: + (cng), (tr) , * (nhn) v / (chia). Ty theo kiu ca hai ton hng m ton t tr v kiu tng ng. Ngoi ra, cn c ton t % (ly phn d) c s dng trong cc kiu s nguyn.

3.6.3 Cc ton t tng v gim


C# cng k tha t C++ v Java cc ton t: +=,-=, *=, /= , %= nhm lm n gin ho. N cn k tha cc ton t tin t v hu t (nh bin++, hay ++bin) gim bt s cng knh trong cc ton t c in.

3.6.4 Cc ton t quan h


Cc ton t quan h c dng so snh hai gi tr vi nhau v kt qu tr v c kiu Boolean. Ton t quan h gm c: == (so snh bng), != (so snh khc), > (so snh ln hn), >= (ln hn hay bng), < (so snh nh hn), <= (nh hn hay bng).

3.6.5 Cc ton t logic


Cc ton t logic gm c: && (v), || (hoc), ! (ph nh). Cc ton t ny c dng trong cc biu thc iu kin kt hp cc ton t quan h theo mt ngha nht nh.

3.6.6 Th t cc ton t
i vi cc biu thc ton, th t u tin l th t c qui nh trong ton hc. Cn th t u tin thc hin ca cc nhm ton t c lit k theo bng di y
Bng 3-4 Th t u tin ca cc nhm ton t (chiu u tin t trn xung)
Nhm ton t Primary (chnh) Unary Nhn Cng Dch bt Quan h Bng Logic trn bit AND XOR OR Ton t {x} x.y f(x) a[x] x++ x-+ - ! ~ ++x x (T)x * / % + << >> < > <= >= is == != & ^ | Nhn, chia, ly phn d cng, tr Dch tri, dch phi nh hn, ln hn, nh hn hay bng, ln hn hay bng v l bng, khc V trn bit. Xor trn bit hoc trn bit ngha

20

Nhng c s ca ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

iu kin AND iu kin OR iu kin Assignment

&& || ?: = *= /= %= += -= <<= =>> &= ^= |=

V trn biu thc iu kin Hoc trn biu thc iu kin iu kin tng t if

3.6.7 Ton t tam phn


C php:
<biu thc iu kin>? <biu thc 1>: <biu thc 2>;

ngha:
Nu biu thc iu kin ng th thc hin biu thc 1. Nu sai th thc hin biu thc 2.

3.7 To vng tn
Nh c gii thch trong phn tch v d HelloWorld, vng tn l mt cch t chc m ngun thnh cc nhm c ng ngha lin quan. V d: Trong m hnh kin trc 3 lp (3 tng, ting Anh l 3 tier Architecture) chia mt ng dng ra thnh 3 tng: tng giao din, tng nghip v v tng d liu (Presentation, Bussiness v Data). Ta c th chia d n thnh 3 vng tn tng ng: Presentation, Bussiness v Data. Cc vng tn ny cha cc lp thuc v tng ca mnh. Mt vng tn cha cc lp v cc vng tn con khc. Vy trong v d trn ta s to mt vng tn chung cho ng dng l MyApplication v ba vng tn kia s l ba vng tn con ca vng tn MyApplication. Cch ny gii quyt c trng hp nu ta c nhiu d n m ch c 3 vng tn v dn n vic khng bit mt lp thuc vng tn Data nhng khng bit thuc d n no.
S o cay vung ten

MyApplication Presentation vung ten con Cac lp Bussiness vung ten con Cac lp Data vung ten con Cac lp

Vng tn con c truy xut thng qua tn vng tn cha cch nhau bng du chm. khai bo vng tn ta s dng t kha namespace. V d di y l 2 cch khai bo cc vng tn trong v d trn.

21

Nhng c s ca ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Cch 1
namespace MyApplication { namespace Presentation { // khai bo lp // khai bo vng tn con } namespace Bussiness { // khai bo lp // khai bo vng tn con } namespace Data { // khai bo lp // khai bo vng tn con } }

Cch 2
namespace { // khai // khai } namespace { // khai // khai } namespace { // khai // khai } MyApplication.Presentation bo lp bo vng tn con MyApplication.Bussiness bo lp bo vng tn con MyApplication.Data bo lp bo vng tn con

Cch khai bo vng tn th nht ch tin nu cc vng tn nm trn cng mt tp tin. Cch th hai tin li hn khi cc vng tn nm trn nhiu tp tin khc nhau.

3.8 Ch th tin x l
Khng phi mi cu lnh u c bin dch cng lc m c mt s trong chng c bin dch trc mt s khc. Cc cu lnh nh th ny gi l cc ch th tin x l. Cc ch th tin x l c t sau du #.

3.8.1 nh ngha cc nh danh


#define DEBUG nh ngha mt nh danh tin x l (preprocessor identifier) DEBUG. Mc d cc ch th tin x l c th nh ngha u tu thch nhng nh

danh tin x l bt buc phi nh ngha u ca chng trnh, trc c t kha using. Do , ta cn trnh by nh sau:
#define DEBUG //... m ngun bnh thng - khng nh hng bi b tin x l

22

Nhng c s ca ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

#if DEBUG // m ngun c bao gm trong chng trnh // khi chy di ch debug #else // m ngun c bao gm trong chng trnh // khi chy di ch khng debug #endif //... cc on m ngun khng nh hng tin x l

Trnh bin dch nhy n cc on tho iu kin tin bin dch bin dch trc.

3.8.2 Hy mt nh danh
Ta hy mt nh danh bng cch dng #undef. B tin x l duyt m ngun t trn xung di, nn nh danh c nh ngha t #define, hy khi gp #undef hay n ht chng trnh. Ta s vit l:
#define DEBUG #if DEBUG // m ngun c bin dch #endif #undef DEBUG #if DEBUG // m ngun s khng c bin dch #endif

3.8.3 #if, #elif, #else v #endif


y l cc ch th chn la xem c tin bin dch hay khng. Cc ch th trn c ngha tng t nh cu lnh iu kin if - else. Quan st v d sau:
#if DEBUG // bin dch on m ny nu DEBUG c nh ngha #elif TEST // bin dch on m ny nu DEBUG khng c nh ngha // nhng TEST c nh ngha #else // bin dch on m ny nu DEBUG ln TEST // khng c nh ngha #endif

3.8.4 Ch th #region v #endregion


Ch th phc v cho cc cng c IDE nh VS.NET cho php m/ng cc ghi ch.
#region ng m mt on m // m ngun #endregion

khi ny VS.NET cho php ng hoc m vng m ny. V d trn ang trng thi m. Khi trng thi ng n vh sau
ng m mt on m

23

Lp v i tng

Gvhd: Nguyn Tn Trn Minh Khang

Chng 4 Lp v i tng
i tng l mt tr c th c to ra, lu gi v s dng. Trong C# tt c cc bin u l i tng. Cc bin kiu s, kiu chui u l i tng. Mi mt i tng u c cc bin thnh vin lu gi d liu v c cc phng thc (hm) tc ng ln bin thnh vin. Mi i tng thuc v mt lp i tng no . Cc i tng c cng lp th c cng cc bin thnh vin v phng thc.

4.1 nh ngha lp
nh ngha mt lp mi vi c php nh sau:
[attribute][b t truy xut] class nh danh [:lp c s] { thn lp }

V d 4-1 Khai bo mt lp
public class Tester { public static int Main( ) { ... } }

Khi khai bo mt lp ta nh ngha cc c tnh chung ca tt c cc i tng ca lp v cc hnh vi ca chng. V d 4-2 Khai bo, to v s dng mt lp
using System; public class Time { // phng thc public public void DisplayCurrentTime( ) { Console.WriteLine( "stub for DisplayCurrentTime" ); } // cc bin private int Year; int Month; int Date; int Hour; int Minute; int Second; } public class Tester { static void Main( ) { Time t = new Time( ); t.DisplayCurrentTime( ); }

24

Lp v i tng

Gvhd: Nguyn Tn Trn Minh Khang

4.1.1 B t truy xut


B t truy xut xc nh thnh vin (ni tt ca bin thnh vin v phng thc thnh vin) no ca lp c truy xut t lp khc. C cc loi kiu truy xut sau:
Bng 4-1 Cc b t truy xut
T kha public protected internal protected internal private (mc nh) Gii thch Truy xut mi ni Truy xut trong ni b lp hoc trong cc lp con Truy xut ni trong chng trnh (assembly) Truy xut ni trong chng trnh (assembly) v trong cc lp con Ch c truy xut trong ni b lp

4.1.2 Cc tham s ca phng thc


Mi phng thc c th khng c tham s m cng c th c nhiu tham s. Cc tham s theo sau tn phng thc v t trong cp ngoc n. V d nh phng thc SomeMethod sau:
V d 4-3 Cc tham s v cch dng chng trong phng thc
using System; public class MyClass { public void SomeMethod(int firstParam, float secondParam) { Console.WriteLine("Here are the parameters received: {0}, {1}", firstParam, secondParam); } } public class Tester { static void Main( ) { int howManyPeople = 5; float pi = 3.14f; MyClass mc = new MyClass( ); mc.SomeMethod(howManyPeople, pi); } }

4.2 To i tng
To mt i tng bng cch khai bo kiu v sau dng t kho new to nh trong Java v C++.

25

Lp v i tng

Gvhd: Nguyn Tn Trn Minh Khang

4.2.1 Hm dng - Constructor


Hm dng l phng thc u tin c triu gi v ch gi mt ln khi khi to i tng, n nhm thit lp cc tham s u tin cho i tng. Tn hm dng trng tn lp; cn cc mt khc nh phng thc bnh thng. Nu lp khng nh ngha hm dng, trnh bin dch t ng to mt hm dng mc nh. Khi cc bin thnh vin s c khi to theo cc gi tr mc nh:
Bng 4-2 Kiu c s v gi tr mc nh
Kiu s (int, long, ) bool char enum Tham chiu Gi tr mc nh 0 false \0 (null) 0 null

V d 4-4 Cch to hm dng


public class Time { // public accessor methods public void DisplayCurrentTime( ) { System.Console.WriteLine("{0}/{1}/{2} {3}:{4}:{5}", Month, Date, Year, Hour, Minute, Second); } // constructor public Time(System.DateTime dt) { Year = dt.Year; Month = dt.Month; Date = dt.Day; Hour = dt.Hour; Minute = dt.Minute; Second = dt.Second; } // private member variables int Year; int Month; int Date; int Hour; int Minute; int Second; } public class Tester { static void Main( ) { System.DateTime currentTime = System.DateTime.Now; Time t = new Time(currentTime); t.DisplayCurrentTime( );

26

Lp v i tng

Gvhd: Nguyn Tn Trn Minh Khang

} } Kt qu: 11/16/2000 16:21:40

4.2.2 Khi to
Ta c th khi to gi tri cc bin thnh vin theo mun bng cch khi to n trong constructor ca lp hay c th gn vo trc tip lc khai bo. Vi gi tr khi to ny th khi mt i tng khai bo kiu ca lp ny th gi tr ban u l cc gi tr khi to ch khng phi l gi tr mc nh.

4.2.3 Hm dng sao chp


Hm dng sao chp (copy constructor) l sao chp ton b ni dung cc bin t i tng tn ti sang i tng mi khi to.
V d 4-5 Mt hm dng sao chp
public Time(Time existingTimeObject) { Year = existingTimeObject.Year; Month = existingTimeObject.Month; Date = existingTimeObject.Date; Hour = existingTimeObject.Hour; Minute = existingTimeObject.Minute; Second = existingTimeObject.Second; }

4.2.4 T kho this


T kho this c dng tham chiu n chnh bn thn ca i tng . V d:
public void SomeMethod (int hour) { this.hour = hour; }

4.3 S dng cc thnh vin tnh


Cc c tnh v phng thc ca mt lp c th l thnh vin th hin (instance member) hay thnh vin tnh. Thnh vin th hin th kt hp vi th hin ca mt kiu, trong khi cc thnh vin ca static n li l mt phn ca lp. Ta c th truy cp cc thnh vin static thng qua tn ca lp m khng cn to mt th hin lp.

4.3.1 Cch gi mt thnh vin tnh


Phng thc tnh (static) c ni l hot ng trong lp. Do , n khng th c tham chiu this ch ti. Phng thc static cng khng truy cp trc tip vo cc phng thc khng static c m phi dng qua th hin ca i tng.
V d 4-6 Cch s dng phng thc tnh
using System;

27

Lp v i tng

Gvhd: Nguyn Tn Trn Minh Khang

public class MyClass { public void SomeMethod(int firstParam, float secondParam) { Console.WriteLine( "Here are the parameters received: {0}, {1}", firstParam, secondParam); } } public class Tester { static void Main( ) { int howManyPeople = 5; float pi = 3.14f; MyClass mc = new MyClass( ); mc.SomeMethod(howManyPeople, pi); } }

Trong v d trn phng thc Main() l tnh v phng thc SomeMethod() khng l tnh.

4.3.2 S dng hm dng tnh


Hm dng tnh (static constructor) s c chy trc khi bt k i tng no to ra.V d:
static Time( ) { Name = "Time"; }

Khi dng hm dng tnh phi kh thn trng v n c th c kt qu kh lng.

4.3.3 Hm dng private


Khi mun to mt lp m khng cho php to bt k mt th hin no ca lp th ta dng hm dng private.

4.3.4 S dng cc trng tnh


Cch dng chung cc bin thnh vin tnh l gi vt ca mt s cc th hin m hin ti n ang tn ti trong lp .
V d 4-7 Cch dng trng tnh
using System; public class Cat { public Cat( ) { instances++; } public static void HowManyCats( ) {

28

Lp v i tng

Gvhd: Nguyn Tn Trn Minh Khang

} private static int instances = 0; } public class Tester { static void Main( ) { Cat.HowManyCats( ); Cat frisky = new Cat( ); Cat.HowManyCats( ); Cat whiskers = new Cat( ); Cat.HowManyCats( ); } } Kt qu: 0 cats adopted 1 cats adopted 2 cats adopted

Console.WriteLine("{0} cats adopted", instances);

Ta c th thy c rng phng thc static c th truy cp vo bin static.

4.4 Hy i tng
Ging vi Java, C# cng cung cp b thu dn rc t ng n s ngm hy cc bin khi khng dng. Tuy nhin trong mt s trng hp ta cng cn hy tng minh, khi ch vic ci t phng thc Finalize(), phng thc ny s c gi bi b thu dn rc. Ta khng cn phi gi phng thc ny.

4.4.1 Hy t ca C#
Hy t ca C# cng ging nh hy t trong C++. Khai bo mt hy t theo c php:
~<nh danh>() {}

trong , nh danh ca hy t trng vi dnh danh ca lp. hy tng minh ta gi phng thc Finalize() ca lp c s trong ni dung ca hy t ny.

4.4.2 Finalize hay Dispose


Finalize khng c php gi tng minh; tuy nhin trong trng hp ta ang gi mt ti nguyn h thng v hm gi c kh nng gii phng ti nguyn ny, ta s ci t giao din IDisposable (ch c mt phng thc Dispose). Giao din s c cpp chng sau.

4.4.3 Cu lnh using


Bi v ta khng th chc rng Dispose() s c gi v v vic gii phng ti nguyn khng th xc nh c, C# cung cp cho ta lnh using m bo rng Dispose() s c gi trong thi gian sm nht. V d sau minh ho vn ny:

29

Lp v i tng

Gvhd: Nguyn Tn Trn Minh Khang

V d 4-8 S dng using


using System.Drawing; class Tester { public static void Main( ) { using (Font theFont = new Font("Arial", 10.0f)) { // s dng theFont } // phng thc Dispose ca theFont c gi Font anotherFont = new Font("Courier",12.0f); using (anotherFont) { // s dng anotherFont } // phng thc Dispose ca anotherFont c gi } }

4.5 Truyn tham s


C# cung cp cc tham s ref h iu chnh gi tr ca nhng i tng bng cc tham chiu.

4.5.1 Truyn bng tham chiu


Mt hm ch c th tr v mt gi tr. Trong trng hp mun nhn v nhiu kt qu, ta s dng chnh cc tham s truyn cho hm nh cc tham s c u ra (cha tr tr v). Ta gi tham s truyn theo kiu ny l tham chiu. Trong C#, tt c cc bin c kiu tham chiu s mc nh l tham chiu khi cc bin ny c truyn cho hm. Cc bin kiu gi tr khai bo tham chiu, s dng t kha ref.
V d 4-9 Tr tr v trong tham s
public class Time { // mt phng thc public public void DisplayCurrentTime( ) { System.Console.WriteLine("{0}/{1}/{2} {3}:{4}:{5}", Month, Date, Year, Hour, Minute, Second); } public int GetHour( ) { return Hour; } public void GetTime(ref int h, ref int m, ref int s) { h = Hour; m = Minute; s = Second; } // hm dng public Time(System.DateTime dt)

30

Lp v i tng

Gvhd: Nguyn Tn Trn Minh Khang

Year = dt.Year; Month = dt.Month; Date = dt.Day; Hour = dt.Hour; Minute = dt.Minute; Second = dt.Second; thnh vin private int Year; int Month; int Date; int Hour; int Minute; int Second;

} // bin private private private private private private

} public class Tester { static void Main( ) { System.DateTime currentTime = System.DateTime.Now; Time t = new Time(currentTime); t.DisplayCurrentTime( ); int theHour = 0; int theMinute = 0; int theSecond = 0; t.GetTime(ref theHour, ref theMinute, ref theSecond); System.Console.WriteLine("Current time: {0}:{1}:{2}", theHour, theMinute, theSecond); } } Kt qu: 11/17/2000 13:41:18 Current time: 13:41:18

4.5.2 Truyn tham s u ra (out parameter)


Nh c p cc chng trc, d s dng c, mt bin phi c khai bo v khi to gi tr ban u. Nh trong V d 4-9 cc bin theHour, theMinute, theSecond phi c khi to gi tr 0 trc khi truyn cho hm GetTime. Sau li gi hm th gi tr cc bin s thay i ngay, v vy C# cung cp t kha out khng cn phi kho8\73i to tham s trc khi dng. Ta sa khai bo hm GetTime trong v d trn nh sau:
public void GetTime(out int h, out int m, out int s)

Hm Main() khng cn khi to trc tham s


int theHour, theMinute, theSecond; t.GetTime(out theHour, out theMinute, out theSecond);

V cc tham s khng c khi gn trc nn trong thn hm (nh trng hp ny l GetTime) khng th s dung cc tham s (thc hin php ly gi tr tham s) ny trc khi khi gn li trong thn hm. V d
public void GetTime(out int h, out int m, out int s) {

31

Lp v i tng

Gvhd: Nguyn Tn Trn Minh Khang

int nKhong_y_nghia = h; // li, h cha khi gn

4.6 Np chng phng thc v hm dng


Ta mun c nhiu phng thc cng tn m mi phng thc li c cc tham s khc nhau, s lng tham s cng c th khc nhau. Nh vy ngha ca cc phng thc c trong sng hn v cc phng thc linh ng hn trong nhiu trng hp. Np chng cho php ta lm c vic ny.
V d 4-10 Np chng hm dng
public class Time { // public accessor methods public void DisplayCurrentTime( ) { System.Console.WriteLine("{0}/{1}/{2} {3}:{4}:{5}", Month, Date, Year, Hour, Minute, Second); } // constructors public Time(System.DateTime dt) { Year = dt.Year; Month = dt.Month; Date = dt.Day; Hour = dt.Hour; Minute = dt.Minute; Second = dt.Second; } public Time(int Year, int Month, int Date, int Hour, int Minute, int Second) { this.Year = Year; this.Month = Month; this.Date = Date; this.Hour = Hour; this.Minute = Minute; this.Second = Second; } // private member variables private int Year; private int Month; private int Date; private int Hour; private int Minute; private int Second; } public class Tester { static void Main( ) { System.DateTime currentTime = System.DateTime.Now; Time t = new Time(currentTime); t.DisplayCurrentTime( ); Time t2 = new Time(2000,11,18,11,03,30); t2.DisplayCurrentTime( );

32

Lp v i tng

Gvhd: Nguyn Tn Trn Minh Khang

4.7 ng gi d liu vi property


Trong lp trnh C++, thng thng c hoc gn gi tr cho bin thnh vin, lp trnh vin thng vit hai hm get v set tng ng cho bin. C# cung cp khai bo hm chung gi l property cho hm get v set. V d: trong lp DocGia c bin thnh vin m_sHoTen, ci t Property cho bin thnh vin ny nh sau:
public string HoTen { get { return m_sHoTen; } set { m_sHoTen = value; } }

Property c mt vi khc bit so vi hm thnh vin. Th nht khai bo Property khng c tham s v cp ngoc. Trong thn property dng hai t kha get/set tng ng cho hai hnh ng ly/thit t gi tr thuc tnh. Trong thn set, c bin mc dnh l value, bin ny s mang kiu c khai bo property, nh trong trng hp trn l string. Bin value s nhn gi tr c gn cho Property. Cch s dng mt Property nh sau:
1 2 3 4 5 6 7 8 // trong thn ca mt hm DocGia dgMoi = new DocGia(); // s dung property set dgMoi.HoTen = "Nguyn Vn A"; // s dng property get string ten = dgMoi.HoTen; //ten c gi tr "Nguyn Vn A"

dng m th 5, khi set trong property HoTen s c gi, bin value s c gi tr ca bin nm sau php gn (trong trng hp ny l "Nguyn Van A"). Nu trong thn hm khng ci t hm set, property s c tnh ch c, php gn s b cm. Ngc li nu khng ci t hm get, property s c tnh ch ghi.
V d 4-11 Minh ha dng mt property
public class Time { // public accessor methods public void DisplayCurrentTime( ) { System.Console.WriteLine("Time\t: {0}/{1}/{2} {3}:{4}:{5}", month, date, year, hour, minute, second); } // constructors public Time(System.DateTime dt) { year = dt.Year; month = dt.Month; date = dt.Day;

33

Lp v i tng

Gvhd: Nguyn Tn Trn Minh Khang

hour = dt.Hour; minute = dt.Minute; second = dt.Second; } // to mt c tnh public int Hour { get { return hour; } set { hour = value; } } // cc bin thnh vin kiu private private int year; private int month; private int date; private int hour; private int minute; private int second; } public class Tester { static void Main( ) { System.DateTime currentTime = System.DateTime.Now; Time t = new Time(currentTime); t.DisplayCurrentTime( ); int theHour = t.Hour; System.Console.WriteLine("\nRetrieved the hour: {0}\n", theHour); theHour++; t.Hour = theHour; System.Console.WriteLine("Updated the hour: {0}\n", theHour); } }

4.7.1 Phng thc get


Thn ca phng thc truy cp get cng ging nh cc phng thc khc nhng phng thc ny tr v mt i tng kiu l mt c tnh ca lp. V d mun ly Hour nh sau:
get { return hour; }

4.7.2 Phng thc set


Phng thc set thit lp gi tr mt property ca i tng v c tr tr v l void. Phng thc set c th ghi vo c s d liu hay cp nht bin thnh vin khi cn. V d:
set { hour = value; }

4.7.3 Cc trng ch c
C# cung cp t kho readonly khai bo cc bin thnh vin. Cc bin khai bo kiu ny ch cho php gn gi tr cho bin mt ln vo lc khi to qua constructor.

34

Tha k v a hnh

Gvhd: Nguyn Tn Trn Minh Khang

Chng 5 Tha k v a hnh


Tha k l cch to mi mt lp t nhng lp c sn. Tc l n cho php ti s dng li m ngun vit trong lp c sn. Tha k ni n gin l vic to mt i tng khc B tha hng tt c cc c tnh ca lp A. Cch ny gi l n tha k. Nu lp B mun c c tnh ca nhiu lp A1, A2 th gi l a tha k. a tha k l khi nim rt kh ci t cho cc trnh bin dch. C# cng nh nhiu ngn ng khc tm cch trnh n khi nim ny. a hnh l vic lp B tha k cc c tnh t lp A nhng c thm mt s ci t ring.

5.1 c bit ho v tng qut ho


S c bit v tng qut ho c mi quan h tng h v phn cp. Khi ta ni ListBox v Button l nhng ca s (Window), c ngha rng ta tm thy c y cc c tnh v hnh vi ca Window u tn ti trong hai loi trn. Ta ni rng Window l tng qut ho ca ListBox v Button; ngc li ListBox v Button l hai c bit ho ca Window

5.2 S k tha
Trong C#, mi quan h chi tit ho l mt kiu k tha. S k tha khng cho mang ngha chi tit ho m cn mang ngha chung ca t nhin v mi quan h ny. Khi ta ni rng ListBox k tha t Window c ngha l n chi tit ho Window. Window c xem nh l lp c s (base class) v ListBox c xem l lp k tha (derived class). Lp ListBox ny nhn tt c cc c tnh v hnh vi ca Window v chi tit ho n bng mt s thuc tnh v phng thc ca n cn.

5.2.1 Thc hin k tha


Trong C#, khi ta to mt lp k tha bng cch cng mt thm du : v sau tn ca lp k tha v theo sau l lp c s nh sau:
public class ListBox : Window

c ngha l ta khai bo mt lp mi ListBox k tha t lp Window. Lp k tha s tha hng c tt cc phng thc v bin thnh vin ca lp c s, thm ch cn tha hng c cc thnh vin m c s tha hng.
V d 5-1 Minh ho cch dng lp k tha
public class Window {

35

Tha k v a hnh

Gvhd: Nguyn Tn Trn Minh Khang

// constructor takes two integers to // fix location on the console public Window(int top, int left) { this.top = top; this.left = left; } // simulates drawing the window public void DrawWindow( ) { System.Console.WriteLine("Drawing Window at {0}, {1}", top, left); } // these members are private and thus invisible // to derived class methods; we'll examine this // later in the chapter private int top; private int left; } // ListBox k tha t Window public class ListBox : Window { // thm tham s vo constructor public ListBox( int top, int left, string theContents): base(top, left) // gi constructor c s { mListBoxContents = theContents; } // to mt phng thc mi bi v trong // phng thc k tha c s thay i hnh vi public new void DrawWindow( ) { base.DrawWindow( ); // gi phng thc c s System.Console.WriteLine ("Writing string to the listbox: {0}", mListBoxContents); } private string mListBoxContents; // bin thnh vin mi } public class Tester { public static void Main( ) { // to mt th hin c s Window w = new Window(5,10); w.DrawWindow( ); // to mt th hin k tha ListBox lb = new ListBox(20,30,"Hello world"); lb.DrawWindow( ); } } Kt qu: Drawing Window at 5, 10 Drawing Window at 20, 30 Writing string to the listbox: Hello world

36

Tha k v a hnh

Gvhd: Nguyn Tn Trn Minh Khang

5.2.2 Gi hm dng lp c s
Trong V d 5-1 lp ListBox tha k t Window v c hm dng ba tham s. Trong hm dng ca ListBox c li gi n hm dng ca Window thng qua t kho base nh sau:
public ListBox( int top, int left, string theContents): base(top, left) // gi constructor c s

Bi v cc hm dng khng c tha k nn lp k tha phi thc hin hm dng ca ring n v ch c th dng hm dng c s thng qua li gi tng minh. Nu lp c s c hm dng mc nh th hm dng lp k tha khng cn thit phi gi hm dng c s mt cch tng minh (mc nh c gi ngm).

5.2.3 Gi cc phng thc ca lp c s


gi cc phng thc ca lp c s C# cho php ta dng t kho base gi n cc phng thc ca lp c s hin hnh.
base.DrawWindow( ); // gi phng thc c s

5.2.4 Cch iu khin truy cp


Cch truy cp vo cc thnh vin ca lp c gii hn thng qua cch dng cc t kho khai bo kiu truy cp v hiu chnh (nh trong chng 4.1). Xem Bng 4-1 Cc b t truy xut

5.3 a hnh
a hnh l vic lp B tha k cc c tnh t lp A nhng c thm mt s ci t ring. a hnh cng l cch c th dng nhiu dng ca mt kiu m khng quan tm n chi tit.

5.3.1 To kiu a hnh


ListBox v Button u l mt Window, ta mun c mt form gi tp hp tt c cc th hin ca Window khi mt th hin no c m th n c th bt Window ca n v ln. Ngn gn, form ny mun qun l mi c x ca tt c cc i tng a hnh ca Window.

5.3.2 To phng thc a hnh


To phng thc a hnh, ta cn t t kho virtual trong phng thc ca lp c s. V d nh:
public virtual void DrawWindow( )

Trong lp k tha np chng li m ngun ca lp c s ta dng t kho override khi khai bo phng thc v ni dung bn trong vit bnh thng. V d v np chng phng thc DrawWindow:
public override void DrawWindow( ) {

37

Tha k v a hnh

Gvhd: Nguyn Tn Trn Minh Khang

base.DrawWindow( ); // gi phng thc ca lp co s Console.WriteLine ("Writing string to the listbox: {0}", listBoxContents); }

Dng hnh thc a hnh phng thc ny th tu kiu khai bo ca i tng no th n dng phng thc ca lp .

5.3.3 To phin bn vi t kho new v override


Khi cn vit li mt phng thc trong lp k tha m c trong lp c s nhng ta khng mun np chng li phng thc virtual trong lp c s ta dng t kho new nh du trc khi t kho virtual trong lp k tha.
public class ListBox : Window { public new virtual void Sort( ) {...}

5.4 Lp tru tng


Phng thc tru tng l phng thc ch c tn thi v n phi c ci t li tt cc cc lp k tha. Lp tru tng ch thit lp mt c s cho cc lp k tha m n khng th c bt k mt th hin no tn ti.
V d 5-2 Minh ho phng thc v lp tru tng
using System; abstract public class Window { // constructor takes two integers to // fix location on the console public Window(int top, int left) { this.top = top; this.left = left; } // simulates drawing the window // notice: no implementation abstract public void DrawWindow( ); // these members are private and thus invisible // to derived class methods. We'll examine this // later in the chapter protected int top; protected int left; } // ListBox derives from Window public class ListBox : Window { // constructor adds a parameter public ListBox(int top, int left, string contents): base(top, left) // call base constructor { listBoxContents = contents; } // an overridden version implementing the // abstract method

38

Tha k v a hnh

Gvhd: Nguyn Tn Trn Minh Khang

} public class Button : Window { public Button( int top, int left): base(top, left) { } // implement the abstract method public override void DrawWindow( ) { Console.WriteLine("Drawing a button at {0}, {1}\n", top, left); } } public class Tester { static void Main( ) { Window[] winArray = new Window[3]; winArray[0] = new ListBox(1,2,"First List Box"); winArray[1] = new ListBox(3,4,"Second List Box"); winArray[2] = new Button(5,6); for (int i = 0;i < 3; i++) { winArray[i].DrawWindow( ); } } }

public override void DrawWindow( ) { Console.WriteLine("Writing string to the listbox: {0}", listBoxContents); } private string listBoxContents; // new member variable

5.4.1 Gii hn ca lp tru tng


V d trn, phng thc tru tng DrawWindow() ca lp tru tng Window c lp ListBox k tha. Nh vy, cc lp sau ny k tha t lp ListBox u phi thc hin li phng thc DrawWindow(), y l im gii hn ca lp tru tng. Hn na, nh th sau ny khng bao gi ta to c lp Window ng ngha. Do vy, nn chuyn lp tru tng thnh giao din tru tng.

5.4.2 Lp nim phong


Lp nim phong vi ngha tri ngc hn vi lp tru tng. Lp nim phong khng cho bt k lp no khc k tha n. Ta dng t kho sealed thay cho t kho abstract c lp ny.

5.5 Lp gc ca tt c cc lp: Object


Trong C#, cc lp k tha to thnh cy phn cp v lp cao nht (hay lp c bn nht) chnh l lp Object. Cc phng thc ca lp Object nh sau:

39

Tha k v a hnh

Gvhd: Nguyn Tn Trn Minh Khang

Bng 5-1 Cc phng thc ca lp i tng Object


Phng thc Equals GetHashCode GetType ToString Finalize() MemberwiswClone Cung cp kiu truy cp ca i tng Cung cp mt biu din chui ca i tng Xo sch b nh ti nguyn To sao chp i tng; nhng khng thc thi kiu ngha s dng So snh gi tr ca hai i tng

V d 5-3 Minh ho vic k tha lp Object


using System; public class SomeClass { public SomeClass(int val) { value = val; } public virtual string ToString( ) { return value.ToString( ); } private int value; } public class Tester { static void Main( ) { int i = 5; Console.WriteLine("The value of i is: {0}", i.ToString( )); SomeClass s = new SomeClass(7); Console.WriteLine("The value of s is {0}", s.ToString( )); } } Kt qu: The value of i is: 5 The value of s is 7

5.6 Kiu Boxing v Unboxing


Boxing v unboxing l tin trnh cho php kiu gi tr (value type) c i x nh kiu tham chiu (reference type). Bin kiu gi tr c "gi (boxed)" vo i tng Object, sau ngc li c "tho (unboxed)" v kiu gi tr nh c.

5.6.1 Boxing l ngm nh


Boxing l tin trnh chuyn i mt kiu gi tr thnh kiu Object. Boxing l mt gi tr c nh v trong mt th hin ca Object.

40

Tha k v a hnh

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 5-1 Kiu tham chiu Boxing

Boxing l ngm nh khi ta cung cp mt gi tr mt tham chiu n gi tr ny v gi tr c chuyn i ngm nh.


V d 5-4 Minh ha boxing
using System; class Boxing { public static void Main( ) { int i = 123; Console.WriteLine("The object value = {0}", i); } }

Console.WriteLine() mong ch mt i tng, khng phi l s nguyn. ph hp vi phng thc, kiu interger c t ng chuyn bi CLR v ToString() c gi ly kt qu i tng. c trng ny cho php ta to cc phng thc ly mt i tng nh l mt tham chiu hay gi tr tham s, phng thc s lm vic vi n.

5.6.2 Unboxing phi tng minh


Tr kt qu ca mt i tng v mt kiu gi tr, ta phi thc hin m tng minh n. Ta nn thit lp theo hai bc sau: 1. Chc chn rng i tng l th hin ca mt tr c box. 2. Sao chp gi tr t th hin ny thnh gi tr ca bin.

41

Tha k v a hnh

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 5-2 Boxing v sau unboxing

V d 5-5 Minh ha boxing v unboxing


using System; public class UnboxingTest { public static void Main( ) { int i = 123; //Boxing object o = i; // unboxing (must be explict) int j = (int) o; Console.WriteLine("j: {0}", j); } }

5.7 Lp lng
Lp c khai bo trong thn ca mt lp c gi l lp ni (inner class) hay lp lng (nested class), lp kia gi l lp ngoi (outer class). Lp ni c thun li l truy cp c trc tip tt c cc thnh vin ca lp ngoi. Mt phng thc ca lp ni cng c th truy cp n cc thnh vin kiu private ca cc lp ngoi. Hn na, lp ni n n trong lp ngoi so vi cc lp khc, n c th l thnh vin kiu private ca lp ngoi. Khi lp ni (vd: Inner) c khai bo public, n s c truy xut thng qua tn ca lp ngoi (vd: Outer) nh: Outer.Inner.
V d 5-6 Cch dng lp ni
using System; using System.Text; public class Fraction { public Fraction(int numerator, int denominator) { this.numerator=numerator; this.denominator=denominator;

42

Tha k v a hnh

Gvhd: Nguyn Tn Trn Minh Khang

} public class Tester { static void Main( ) { Fraction f1 = new Fraction(3,4); Console.WriteLine("f1: {0}", f1.ToString( )); Fraction.FractionArtist fa = new Fraction.FractionArtist(); fa.Draw(f1); } }

} // Methods elided... public override string ToString( ) { StringBuilder s = new StringBuilder( ); s.AppendFormat("{0}/{1}", numerator, denominator); return s.ToString( ); } internal class FractionArtist { public void Draw(Fraction f) { Console.WriteLine("Drawing the numerator: {0}", f.numerator); Console.WriteLine("Drawing the denominator: {0}", f.denominator); } } private int numerator; private int denominator;

43

Np chng ton t

Gvhd: Nguyn Tn Trn Minh Khang

Chng 6 Np chng ton t


Mc tiu thit k ca C# l kiu ngi dng nh ngha (lp) phi c i x nh cc kiu nh sn. V d, chng ta mun nh ngha lp phn s (Fraction) th cc chc nng nh cng, tr, nhn, phn s l iu tt yu phi c. lm c vic ta nh ngha cc phng thc: cng, nhn, khi , ta phi vit l:
Phn_s tng = s_th_nht.cng(s_th_hai);

Cch ny hi gng p v khng th hin ht ngha. iu ta mun l vit thnh:


Phn_s tng = s_th_nht + s_th_hai;

lm c iu ny ta dng t kho operator th hin.

6.1 Cch dng t kho operator


Trong C#, cc ton t l cc phng thc tnh, kt qu tr v ca n l gi tr biu din kt qu ca mt php ton v cc tham s l cc ton hng. Khi ta to mt ton t cho mt lp ta ni l ta np chng ton t, np chng ton t cng ging nh bt k vic np chng cc phng thc no khc. V d np chng ton t cng (+) ta vit nh sau:
public static Fraction operator+ (Fraction lhs, Fraction rhs)

N chuyn tham s lhs v pha tri ton t v rhs v pha phi ca ton t. C php C# cho php np chng ton t thng qua vic dng t kho operator.

6.2 Cch h tr cc ngn ng .Net khc


C# cung cp kh nng np chng ton t cho lp ca ta, ni ng ra l trong Common Language Specification (CLS). Nhng ngn ng khc nh VB.Net c th khng h tr np chng ton t, do , iu quan trng l ta cng cung cp cc phng thc h tr km theo cc ton t c th thc hin c cc mi trng khc. Do , khi ta np chng ton t cng (+) th ta cng nn cung cp thm phng thc add() vi cng ngha.

6.3 S hu ch ca cc ton t
Cc ton t c np chng c th gip cho on m ngun ca ta d nhn hn, d qun l v trong sng hn. Tuy nhin nu ta qu lm dng a vo cc ton t qu mi hay qu ring s lm cho chng trnh kh s dng cc ton t ny m i khi cn c cc nhm ln v v na.

44

Np chng ton t

Gvhd: Nguyn Tn Trn Minh Khang

6.4 Cc ton t logic hai ngi


Cc ton t kh ph bin l ton t (==) so snh bng gi hai i tng, (!=) so snh khng bng, (<) so snh nh hn, (>) so snh ln hn, (<=, >=) tng ng nh hn hay bng v ln hn hay bng l cc ton t phi c cp ton hng hay gi l cc ton t hai ngi.

6.5 Ton t so snh bng


Nu ta np chng ton t so snh bng (==), ta cng nn cung cp phng thc o Equals() bi object v hng chc nng ny n ton t bng. iu ny cho php lp ca ta a hnh v cung cp kh nng hu ch cho cc ngn ng .Net khc. Phng thc Equals() c khai bo nh sau:
public override bool Equals(object o)

Bng cch np chng phng thc ny, ta cho php lp Fraction a hnh vi tt c cc i tng khc. Ni dung ca Equals() ta cn phi m bo rng c s so snh vi i tng Fraction khc. Ta vit nh sau:
public override bool Equals(object o) { if (! (o is Fraction) ) { return false; } return this == (Fraction) o; }

Ton t is c dng kim tra kiu ang chy c ph hp vi ton hng yu cu khng. Do , o is Fraction l ng nu o c kiu l Fraction.

6.6 Ton t chuyn i kiu (p kiu)


Trong C# cng nh C++ hay Java, khi ta chuyn t kiu thp hn (kch thc nh) ln kiu cao hn (kch thc ln) th vic chuyn i ny lun thnh cng nhng khi chuyn t kiu cao xung kiu thp c th ta s mt thng tin. V d ta chuyn t int thnh long lun lun thnh cng nhng khi chuyn ngc li t long thnh int th c th trn s khng nh ca ta. Do khi chuyn t kiu cao xung thp ta phi chuyn tng minh. Cng vy mun chuyn t int thnh kiu Fraction lun thnh cng, ta dng t kho implicit biu th ton t kiu ny. Nhng khi chuyn t kiu Fraction c th s mt thng tin do vy ta dng t kho explicit biu th ton t chuyn i tng minh.
V d 6-1 Minh ho chuyn i ngm nh v tng minh
using System; public class Fraction { public Fraction(int numerator, int denominator)

45

Np chng ton t

Gvhd: Nguyn Tn Trn Minh Khang

Console.WriteLine("In Fraction Constructor(int, int)"); this.numerator=numerator; this.denominator=denominator;

} public Fraction(int wholeNumber) { Console.WriteLine("In Fraction Constructor(int)"); numerator = wholeNumber; denominator = 1; } public static implicit operator Fraction(int theInt) { System.Console.WriteLine("In implicit conversion to Fraction"); return new Fraction(theInt); } public static explicit operator int(Fraction theFraction) { System.Console.WriteLine("In explicit conversion to int"); return theFraction.numerator / theFraction.denominator; } public static bool operator==(Fraction lhs, Fraction rhs) { Console.WriteLine("In operator =="); if (lhs.denominator == rhs.denominator && lhs.numerator == rhs.numerator) { return true; } // code here to handle unlike fractions return false; } public static bool operator !=(Fraction lhs, Fraction rhs) { Console.WriteLine("In operator !="); return !(lhs==rhs); } public override bool Equals(object o) { Console.WriteLine("In method Equals"); if (! (o is Fraction) ) { return false; } return this == (Fraction) o; } public static Fraction operator+(Fraction lhs, Fraction rhs) { Console.WriteLine("In operator+"); if (lhs.denominator == rhs.denominator) { return new Fraction(lhs.numerator+rhs.numerator, lhs.denominator); } // simplistic solution for unlike fractions // 1/2 + 3/4 == (1*4) + (3*2) / (2*4) == 10/8 int firstProduct = lhs.numerator * rhs.denominator; int secondProduct = rhs.numerator * lhs.denominator;

46

Np chng ton t

Gvhd: Nguyn Tn Trn Minh Khang

return new Fraction( firstProduct + secondProduct, lhs.denominator * rhs.denominator ); } public override string ToString( ) { String s = numerator.ToString( ) + "/" + denominator.ToString( ); return s; } private int numerator; private int denominator;

} public class Tester { static void Main( ) { //implicit conversion to Fraction Fraction f1 = new Fraction(3); Console.WriteLine("f1: {0}", f1.ToString( )); Fraction f2 = new Fraction(2,4); Console.WriteLine("f2: {0}", f2.ToString( )); Fraction f3 = f1 + f2; Console.WriteLine("f1 + f2 = f3: {0}", f3.ToString( )); Fraction f4 = f3 + 5; Console.WriteLine("f3 + 5 = f4: {0}", f4.ToString( )); Fraction f5 = new Fraction(2,4); if (f5 == f2) { Console.WriteLine("F5: {0} == F2: {1}", f5.ToString( ), f2.ToString( )); } int k = (int)f4; //explicit conversion to int Console.WriteLine("int: F5 = {0}", k.ToString()); } }

47

Cu trc

Gvhd: Nguyn Tn Trn Minh Khang

Chng 7 Cu trc
Mt cu trc (struct) l mt kiu do ngi dng nh ngha, n tng t nh lp nh nh hn lp.

7.1 nh ngha cu trc


C php
[thuc tnh] [kiu truy cp] struct <nh danh> [: <danh sch cc giao din >] { // Cc thnh vin ca cu trc }

V d 7-1 Minh ha cch khai bo v dng mt cu trc


using System; public struct Location { public Location(int xCoordinate, int yCoordinate) { xVal = xCoordinate; yVal = yCoordinate; } public int x { get{ return xVal; } set{ xVal = value; } } public int y { get{ return yVal; } set{ yVal = value; } } public override string ToString( ) { return (String.Format("{0}, {1}", xVal,yVal)); } private int xVal; private int yVal; } public class Tester { public void myFunc(Location loc) { loc.x = 50; loc.y = 100; Console.WriteLine("Loc1 location: {0}", loc); } static void Main( ) { Location loc1 = new Location(200,300);

48

Cu trc

Gvhd: Nguyn Tn Trn Minh Khang

Console.WriteLine("Loc1 location: {0}", loc1); Tester t = new Tester( ); t.myFunc(loc1); Console.WriteLine("Loc1 location: {0}", loc1); } } Kt qu: Loc1 location: 200, 300 In MyFunc loc: 50, 100 Loc1 location: 200, 300

Khng ging nh lp, cu trc khng h tr k tha. Tt c cc cu trc tha k ngm nh object nhng n khng th tha k t bt k lp hay cu trc no khc. Cc cu trc cng ngm nh l nim phong. Tuy nhin, n c im ging vi lp l cho php ci t a giao din. Cu trc khng c hy t cng nh khng th t cc tham s tu cho hm dng. Nu ta khng ci t bt k hm dng no th cu trc c cung cp hm dng mc nh, t gi tr 0 cho tt c cc bin thnh vin. Do cu trc c thit k cho nh nhng nn cc bin thnh vin u l kiu private v c gi gn li ht. Tu tng tnh hung v mc ch s dng m ta cn cn nhc chn la dng lp hay cu trc.

7.2 Cch to cu trc


Mun to mt th hin ca cu trc ta dng t kho new. V d nh:
Location loc1 = new Location(200,300);

7.2.1 Cu trc nh cc kiu gi tr


Khi ta khai bo v to mi mt cu trc nh trn l ta gi n constructor ca cu trc. Trong V d 7-1 trnh bin dch t ng ng gi cu trc v n c ng gi kiu object thng qua WriteLine(). ToString()c gi theo ku ca object, bi v cc cu trc tha k ngm t object, nn n c kh nng a hnh, np chng phng thc nh bt k i tng no khc. Cu trc l object gi tr v khi n qua mt hm, n c thng qua nh gi tr.

7.2.2 Gi hm dng mc nh
Theo trn trnh by khi ta khng to bt k ny th khi to mt th hin ca cu trc thng qua t kho new n s gi n constructor mc nh ca cu trc. Ni dung ca constructor s t gi tr cc bin v 0.

7.2.3 To cu trc khng dng new


Bi v cu trc khng phi l lp, do , th hin ca lp c to trn stack. Cu trc cng cho php to m khng cn dng t kho new, nhng trong trng hp ny constructor khng c gi (c mc nh ln ngi dng nh ngha).

49

Giao din

Gvhd: Nguyn Tn Trn Minh Khang

Chng 8 Giao din


Giao din nh ngha cc hp ng (constract). Cc lp hay cu trc ci t giao din ny phi tn trng hp ng ny. iu ny c ngha l khng nh vi client (ngi dng lp hay cu trc) rng Ti bo m rng ti s h tr y y cc phng thc, property, event, delegate, indexer c ghi trong giao din Mt giao din c th tha k mt hay nhiu giao din khc, v mt lp hay cu trc c th ci t mt hay nhiu giao din. Quan st v pha lp trnh th giao din l tp cc hm c khai bo sn m khng ci t. Cc lp hay cu trc ci t c nhim v phi ci tt c cc hm ny.

8.1 Ci t mt giao din


C php ca vic nh ngha mt giao din:
[attributes] [access-modifier] interface interface-name [:base-list] { interface-body }

ngha ca tng thnh phn nh sau


attributes: s cp phn sau. modifiers: b t phm vi truy xut ca giao din identifier: tn giao din mun to base-list: danh sch cc giao din m giao din ny tha k, (ni r trong phn tha k) interface-body: thn giao din lun nm gia cp du {}

Trong th vin .NET Framework cc giao din thng bt u bi ch I (i hoa), iu ny khng bt buc. Gi s rng chng ta to mt giao din cho cc lp mun lu tr xung/c ra t c s d liu hay cc h lu tr khc. t tn giao din ny l IStorable, cha hai phng thc Read( ) v Write( ).
interface IStorable { void Read( ); void Write(object); }

Giao din nh ng tn ca n: khng d liu, khng ci t. Mt giao din ch trng ra cc kh nng, v khi nng ny s c hin thc ho trong cc lp ci t n. V d nh ta to lp Document, do mun cc i tng Document s c lu tr vo c s d liu, nn ta cho Document k tha (ci t) giao din IStorable.
// lp Document tha k IStorable, // phi ci t tt c cc phng thc ca IStorable public class Document : IStorable

50

Giao din

Gvhd: Nguyn Tn Trn Minh Khang

public void Read( ) { // phi ci t...} public void Write(object obj) { // phi ci t...} // ...

8.1.1 Ci t nhiu giao din


Lp c th ci t mt hoc nhiu giao din. Chng hn nh lp Document ngoi lu tr ra n cn c th c nn li. Ta cho lp Document ci t thm mt giao din th hai l ICompressible
public class Document : IStorable, ICompressible

Tng t, Document phi ci t tt c phng thc ca ICompressible:


public void Compress( ) { Console.WriteLine("Implementing the Compress Method"); } public void Decompress( ) { Console.WriteLine("Implementing the Decompress Method"); }

8.1.2 M rng giao din


Chng ta c th m rng (tha k) mt giao din tn ti bng cch thm vo nhng phng thc hoc thnh vin mi. Chng hn nh ta c th m rng ICompressable thnh ILoggedCompressable vi phng thc theo di nhng byte c lu:
interface ILoggedCompressible : ICompressible { void LogSavedBytes( ); }

Lp ci t phi cn nhc chn la gia 2 lp ICompressable hay ILoggedCompressable, iu ny ph thuc vo nhu cu ca lp . Nu mt lp c s dng giao din ILoggedCompressable th n phi thc hin ton b cc phng thc ca ILoggedCompressable (bao gm ICompressable v phng thc m rng).

8.1.3 Kt hp cc giao din khc nhau


Tng t, chng ta c th to mt giao din mi bng vic kt hp nhiu giao din v ta c th ty chn vic c thm nhng phng thc hoc nhng thuc tnh mi. V d nh ta to ra giao din IStorableCompressable t giao din IStorable v ILoggedCompressable v thm vo mt phng thc mi dng lu tr kch thc tp tin trc khi nn.
interface IStorableCompressible: IStoreable,ILoggedCompressible { void LogOriginalSize( ); }

51

Giao din

Gvhd: Nguyn Tn Trn Minh Khang

8.2 Truy xut phng thc ca giao din


Chng ta c th truy xut thnh vin ca giao din IStorable nh chng l thnh vin ca lp Document:
Document doc = new Document("Test Document"); doc.status = -1; doc.Read( );

hoc ta c th to mt th din ca giao din bng vic phn phi ti liu v kiu ca giao din v sau s dng giao din truy cp nhng phng thc:
IStorable isDoc = (IStorable) doc; isDoc.status = 0; isDoc.Read( );

In this case, in Main( ) you know that Document is in fact an IStorable, so you can take advantage of that knowledge. As stated earlier, you cannot instantiate an interface directly. That is, you cannot say:
IStorable isDoc = new IStorable( );

Mc d vy, chng ta c th to mt th hin ca lp thi cng nh sau:


Document doc = new Document("Test Document");

Sau y ta c th to mt th hin ca giao din bng vic phn b nhng i tng thi cng n nhng kiu giao din, trong trng hp ny l IStorable:
IStorable isDoc = (IStorable) doc;

Chng ta kt hp nhng bc m t trn bng on m di y:


IStorable isDoc = (IStorable) new Document("Test Document");

8.2.1 p kiu thnh giao din


Trong nhiu trng hp, chng ta khng bit i tng y h tr nhng giao din loi g. Gi s nh chng ta c mt tp cc giao din ca Documents, mt s trong chng c th lu tr cn mt s khc th khng th, chng ta s thm vo mt giao din th hai ICompressable cho nhng i tng thuc loi ny chng c th nn li cho cng vic chuyn i c lin quan n email nhanh hn.
interface ICompressible { void Compress( ); void Decompress( ); }

Vi kiu ca Document, chng ta c th khng bit rng chng c h tr bi giao din IStorable hoc giao din ICompressable hoc c hai. Chng ta c th gii quyt iu ny bng cch phn b nhng giao din li:
Document doc = new Document("Test Document"); IStorable isDoc = (IStorable) doc; isDoc.Read( ); ICompressible icDoc = (ICompressible) doc; icDoc.Compress( );

Nu Document ch h tr bi giao din IStorable th gi tr tr v l:

52

Giao din

Gvhd: Nguyn Tn Trn Minh Khang

public class Document : IStorable

Vic phn b ICompressable phi n khi bin dch mi bit c bi v ICompressable l mt giao din hp l. Mc d vy, nu s phn b ti th c th s xy ra li, v lc y th mt exception s c qung ra cnh bo:
An exception of type System.InvalidCastException was thrown.

Chi tit v exception s c cp trong nhng chng sau:

8.2.2 Ton t is
Khi chng ta mun mt i tng c kh nng h tr giao din, theo nguyn tc l chng ta phi gi phng thc tng ng ln. Trong C# c 2 phng thc h tr cng vic ny. C php nh sau:
expression is type hay if (doc is IStorable)

Chc lp giao din IStorable chc bn vn cn nh, y cu lnh if s kim tra xem i tng doc c h tr giao din IStorable khng m thi. Tht khng may mn cho chng ta, tuy rt d hiu vi cch vit nh th nhng chng li khng hiu qu cho lm. hiu vn l ti sao li nh th th chng ta cn phi nhng chng vo trong m MSIL v sau pht sinh. V sau y l mt s kt qu (th hin bng s Hexa)
IL_0023: isinst ICompressible IL_0028: brfalse.s IL_0039 IL_002a: ldloc.0 IL_002b: castclass ICompressible IL_0030: stloc.2 IL_0031: ldloc.2 IL_0032: callvirt instance void ICompressible::Compress( ) IL_0037: br.s IL_0043 IL_0039: ldstr "Compressible not supported"

C mt s vn l chng ta phi ch l trong phn kim tra ICompressable trong dng 23. T kha isinst l m MSIL ca tc t is. Nh ta thy trong phn kim tra i tng doc pha bn phi v dng 2b th vic kim tra thnh cng khi castclass c gi.

8.2.3 Ton t as
Ton t as kt hp tc t is v s phn b cc thao tc bng vic kim tra s phn b c hp l hay khng (gi tr s tr v l true) v sau y s hon tt cng vic. Nu s phn b khng hp l (tc t is s tr v gi tr false), tc t as s tr v gi tr null. C php ca vic khai bo:
expression as type

on m sau y s dng tc t as:


static void Main( )

53

Giao din

Gvhd: Nguyn Tn Trn Minh Khang

Document doc = new Document("Test Document"); IStorable isDoc = doc as IStorable; if (isDoc != null) isDoc.Read( ); else Console.WriteLine("IStorable not supported"); ICompressible icDoc = doc as ICompressible; if (icDoc != null) icDoc.Compress( ); else Console.WriteLine("Compressible not supported");

Hy xem qua on m MSIL, chng ta thy c mt s im thun tin:


IL_0023: IL_0028: IL_0029: IL_002a: IL_002c: IL_002d: isinst ICompressible stloc.2 ldloc.2 brfalse.s IL_0034 ldloc.2 callvirt instance void ICompressible::Compress( )

8.2.4 Ton t is hay ton t as


Cc giao din xem ra c v l nhng lp tru tng. Tht ra th chng ta c th thay i phn khai bo ca giao din IStorable thnh lp tru tng:
abstract class Storable { abstract public void Read( ); abstract public void Write( ); }

Lp Document k tha t lp Storable, gi s nh chng ta va mua mt lp List t mt hng th ba vi mong mun l c s kt hp ca List vi Storable. Trong C++ ta c th to mt lp StorableList bng cch k tha t List v Storable nhng trong C# th ta khng th v C# khng h tr a tha k. Mc d vy, C# cho php chng ta ch r ra s giao din v kt xut t lp c s. Bng vc to mt giao din Storable, ta c th k tha t lp List v giao din IStorable nh trong v d sau:
public class StorableList : List, IStorable { // List methods here ... public void Read( ) {...} public void Write(object obj) {...} // ... }

8.3 Np chng phn ci t giao din


Mt lp thi cng tht s t do th phi nh du mt vi hoc ton b cc phng thc c th thc hin c giao din nh l phng thc o. Lp dn xut t chng c th np chng. Chng hn nh lp Document c th thc hin giao din

54

Giao din

Gvhd: Nguyn Tn Trn Minh Khang

IStorable v xem cc phng thc Read( ) v Write( ) nh l phng thc o. Ngi pht trin c th kt xut t nhng kiu ca Document, nh l kiu Note hay EmailMessage v anh ta c l quyt nh Note vi tnh nng l s c c v vit vo c s d liu hn l vic th hin bng mt tp tin.

8.4 Thc hin giao din mt cch tng minh


Bi v mt lp c th ci t nhiu giao din nn c th xy ra trng hp ng v tn khi khi hai giao din c cng mt tn hm. gii quyt xung t ny ta khai bo ci t mt cch tng minh hn. V d nh nu ta c hai giao din IStorable v ITalk u cng c phng thc Read(), lp Document s ci t hai giao din ny. Khi ta ta phi thm tn giao din vo trc tn phng thc
using System; interface IStorable { void Read( ); void Write( ); } interface ITalk { void Talk( ); void Read( ); } public class Document : IStorable, ITalk { // document constructor public Document(string s) { Console.WriteLine("Creating document with: {0}", s); } // to read ca IStorable public virtual void Read( ) { Console.WriteLine("Implementing IStorable.Read"); } public void Write( ) { Console.WriteLine("Implementing IStorable.Write"); } // ci t phng htc Read ca ITalk void ITalk.Read( ) { Console.WriteLine("Implementing ITalk.Read"); } public void Talk( ) { Console.WriteLine("Implementing ITalk.Talk"); }

} public class Tester { static void Main( )

55

Giao din

Gvhd: Nguyn Tn Trn Minh Khang

// create a document object Document theDoc = new Document("Test Document"); // p kiu c th gi IStorable.Read() IStorable isDoc = theDoc as IStorable; if (isDoc != null) { isDoc.Read( ); } // p kiu c th gi ITalk.Read() ITalk itDoc = theDoc as ITalk; if (itDoc != null) { itDoc.Read( ); } theDoc.Read( ); theDoc.Talk( );

} } Kt qu: Creating document with: Test Document Implementing IStorable.Read Implementing ITalk.Read Implementing IStorable.Read Implementing ITalk.Talk

8.4.1 Chn la phi by cc phng thc ca giao din


Ngi thit k lp c thm mt thn li l khi mt giao din c thi cng th trong sut qu trnh y s thi cng tng minh y khng c th hin bn pha client ngoi tr vic phn b. Gi s nh i tng Document thi cng giao din IStorable nhng chng ta khng mun cc phng thc Read( ) v Write( ) c xem nh l public trong lp Document. Chng ta c th s dng phn thc hin tng minh chc rng chng khng sn c trong sut qu trnh phn b. iu ny cho php chng gi gn ng ngha ca lp Document trong khi ta thc hin IStorable. Nu Client mun mt object c th thi cng trn giao din IStorable, th chng phi c s phn b mt cch tng minh nhng khi s dng ti liu ca chng ta nh l Document trong ng ngha l s khng c cc phng thc Read( ) v Write ( ).

8.4.2 Thnh vin n


Vi mt kh nng mi l mt thnh vin ca giao din c th c n i. V d nh chng ta to mt giao din IBase vi property P:
interface IBase { int P { get; set; } }

56

Giao din

Gvhd: Nguyn Tn Trn Minh Khang

V khi nhng giao din c k tha t n, chng hn IDerived th property P oc n i vi mt phng thc mi P( )
interface IDerived : IBase { new int P( ); }

Vic lm n thnh vin nh l lm trn i vi IBase c th xem nh l mt tng tt, by gi th chng ta c th n property P trong giao din c s. V trong nhng giao din c k tha t chng s phi cn ti thiu l 1 giao din thnh vin tng minh. Do ta c th s dng phn thi cng tng minh ny cho property c s hoc cho nhng phng thc k tha hoc s dng c hai. Do m ta c th 3 phin bn ci t khc nhau nhng vn hp l:
class myClass : IDerived { // explicit implementation for the base property int IBase.P { get {...} } // implicit implementation of the derived method public int P( ) {...} } class myClass : IDerived { // implicit implementation for the base property public int P { get {...} } // explicit implementation of the derived method int IDerived.P( ) {...} } class myClass : IDerived { // explicit implementation for the base property int IBase.P { get {...} } // explicit implementation of the derived method int IDerived.P( ) {...} }

57

Array, Indexer, and Collection

Gvhd: Nguyn Tn Trn Minh Khang

Chng 9 Array, Indexer, and Collection


.NET Framework cung cp cho ta rt nhiu kiu lp tp hp: Array, ArrayList, NameValueCollection, StringCollection, Queue, Stack, v BitArray. Array l lp n gin nht. Trong C# n c nh x thnh c php dng sn tng t nh C/C++. Net Framework cng cung np nhng giao din chun nh IEnumerable, ICollection tng tc vi cc lp tp hp (ti cha).

9.1 Mng (Array)


Mng l mt tp hp cc phn t c cng kiu, c xc nh v tr trong tp hp bng ch mc. C# cung cp nhng dng c php dng n gin nht cho vic khai bo mt mng, rt d hc v s dng.

9.1.1 Khai bo mng


Chng ta c th khai bo mt mng kiu C# nh sau:
kiu[] tn_mng;

V d nh:
int[] myIntArray;

Du ngoc vung [ ] biu th cho tn bin sau l mt mng V d di y khai bo mt bin kiu mng nguyn myIntArray vi s phn t ban u l 5:
myIntArray = new int[5];

9.1.2 Gi tr mc nh
Gi s c on m sau:
/*1*/ int[] myArray; /*2*/ maArray = new int[5]; /*3*/ Button[] myButtonArray; /*4*/ myButtonArray = new Button[5];

dng /*1*/ khai bo bin myArray l mt mng kiu int. Khi ny bin myArray c gi tr l null do cha c khi to. Dng /*2*/ khi to bin myArray, cc phn t trong mng c khi to bng gi tr mc nh l 0. Dng /*3*/ tng t /*1*/ nhng Button thuc kiu tham chiu (reference type). Dng /*4*/ khi to bin myButtonArray, cc phn t trong mng khng c khi to (gi tr "khi to" l null). S dng bt k phn t no ca mng cng gy li cha khi to bin.

58

Array, Indexer, and Collection

Gvhd: Nguyn Tn Trn Minh Khang

9.1.3 Truy cp n nhng phn t trong mng


truy cp n nhng phn t trong mng, ta s dng ton t ly ch mc []. Cng ging nh C/C++, ch mc mng c tnh bt u t phn t 0. Property Length ca lp Array cho bit c kch thc mt mng. Nh vy ch mc ca mng i t 0 n Length - 1. Trong mng myArray v d trn ly phn t th 2 (c ch s l 1) trong mng, ta vit nh sau:
int phan_tu_thu_hai = myArray[1];

9.2 Cu lnh foreach


foreach l mt lnh vng lp, dng duyt tt c cc phn t ca mt mng, tp hp (ni ng hn l nhng lp c ci t giao din IEnumerable). C php ca foreach nh nhng hn vng lp for (ta c th dng for thay cho foreach)
foreach (kiu tn_bin in bin_mng) { khi lnh }

V d 9-1 S dng foreach


using System; namespace Programming_CSharp { // mt lp n gin cha trong mng public class Employee { public Employee(int empID) { this.empID = empID; } public override string ToString() { return empID.ToString(); } private int empID; private int size; } public class Tester { static void Main() { int[] intArray; Employee[] empArray; intArray = new int[5]; empArray = new Employee[3]; // populate the array for (int i = 0; i < empArray.Length; i++) empArray[i] = new Employee(i+10); foreach (int i in intArray) Console.WriteLine(i.ToString()); foreach (Employee e in empArray) Console.WriteLine(e.ToString());

59

Array, Indexer, and Collection

Gvhd: Nguyn Tn Trn Minh Khang

} }

9.2.1 Khi to cc phn t mng


Ta c th khi to cc phn t mng vo thi im khai bo mng, bng cch ta cung cp mt danh sch nhng gi tr ca mng c gii hn trong hai du ngoc nhn { }. C# c th cung cp nhng c phpngn gn nh sau:
int[] myIntArray = new int[5] { 2, 4, 6, 8, 10 } int[] myIntArray = { 2, 4, 6, 8, 10 }

Hai cch trn cho cng kt qu l mt mng 5 phn t c gi tr l 2, 4, 6, 8, 10.

9.2.2 T kha params


i lc c nhng phng thc ta khng bit trc s lng tham s c truyn vo nh: phng thc Main() khng th bit trc s lng tham s ngi dng s truyn vo. Ta c th s tham s l mng. Tuy nhin khi gi hm ta phi to mt bin mng lm tham s. C# cung cp c php ta khng cn truyn trc tip cc phn t ca mng bng cch thm t kha params
V d 9-2 S dng t kha params
using System; namespace Programming_CSharp { public class Tester { static void Main( ) { Tester t = new Tester( ); /** * cch truyn tham s bng cc phn t * khng cn phi khi to mng * (c php rt t do) */ t.DisplayVals(5,6,7,8); /** * Cch truyn tham s bng mng * Mng phi c to sn */ int [] explicitArray = new int[5] {1,2,3,4,5}; t.DisplayVals(explicitArray);

} public void DisplayVals(params int[] intVals) { foreach (int i in intVals) { Console.WriteLine("DisplayVals {0}",i); } }

60

Array, Indexer, and Collection

Gvhd: Nguyn Tn Trn Minh Khang

} } Kt qu: DisplayVals DisplayVals DisplayVals DisplayVals DisplayVals DisplayVals DisplayVals DisplayVals DisplayVals

5 6 7 8 1 2 3 4 5

9.2.3 Mng nhiu chiu


Ma trn l mt v d v mng hai chiu. C# cho php khai bo mng n chiu, tuy nhin thng dng nht vn l mng mt chiu (mng) v mng hai chiu. V d trong phn ny l mng hai chiu, tuy nhin i vi n chiu c php vn tng t.

9.2.3.1 Mng ch nht


Trong mng ch nht (Rectangular array) 2 chiu, chiu th nht l s dng v chiu th hai l s ct. S phn t trong cc dng l nh nhau v bng s ct (tng t s phn t trong cc ct l nh nhau v bng s dng) khai bo ta s dng c php sau:
type [,] array-name

v d nh:
int [,] myRectangularArray;

9.2.3.2 Mng Jagged


Mng jagged l loi mng trong mng. Loi mng ny tht s th chng ch l mng mt chiu nhng nhng phn t ca chng c kh nng qun l c mt mng khc na, m kch thc cc mng ny thay i ty theo nhu cu ca lp trnh vin. Ta c th khai bo nh sau:
type [ ] [ ]...

V d nh khai bo mt mng hai chiu vi tn l myJaggedArray:


int [ ] [ ] myJaggedArray;

Chng ta c th truy cp phn t th 5 ca mng th ba bng c php myJaggedArray[2][4]

9.2.4 Lp System.Array
Lp Array c rt nhiu hm hu ch, n lm cho mng trong C# "thng minh" hn nhiu ngn ng khc. Chng c h tr nh l cc phng thc c dng sn nh trng hp string. Hai phng thc quan trong nht ca lp System.Array l Sort() v Reverse().

61

Array, Indexer, and Collection

Gvhd: Nguyn Tn Trn Minh Khang

9.3 Indexers
Indexer tng t nh Property, tuy c khc nhau mt cht v ngha. Xt mt v d m phng mt quyn sch c nhiu chng

Xy dng 2 lp Sch v Chng. Lp Chng ci t bnh thng. Vi lp Sch ta s ci t mt bin thnh vin c kiu ti cha. n gin bin ny c kiu l mt mng
public class Chuong { // Cc bin thnh vin string m_sTen; string m_sNoiDung; } public class Sach { // bin thnh vin Chuong[] m_dsChuong; // Property public Chuong[] DsChuong { get{ return m_dsChuong; } } }

Cch lm ny c vi bt li nh sau: th nht ly ni dung tng chng chng ta dng Property ly danh sach chng sau duyt qua mng ly chng mong mun. Th hai l mi chng c nh danh bi tn chng nn ta mong mun c cch ly mt chng thng qua tn ca n. Ta c th ci t mt hm duyt qua mng cc chng, nhng Indexer s gip lm vic ny.
V d 9-3 S dng indexer
using System; using System.Collections; namespace ConsoleApplication { // Ci t lp Chuong public class Chuong { private string m_sTen; private string m_sNoiDung; public Chuong() { m_sTen = ""; m_sNoiDung = ""; } public Chuong(string sTen, string sNoiDung) { m_sTen = sTen;

62

Array, Indexer, and Collection

Gvhd: Nguyn Tn Trn Minh Khang

m_sNoiDung = sNoiDung; } public string Ten { get { return m_sTen; } set { m_sTen = value; } } public string NoiDung { get { return m_sNoiDung; } set { m_sNoiDung = value; } } } // ht class Chuong // Ci t lp Sach public class Sach { private string m_sTen; private ArrayList m_dsChuong; public Sach() { m_sTen = ""; m_dsChuong = new ArrayList(); } public Sach(string sTen) { m_sTen = sTen; m_dsChuong = new ArrayList(); } public string Ten { get { return m_sTen; } set { if ( value == null ) throw new ArgumentNullException(); } m_sTen = value;

} // indexer th nht c mt tham s kiu int public Chuong this[int index] { get { if ( index < 0 || index > m_dsChuong.Count - 1 ) return null; return (Chuong)m_dsChuong[index]; } set { if ( index < 0 || index > m_dsChuong.Count - 1 ) throw new ArgumentOutOfRangeException(); m_dsChuong[index] = value; } }

63

Array, Indexer, and Collection

Gvhd: Nguyn Tn Trn Minh Khang

// indexer th hai c mt tham s kiu string public Chuong this[string tenChuong] { get { foreach (Chuong chuong in m_dsChuong) { if ( chuong.Ten == tenChuong ) { return chuong; } } return null; } } public int add (Chuong chuong) { if ( chuong == null ) throw new ArgumentNullException(); return m_dsChuong.Add(chuong); } }// ht class Sach class Class { static void Main(string[] args) { Sach s = new Sach("tlv"); s.add(new Chuong("CS", "Tac gia CS")); s.add(new Chuong("VB", "Tac gia VB")); Console.WriteLine(s.Ten); // dng indexer th nht Console.WriteLine(s[0].Ten + ": "+ s[0].NoiDung); // dng indexer th hai Console.WriteLine("VB: " + s["VB"].NoiDung); Console.Read(); } } }

Trc ht quan st lp Sach xem khai bo mt indexer


// indexer th nht c mt tham s kiu int public Chuong this[int index] public: phm vi truy xut ca indexer Chuong: kiu tr v int index: kiu v tn tham s nhn vo this[...]: bt buc khai bo indexer

Thn hm Indexer cng chia thnh 2 hm get v set y ht nh Property. Indexer cung cp thm mt hoc nhiu tham s v cho ta cch s dng nh s dng mt mng:
// dng indexer th nht Console.WriteLine(s[0].Ten + ": "+ s[0].NoiDung);

64

Array, Indexer, and Collection

Gvhd: Nguyn Tn Trn Minh Khang

// dng indexer th hai Console.WriteLine("VB: " + s["VB"].NoiDung);

9.4 Cc giao din ti cha


.NET Framework cung cp mt s cc giao din chun tng tc vi cc lp ti cha hay ci t cc lp ti cha mi tng thch (c cng giao din) vi cc lp chun ca .NET Framework. Cc giao din c lit k Bng 9-1 Cc giao din ti cha
Bng 9-1 Cc giao din ti cha
Giao din IEnumerable ICollection IComparer IList IDictionary IDictionaryEnumerator ngha Khi mt lp ci t giao din ny, i tng thuc lp c c dng trong cu lnh foreach c ci t bi tt c cc lp ti cha c thnh vin CopyTo(), Count, IsReadOnly(), IsSyncronize(), SyncRoot() So snh hai i tng trong ti cha Dng bi cc lp ti cha truy xut phn t thng qua ch mc (s) Dng bi cc lp ti cha truy xut phn t thng qua quan h kha/gi tr nh Hashtabe, StoredList. Cho php duyt i vi cc ti cha ci t IDictionary

9.5 Array Lists


Mt vn c in trong khi s dng lp Array l kch thc: kch thc mt mng c nh. Nu khng th bit trc cn c bao nhiu phn t, ta c th khai bo qu nhiu (lng ph) hay qu ch (chng trnh c li). ArrayList ci t cu trc d liu danh sach lit k cho php cp pht ng cc phn t. Lp ny ci t giao din IList, ICollection, IEnumerable v c rt nhiu hm dng thao tc ln danh sch. IComparable ArrayList c phng thc Sort( ) gip chng ta sp xp cc phn t. iu bt buc l phn t phi thuc lp c ci t giao din IComparable (c duy nht mt phng thc CompareTo()).

9.6 Hng i
Hng i (queue) l mt ti cha hot ng theo c ch FIFO (First in first out vo trc ra trc). Cng ging nh ta i xp hng mua v xem phim, nu ta vo trc mua v th ta s c mua v trc. Hng i l mt tp hp tt cho vic ta s dng qun l ngun ti nguyn c gii hn. V d nh ta gi i nhng thng ip n ti nguyn, m ti nguyn th ch c th gii quyt cho mt thng ip. Do chng ta phi to mt hng i nhng

65

Array, Indexer, and Collection

Gvhd: Nguyn Tn Trn Minh Khang

thng ip cho ti nguyn c th da vo m x l t t. Lp Queue ci t ti cha ny.

9.7 Stacks
Stack l ti cha hot ng theo c ch LIFO (Last in first out - vo sau ra trc). Hai phng thc c bn trong vic thm hoc xa Stack l:Push( ) v Pop( ). Ngoi ra Stack cn c phng thc Peek( ), tng t nh Pop() nhng khng xa b phn t ny. Cc lp ArrayList, Queue v Stack u c nhng phng thc ging nhau nh CopyTo( ) v ToArray( ) dng sao chp nhng phn t vo trong mt mng. Trong trng hp Stack th phng thc CopyTo( ) s sao chp nhng phn t vo mt mng mt chiu tn ti, v ni dung chng s ghi ln v tr bt u m chng ta ch nh. Phng thc ToArray( ) tr v mt mng mi vi ni dung l nhngphn t trong stack.

9.8 Dictionary
Dictionary l tn gi chung cho cc ti cha lu tr cc phn t theo quan h kha/gi tr. iu ny c ngha l tng ng vi mt "kha", ta tm c mt v ch duy nht mt "gi tr" tng ng.Ni cch khc l mt "gi tr" c mt "kha" duy nht khng trng vi bt k "kha" ca gi tr khc. Mt lp mun l mt Dictionary th ci t giao din IDictionary. Lp Dictionary mun c s dng trong cu lnh foreach th ci t giao din IDictionaryEnumerator. Dictionary thng c dng nht l bng bm (Hashtable). Bng bm Hashtable l cu trc d liu c mc tiu ti u ha vic tm kim. .et Framework cung cp lp Hashtable ci t cu trc d liu ny. Mt i tng c dng nh "kha" phi ci t hay tha k phng thc Object.GetHashCode() v Object.Equals() (cc lp th vin .NET Framework hin nhin tha iu kin ny). Mt iu kin na l i tng ny phi immutable (d liu cc trng thnh vin khng thay i) trong lc ang l kha.

66

Chui

Gvhd: Nguyn Tn Trn Minh Khang

Chng 10 Chui
Chui (string) trong C# l mt kiu dng sn nh cc kiu int, long, c y tnh cht mm do, mnh m v d dng. Mt i tng chui trong C# l mt hay nhiu k t Unicode khng th thay i th t. Ni cch khc l cc phng thc p dng ln chui khng lm thay i bn thn chui, chng ch to mt bn sao c sa i, chui gc vn gi nguyn. khai bo mt i tng chui, s dng t kha string; i tng ny tht s trng vi i tng System.String trong th vin lp .NET Framework. Vic s dng hai i tng ny l nh nhau trong mi trng hp. Khai bo lp System.String nh sau:
public sealed class String:IComparable,ICloneable,Iconvertible

Khai bo ny c ngha nh sau:


seal - khng th tha k t lp ny ICompareable - cc i tng chui c th c sp th th IClonable - c th to mt i tng B mi y ht i tng A. IConvertible - c th chuyn thnh cc kiu dng sn khc nh ToInt32(), ToDouble()

10.1 To chui mi
Cch n gin nht to mt bin kiu chui l khai bo v gn mt chui cho n
string sChuoi = "Khai bo v gn mt chui";

Mt s k t c bit c qui tc ring nh "\n", "\\" hay "\t" i din cho k t xung dng, du xuyt (\), du tabV d khai bo
string sDuongDan = "C:\\WinNT\\Temp";

bin sDuongDan s c gi tr C:\WinNT\Temp. C# cung cp mt cch khai bo theo ng nguyn gc chui bng cch thm k t @. Khai bo sDuongDan s nh sau
string sDuongDan = @"C:\WinNT\Temp";

10.2 Phng thc ToString()


y l phng thc ca i tng object (v ca tt c cc i tng khc) thng dng chuyn mt i tng bt k sang kiu chui.
int myInteger = 5; string integerString = myInteger.ToString();

Chui intergerString c gi tr l "5". Bng cch ny ta cng c th to mt chui mi. Chui cng c th c to thng qua hm dng ca lp System.String. Lp ny c hm dng nhn vo mt mng cc k t. Nh vy ta cng to c chui t mng k t.

67

Chui

Gvhd: Nguyn Tn Trn Minh Khang

10.3 Thao tc chui


Lp chui cung cp nhiu phng thc cho vic so snh, tm kim c lit k trong bng sau:
Bng 10-1 Cc thnh vin lp string
Thnh vin Empty Compare() CompareOrdinal() Concat() Copy() Equals() Format() Intern() IsInterned() Join() Chars Length Clone() CompareTo() CopyTo() EndsWith() Equals() Insert() LastIndexOf() PadLeft() PadRight() Remove() Split() StartsWith() SubString() ToCharArray() ToLower() ToUpper() Trim() Gii thch Bin thnh vin tnh i din cho mt chui rng Phng thc tnh so snh hai chui Phng thc tnh, so snh 2 chui khng quan tm n ngn ng Phng thc tnh, to mt chui mi t nhiu chui Phng thc tnh, to mt bn sao Phng thc tnh, so snh hai chui c ging nhau Phng thc tnh, nh dng chui bng cc nh dng c t Phng thc tnh, nhn v mt tham chiu n chui Phng thc tnh, nhn v mt tham chiu n chui tn ti Phng thc tnh, ghp ni nhiu chui, mm do hn Concat() Indexer ca chui Chiu di chui (s k t) Tr v mt chui So snh vi chui khc Sao chp mt lng k t trong chui sang mng k t Xc nh chui c kt thc bng chui tham s khng Xc nh hai chui c cng gi tr Chn mt chui khc vo chui v tr xut hin cui cng ca mt chui con trong chui Canh phi cc k t trong chui, chn thm cc khong trng bn tri khi cn Canh tri cc k t trong chui, chn thm cc khong trng bn phi khi cn Xa mt s k t Ct mt chui thnh nhiu chui con Xc nh chui c bt u bng mt chui con tham s Ly mt chui con Sao chp cc k t ca chui thnh mng cc k t To bn sao chui ch thng To bn sao chui ch hoa Ct b cc khong trng hai u chui

68

Chui

Gvhd: Nguyn Tn Trn Minh Khang

Thnh vin TrimEnd() TrimStart()

Gii thch Ct b khong trng cui chui Ct b khong trng u chui

bit chi tit cc s dng ca cc hm trn, c th tham tho ti liu ca Microsoft, c bit l MSDN. Di y ch gii thiu vi phng thc thao dng thao tc chui. Ghp chui ghp 2 chui ta dng ton t +
string a = "Xin"; string b = "cho"; string c = a + " " + b; // c = "Xin cho"

Ch : vic ghp ni bng ton t + tuy cho m ngun p, t nhin nhng s khng cho hiu qu tt khi thc hin nhiu ln v C# s cp pht vng nh li sau mi php ghp chui. Ly k t ly mt k t ti mt v tr trn chui ta dng ton t []
string s = "Xin cho mi ngi"; char c = s[5]; // c = 'h'

Ch : v tr rn chui bt u t v tr s 0 Chiu di chui bit s k t ca chui, dng thuc tnh Length


string s = "Xin cho"; int l = s.Length; // l = 8

Ch : khng cn ng ngoc sau property Ly chui con ly chui con ca mt chui, s dng phng thc Substring().
string s; /* 1 */ s = "Lay chuoi con".Substring(4);// s = "chuoi con" /* 2 */ s = "Lay chuoi con".Substring(4, 5); // s = "chuoi"

Trong /*1*/ s ly chui con tnh t v tr th 4 tr v sau, cn trong /*2*/ s ly chui con t v tr th 4 v ly chui con c chiu di l 5. Thay th chui con thay th chui con trong chui bng mt chui con khc, s dng phng thc
Replace()
string s; /* 1 */ s = "thay the chuoi.".Replace('t', 'T'); // s = "Thay The chuoi" /* 2 */ s = "thay the chuoi.".Replace("th", "TH");

69

Chui

Gvhd: Nguyn Tn Trn Minh Khang

// s = "THay THe chuoi"

Trong /*1*/ s l chui thay th k t 't' thnh 'T', cn trong /*2*/ l chui thay th chui "th" thnh "TH". nh dng chui Chui c s dng nhiu trong trng hp kt xut kt qu ra cho ngi dng. Trong nhiu trng hp ta khng th c c chnh xc chui cn thit m phi ph thuc vo mt s bin. V vy hm nh dng chui gip ta nh dng li chui trc khi kt xut.
double d = tinh_toan_phuc_tap_1(); double e = tinh_toan_phuc_tap_2(); // gi s d = 2.5, e = 3.5 string s; s = string.Format("Kt qu l: {0:C} va {1:c} la", d, e); // s = "Kt qu l: $2.5 v $3.5 la"

Hm nh dng chui kh phc tp v c nhiu ty chn. C php c hm nh dng tng qut nh sau
string.Format(provider, format, arguments) provider: ngun cung cp nh dng format: chui cn nh dng cha thng tin nh dng arguments: cc thng s cho nh dng

C# to sn cc ngun nh ng cho kiu s, kiu dng nhiu nht, v vy ta ch quan tm n c php rt gn sau v cc thng tin nh dng cho kiu s.
string.Format (format, arguments);

Hnh 10-1 Vi nh dng thng dng


K t C hoc c D hoc d E hoc e F hoc f G hoc g N hoc n X hoc x M t Tin t (Currency) Decimal Khoa hoc (Scientific) C nh phn thp phn (Fixed-point) General S (Number) H s 16 (Hexadecimal) V d string.Format("{0:C}", 2.5); string.Format("{0:C}", -2.5); string.Format("{0:D5}", 25); string.Format("{0:E}", 250000); string.Format("{0:F2}", 25); string.Format("{0:F0}", 25); string.Format("{0:G}", 2.5); string.Format("{0:N}", 2500000); string.Format("{0:X}", 250); string.Format("{0:X}", 0xffff); Kt qu $2.50 ($2.50) 00025 2.500000E+005 25.00 25 2.5 2,500,000.00 FA FFFF

10.4 Thao tc chui ng


Sau mi thao tc ln chui s to ra mt bn sao chui mi. V vy s dng i tng string c th lm gim hiu nng h thng. Khi ta nn s dng lp StringBuilder (mt loi chui khc). Cc thao tc ln chui lm thay i trn chnh chui. Vi phng thc quan trng ca lp c lit k di y.

70

Chui

Gvhd: Nguyn Tn Trn Minh Khang

Phng thc

Gii thch

Capacity Chars Length MaxCapacity Append() AppendFormat() EnsureCapacity() Insert() Remove() Replace()

Ly/thit t s k t ti a chui c th lu gi Indexer Kch thc chui Ly s k t ti a lp c th lu gi Thm mt i tng vo cui chui nh dng chui tham s, sau thm chui ny vo cui Xc nh chui c th lu gi ti thiu mt lng k t khng Chn mt i tng vo chui ti v tr Xa mt s k t trong chui Thay mt k t/chui con bng k t/chui con mi

V d 10-1 S dng StringBuilder


using System; using System.Text; namespace Programming_CSharp { public class StringTester { static void Main( ) { // mt chui bt k thao tc string s1 = "One,Two,Three Liberty Associates, Inc."; // hng k t const char Space = ' '; const char Comma = ','; // mng cc du cch char[] delimiters = new char[]{ Space, Comma }; // dng StringBuilder to mt chui StringBuilder output = new StringBuilder( ); int ctr = 1; // tch chui, sau ghp li theo dang mong mun // tch chui theo cc du phn cch trong delimiter foreach (string subString in s1.Split(delimiters)) { // chn mt chui sau khi nh dng chui xong output.AppendFormat("{0}: {1}\n",ctr++,subString); } Console.WriteLine(output); } } } Kt qu: 1: One 2: Two 3: Three 4: Liberty 5: Associates 6: 7: Inc.

71

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

Chng 11 Qun l li
C# qun l li v cc trng thi bt thng bng bit l (exception). Mt bit l l mt i tng cha cc thng tin v s c bt thng ca chng trnh. iu quan trng trc ht l phi phn bit r s khc nhau gia bug, error v bit l. Bug l li v mt lp trnh do chnh lp trnh vin khng kim sot c m ngun. Bit l khng th sa cc bug. Mc d bug s pht sinh (nm) mt bit l, chng ta khng nn da vo cc bit l sa cc bug, m nn vit li m ngun cho ng. Error l li gy ra bi ngi dng. Chng hn nh ngi dng nhp mt con s thay v phi nhp cc k t ch ci. Mt error cng nm ra mt bit l, nhng ta c th ngn chn bng cch bt ly li ny, yu cu ngi dng chnh sa cho n khi hp l. Bt c khi no c th, error nn c tin on trc v ngn chn. Ngay c khi cc bug c sa, cc error c tin on ht th vn cn nhiu tnh hung khng th lng trc nh: h thng ht b nh hay chng trnh ang truy cp mt tp tin khng tn ti. Chng ta khng th ngn chn c bit l nhng c li c th qun l c chng chng khng lm gy ng dng. Khi chng trnh gp phi tnh hung trn, chng hn ht b nh, n s nm (pht sinh) mt bit l. Khi mt bit l c nm ra, hm ang thc thi s b tm dng v vng nh stack s c duyt ngc cho n khi gp trnh gii quyt bit l. iu ny c ngha l nu hm hin hnh khng c trnh gii quyt bit l th hm s b ngt v hm gi s c c hi gii quyt li. Nu khng c hm gi no gii quyt bit l th bit l s c nm cho CLR gii quyt. iu ny ng ngha vi vic chng trnh s b dng mt cch bt thng. Trnh qun l li (exception handler) l mt on m c thit k gii quyt cc bit l c nm ra. Trnh gii quyt li c ci t trong khi lnh bt u bi t kha catch{}. Mt cch l tng th khi bit l c bt v gii quyt th chng trnh tip tc thc thi v vn c gii quyt. Ngay c trong trng hp chng trnh khng th tip tc c th bng cch bt bit l ta vn cn mt c hi in (hoc ghi li thnh tp tin) cc thng bo li v kt thc chng trnh mt m p. Nu trong hm c nhng on m phi c thc thi bt chp c hay khng c xy ra bit l (nh on m gii phng cc ngun lc c cp pht), on m ny nn c b trong khi lnh finnally{}.

72

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

11.1 Nm v bt bit l
Trong C# chng ta c th nm bt k mt i tng no thuc lp hay lp con ca lp System.Exception (vit tt l Exception). Vng tn System khai bo sn nhiu lp bit l hu ch chng hn nh ArgumentNullException, InValidCastException, OverflowException

11.1.1 Lnh nm throw


bo hiu mt tnh hung bt thng trong mt lp C#, ta nm ra mt bit l bng cch s dng t kha throw. Dng lnh sau to mt th hin ca lp Exception v sau nm n ra
throw new System.Exception();

Nm mt bit l s lm chng trnh tm dng lp tc v CLR tm kim mt trnh qun l bit l. Nu hm nm khng c trnh gii quyt bit l, stack s c duyt ngc (unwind) bng cch pop ra cho n khi gp c trnh gii quyt bit l. Nu vn khng tm thy cho n tn hm Main(), chng trnh s b dng li. V d 11-1. Nm mt bit l
using System; namespace Programming_CSharp { 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..."); } } } Kt qu: Enter Main... Enter Func1... Enter Func2... Exception occurred: System.Exception: An exception of type System.Exception was thrown. at Programming_CSharp.Test.Func2( )

73

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

in at in at in

...exceptions01.cs:line 26 Programming_CSharp.Test.Func1( ) ...exceptions01.cs:line 20 Programming_CSharp.Test.Main( ) ...exceptions01.cs:line 12

V d trn in thng bo ra mn hnh console khi bt u v kt thc mi hm. Hm Main() to mt i tng kiu Test v gi hm Func1(). Sau khi in thng bo Enter Func1, hm Func1() gi hm Func2(). Func2() in ra cu thng bo bt u v nm ra mt bit l. Chng trnh s tm ngng thc thi v CLR tm trnh gii quyt bit l trong hm Func2(). Khng c, vng nh stack c unwind cho n hm Func1(). Vn khng c, vng nh stack tip tc c unwind cho n hm Main(). Vn khng c, trnh gii quyt bit l mc nh c gi. Thng bo li hin th trn mn hnh.

11.1.2 Lnh bt catch


Trnh gii quyt bit l t trong khi lnh catch, bt u bng t kha catch. Trong v d 11-2, lnh nm throw c t trong khi lnh try, lnh bt t trong khi catch. V d 11-2.Bt mt bit l.
using System; namespace Programming_CSharp { 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..."); try { Console.WriteLine("Entering try block..."); throw new System.Exception( ); Console.WriteLine("Exiting try block..."); } catch {

74

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

Console.WriteLine( "Exception caught and handled."); } Console.WriteLine("Exit Func2..."); } } Kt qu: Enter Main... Enter Func1... Enter Func2... Entering try block... Exception caught and handled. Exit Func2... Exit Func1... Exit Main... }

V d ny y ht nh v d 11-1 ngoi tr chng trnh c t trong khi lnh try/catch. Ta t cc on m d gy li trong khi lnh try, chng hn nh on m truy cp tp tin, xin cp pht vng nh. Theo sau khi lnh try l khi lnh catch. Khi lnh catch trong v d l khi lnh catch chung v ta khng th on trc c loi bit l no s pht sinh. Nu bit chnh xc loi bit l no pht sinh, ta s vit khi lnh catch cho loi bit l (s cp phn sau).

11.1.2.1 Sa cha li lm
Trong v d 11-2, lnh bt catch ch n gin thng bo rng mt bit l c bt v qun l. Trong ng dng thc t, chng ta s vit cc on m gii quyt li y. V d nu ngi dng c m mt tp ch c, ta hn cho gi mt phng thc cho php ngi dng thay i thuc tnh tp tin. Nu trng hp ht b nh, ta hn cho ngi dng c hi ng cc ng dng khc. Nu tt c u tht bi, khi lnh catch s cho in cc thng bo m t chi tit li ngi dng bit r vn .

11.1.2.2 Duyt li (unwind) vng nh stack


Nu xem kt qu v d 11-2 cn thn, ta s thy cc thng bo bt u hm Main(), Func1(), Func2() v khi lnh try; tuy nhin li khng thy thng bo kt thc khi try mc d n thot khi hm Func2(), Func1() v hm
Main().

Khi mt bit l xy ra, khi try ngng thc thi ngay lp tc v quyn c trao cho khi lnh catch. N s khng bao gi quay tr li khi try v v th khng th in dng lnh thot khi try. Sau khi hon tt khi lnh catch, cc dng lnh sau khi catch c thc thi tip tc. Khng c khi catch, vng nh stack c duyt ngc, nhng nu c khi catch vic ny s khng xy ra. Bit l c gii quyt, khng cn li na,

75

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

chng trnh tip tc thc thi. iu ny s r rng hn nu t try/catch trong hm Func1() nh trong v d 11-3 V d 11-3. Bt bit l trong hm gi.
using System; namespace Programming_CSharp { 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..."); try { Console.WriteLine("Entering try block..."); Func2( ); Console.WriteLine("Exiting try block..."); } catch { Console.WriteLine( "Exception caught and handled." ); } Console.WriteLine("Exit Func1..."); } public void Func2( ) { Console.WriteLine("Enter Func2..."); throw new System.Exception( ); Console.WriteLine("Exit Func2..."); } } } Kt qu: Enter Main... Enter Func1... Entering try block... Enter Func2... Exception caught and handled. Exit Func1... Exit Main...

By gi bit l khng c gii quyt trong trong hm Func2(), n c gii quyt trong hm Func1(). Khi Func2() c gi, n in dng Enter Func2 v sau nm mt bit l. Chng trnh tm ngng thc thi, CLR tm kim trnh gii quyt bit l trong hm Func2(). Khng c. Vng nh stack c duyt ngc v CLR tm thy trnh gii quyt bit l trong hm Func1(). Khi lnh catch c gi, chng trnh tip tc thc thi sau khi lnh catch ny, in ra dng Exit

76

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

ca Func1() v sau l ca Main(). Dng Exit Try Block v dng Exit Func2 khng c in.

11.1.2.3 To mt lnh catch chuyn dng


Ta c th to mt lnh catch chuyn dng qun l mt loi bit l. V d 11-4 m t cch xc nh loi bit l no ta nn qun l. V d 11-4. Xc nh bit l phi bt
using System; namespace Programming_CSharp { public class Test { public static void Main( ) { Test t = new Test( ); t.TestFunc( ); } // th chia hai s // v gii quyt cc bit l public void TestFunc( ) { try { double a = 5; double b = 0; Console.WriteLine("{0}/{1}={2}", a, b, DoDivide(a,b)); } // cc bit l thuc lp con phi ng trc catch (System.DivideByZeroException) { Console.WriteLine("DivideByZeroException caught!"); } catch (System.ArithmeticException) { Console.WriteLine("ArithmeticException caught!"); } // bit l tng qut ng sau cng catch { Console.WriteLine("Unknown exception caught"); } } // thc hin php chia hp 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; } } }

77

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

Kt qu: DivideByZeroException caught!

Trong v d ny, DoDivide() s khng cho php chia mt s cho 0 hay chia 0 cho s khc. N s nm ra bit l DivideByZeroException nu ta c chia cho khng. Nu ta em chia 0 cho s khc, s khng c bit l thch hp: v chia khng cho mt s l mt php ton hp l v khng nn nm bt k bit l no. Tuy nhin gi s trong v d ny ta khng mun em 0 chia cho s khc v s nm ra bit l ArithmeticException. Khi mt bit l c nm ra, CLR tm kim trnh gii quyt bit l theo theo trnh t, v chn trnh gii quyt ph hp vi bit l. Khi chy chng trnh vi a = 5 v b = 7, kt qu l:
5 / 7 = 0.7142857142857143

Khng c bit l no pht sinh. Tuy nhin nu thay a = 0, kt qu s l:


ArithmeticException caught!

Mt bit l c nm ra, v CLR xc nh trnh gii quyt bit l u tin: DivideByZeroException. Khng ng, CLR s i n trnh gii quyt bit l kt tip, ArithmeticException. Cui cng, nu a=7, v b=0 bit l DivideByZeroException c nm ra. Ghi ch: Bi v DevideByZero tha k t ArithmeticException, nn trong v d trn nu hon v hai khi lnh catch th c th khi lnh catch bt bit l DivideByZeroException s khng bao gi c thc thi. Thay vo khi catch bt bit l ArithmeticException s bt cc bit l DivideByZeroException. Trnh bin dch s nhn ra iu ny v bo li. Thng thng hm s bt cc bit l chuyn dng cho ring mc tiu ca hm, cn cc bit l tng qut hn s do cc hm cp cao hn bt.

11.1.3 Lnh finally


Trong mt s trng hp, nm mt bit l v unwind vng nh stack c th gy thm vn . V d nh nu ta ang m mt tp tin hoc ni chung l ang gi mt ti nguyn no khc, ta mong mun c mt c hi ng tp tin hay gii phng ti nguyn . Trong trng hp ng mt tp tin ang m, ta c th gii quyt bng cch vit mt lnh ng khi try mt khi catch (nh vy lnh ng s lun c gi). Tuy nhin on m ny lp li mt cch v l. Mc khc cch ny c th khng gii quyt c nu ta quyt nh khng vit khi catch hm ny m giao cho hm gi x l. Khi khng th vit lnh ng tp tin. Cch vit p nht l trong khi finally. Khi lnh ny chc chn c gi cho d c hay khng c xy ra bit l. V d 11-5 chng minh cho iu ny

78

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

V d 11-5. S dng khi lnh finally


using System; namespace Programming_CSharp { public class Test { public static void Main( ) { Test t = new Test( ); t.TestFunc( ); } // th chia hai s // v gii quyt cc bit l public void TestFunc( ) { try { 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 may not print"); } catch (System.DivideByZeroException) { Console.WriteLine("DivideByZeroException caught!"); } catch { Console.WriteLine("Unknown exception caught"); } finally { Console.WriteLine ("Close file here."); } } // thc hin php chia hp 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; } } } Kt qu: Open file here DivideByZeroException caught! Close file here. Output when b = 12: Open file here 5 / 12 = 0.41666666666666669 This line may or may not print Close file here.

79

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

Trong v d ny dng thng bo Close file here lun lun xut hin, cho d bit l c xy ra hay khng. Ghi ch: khi lnh finally c th c to m khng cn khi catch, nhng bt buc phi c khi try. Khng th dng cc lnh break, continue, return v goto trong khi finally.

11.2 i tng Exception


i tng System.Exception cung cp nhiu phng thc v property hu ch cho vic by li. Chng hn property Message cung cp thng tin ti sao n c nm. Message l thuc tnh ch c, n c thit t vo lc khi to bit l. Property HelpLink cung cp mt kt ni n tp tin gip . Property ny c th c v thit t. Property StackTrace ch c v c thit lp vo lc chy. Trong v d 11-6, property Exception.HelpLink c thit t v nhn v thng tin thm cho ngi dng v bit l DivideByZeroException. Property StackTrace c dng cung cp cc vt ca vng nh stack. N hin th hng lot cc phng thc gi dn n phng thc m bit l c nm ra. V d 11-6. Lm vic vi i tng Exception
using System; namespace Programming_CSharp { public class Test { public static void Main( ) { Test t = new Test( ); t.TestFunc( ); } 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 may 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

80

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

Console.WriteLine("Unknown exception caught"); } finally { Console.WriteLine ("Close file here."); } } public double DoDivide(double a, double b) { if (b == 0) { DivideByZeroException e = new DivideByZeroException(); e.HelpLink = "http://www.libertyassociates.com"; throw e; } if (a == 0) throw new ArithmeticException( ); return a / b; } } } Kt qu: Open file here DivideByZeroException! Msg: Attempted to divide by zero. HelpLink: http://www.libertyassociates.com Here's a stack trace: at Programming_CSharp.Test.DoDivide(Double a, Double b) in c:\...exception06.cs:line 56 at Programming_CSharp.Test.TestFunc( ) in...exception06.cs:line 22 Close file here.

Kt qu lit k cc phng thc theo trnh t ngc vi trnh t chng c gi. c kt qu trn nh sau: C mt bit l xy ra ti hm DoDivide(), hm DoDivide ny c gi bi hm TestFunc(). Trong v d ny ta to mt th hin ca DivideByZeroException
DivideByZeroException e = new DivideByZeroException();

Do khng truyn tham s, thng bo mc nh c dng:


DivideByZeroException! Msg: Attempted to divide by zero.

Ta c th thay thng bo mc nh ny bng cch truyn tham s khi khi to:


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

Trong trng hp ny kt qu s l:
DivideByZeroException! Msg:You tried to divide by zero which is not meaningful

Trc khi nm bit l ny, ta thit t thuc tnh HelpLink


e.HelpLink = "http://www.libertyassociates.com";

Khi bit l c bt, chng trnh in thng bo v c ng dn n kt ni gip


catch (System.DivideByZeroException e)

81

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

Console.WriteLine("\nDivideByZeroException! Msg: {0}", e.Message); Console.WriteLine("\nHelpLink: {0}", e.HelpLink);

Nh vy ta c th cung cp cc thng tin cn thit cho ngi dng. Sau l in


StackTrace
Console.WriteLine("\nHere's a stack trace:{0}", e.StackTrace);

Ta c kt qu cui cng.

11.3 Cc bit l t to
Vi cc bit l c th ty bin thng bo do CLR cung cp, thng cho hu ht cc ng dng. Tuy nhin s c lc ta mun thm nhiu dng thng tin hn cho i tng bit l, khi ta phi t to ly cc bit l mong mun. Bit l t to bt buc tha k t lp System.Exception. V d 11-7 m t cch to mt bit l mi. V d 11-7. T to bit l
using System; namespace Programming_CSharp { public class MyCustomException : System.ApplicationException { public MyCustomException(string message) : base(message) { } } public class Test { public static void Main( ) { Test t = new Test( ); t.TestFunc( ); } 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 may not print"); } catch (System.DivideByZeroException e) { Console.WriteLine("\nDivideByZeroException! Msg: {0}", e.Message); Console.WriteLine("\nHelpLink: {0}\n", e.HelpLink); } catch (MyCustomException e) { Console.WriteLine("\nMyCustomException! Msg: {0}", e.Message); Console.WriteLine("\nHelpLink: {0}\n", e.HelpLink);

82

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

} catch { Console.WriteLine("Unknown exception caught"); } finally { Console.WriteLine ("Close file here."); } } // do the division if legal public double DoDivide(double a, double b) { if (b == 0) { DivideByZeroException e = new DivideByZeroException(); e.HelpLink = "http://www.libertyassociates.com"; throw e; } if (a == 0) { MyCustomException e = new MyCustomException( "Can't have zero divisor"); e.HelpLink = "http://www.libertyassociates.com/NoZeroDivisor.htm"; throw e; } return a / b; } } }

MyCustomException tha k t System.ApplicationException v n

khng c g khc hn l mt hm dng nhn tham s l mt thng bo. Cu thng bo ny s c chuyn ti lp cha. Bit l MyCustomException c thit k cho chnh lp Test, khng cho php chia cho 0 v khng chia 0 cho s khc. S dng ArithmeticException cng cho kt qu tng t nhng c th gy nhm ln cho lp trnh vin khc do php chia 0 cho mt s khng phi l mt li ton hc.

11.4 Nm bit l ln na.


S c trng hp ta mun rng trong khi lnh catch ta s khi ng mt hnh ng sa li, v sau nm bit l cho khi try khc (khi try ca hm gi). Bit l ny c th cng loi hay khc loi vi bit l khi catch bt c. Nu l cng loi, khi catch s nm bit l ny mt ln na; cn nu khc loi, ta s nhng bit l c vo bit l mi khi try hm gi bit c lch s ca bit l. Property InnerException c dng thc hin vic ny. Bit l em nhng gi l bit l ni. Bi v InnerException cng chnh l mt bit l nn n cng c InnerException ca n. C nh vy to nn mt lot cc bit l.

83

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

V d 11-8. Nm bit l ln na v bit l ni (inner exception)


using System; namespace Programming_CSharp { 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(); } public void TestFunc() { try { DangerousFunc1(); } // khi bt c bit l t to // in lch s cc bit l 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( ); } // nu bt c mt bit l // nm mt bit l t to catch(System.Exception e) { MyCustomException ex = new MyCustomException( "E3 - Custom Exception Situation!",e); throw ex; } } public void DangerousFunc2( ) { try

84

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

} 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"); } } } Kt qu: E3 - Custom Exception Situation! Retrieving exception history... E2 - Func2 caught divide by zero E1 - DivideByZeroException

DangerousFunc3( ); } // nu bt c bit l DivideByZeroException thc hin // vi cng vic sa li v nm ra bit l tng qut catch (System.DivideByZeroException e) { Exception ex = new Exception( "E2 - Func2 caught divide by zero",e); throw ex; }

Ghi ch: Kt qu xut hin trn mn hnh khng th hin ht , cch tt nht l nn chy chng trnh ch tng dng lnh hiu r vn hn. Chng ta bt u bng li gi hm DangerousFunc1() trong khi try
try { DangerousFunc1( ); }

DangerousFunc1() gi DangerousFunc2(), DangerousFunc2() gi DangerousFunc3(), DangerousFunc3() gi DangerousFunc4(). Tt c cc li gi ny u c khi try ca ring n. Cui cng DangerousFunc4() nm mt bit l DivideByZeroException vi cu thng bo E1 - DivideByZero Exception.

85

Qun l li

Gvhd: Nguyn Tn Trn Minh Khang

Khi lnh catch trong hm DangerousFunc3() s bt bit l ny. Theo logic, tt c cc li ton hc u c bt bi bit l ArithmeticException (v vy c DivideByZeroException). N chng lm g, ch nm bit l ny ln na.
catch (System.ArithmeticException) { throw; }

C php trn nm cng mt loi bit l cho khi try bn ngoi (ch cn t kha
throw) DangerousFunc2() s bt c bit l ny, n s nm ra mt bit l mi thuc kiu Exception. Khi khi to bit l ny, ta truyn cho n hai tham s: thng bo E2 - Func2 caught divide by zero, v bit l c lm bit l ni. DangerousFunc1() bt bit l ny, lm vi cng vic no , sau to mt bit l c kiu MyCustomException. Tng t nh trn khi khi to bit l ta truyn cho n hai tham s: thng bo E3 - Custom Exception Situation!, v bit

l va bt c lm bit l ni. n thi im ny bit l c hai mc bit l ni. Cui cng, khi catch s bt bit l ny v in thng bo
E3 - Custom Exception Situation!

Sau s tip tc in cc thng bo ca cc bit l ni


while (inner != null) { Console.WriteLine("{0}",inner.Message); inner = inner.InnerException; }

V ta c kt qu
Retrieving exception history... E2 - Func2 caught divide by zero E1 - DivideByZero Exception

86

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

Chng 12 Delegate v Event


Delegate c ngha l y quyn hay y thc. Trong lp trnh i lc ta gp tnh hung phi thc thi mt hnh ng no , nhng li khng bit s gi phng thc no ca i tng no. Chng hn, mt nt nhn button khi c nhn phi thng bo cho i tng no bit, nhng i tng ny khng th c tin on trong lc ci t lp button. V vy ta s kt ni lp button vi mt i tng y thc v y thc (hay thng bo) cho i tng ny trch nhim thc thi khi button c nhn. i tng y thc s c gn (ng k y thc) vo thi im khc thch hp. Event c ngha l s kin. Ngy nay m hnh lp trnh giao din ngi dng ha (Graphical User Interface - GUI) i hi cch tip cn theo hng s kin. Mt ng dng ngy nay hin th giao din ngi dng v ch ngi dng thao tc. ng vi mi thao tc nh chn mt trnh n, nhn mt nt button, nhp liu vo textbox s mt s kin s pht sinh. Mt s kin c ngha l c iu g xy ra v chng trnh phi p tr. Delegate v event l hai khi nim c lin quan cht ch vi nhau. Bi v qun l cc s kin mt cch mm do i hi cc p tr phi c phn phi n cc trnh gii quyt s kin. Trnh gii quyt s kin trong C# c ci t bng delegate. Delegate cn c s dng nh mt hm callback. Hm callback l hm c th c t ng gi bi hm khc. Cng dng th hai ny ca delegate c cp trong chng 19.

12.1 Delegate (y thc, y quyn)


Trong C#, delegate c h tr hon ton bi ngn ng. V mt k thut, delegate thuc kiu tham chiu c dng ng gi phng thc xc nh kiu tr v v s lng, kiu tham s. Chng ta c th ng gi bt k phng thc thc no ph hp vi phng thc ca delegate. (Trong C++ c k thut tng t l con tr hm, tuy nhin delegate c tnh hng i tng v an ton v kiu) Mt delegate c th c to bng t kha delagate, sau l kiu tr v, tn delegate v cc tham s ca phng thc m delegate chp nhn:
public delegate int WhichIsFirst(object obj1, object obj2)

Dng trn khai bo mt delegate tn l WhichIsFirst c th ng gi (nhn) bt k mt phng thc no nhn vo hai tham s kiu object v tr v kiu int.

87

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

Khi mt delegate c nh ngha, ta c th ng gi mt phng thc vi delegate bng cch khi to vi tham s l phng thc cho delegate.

12.1.1 Dng delegate xc nh phng thc vo lc chy


Delegate c dng xc nh (specify) loi (hay kiu) ca cc phng thc dng qun l cc s kin; hoc ci t cc hm callback trong ng dng. Chng cng c dng xc nh cc phng thc tnh v khng tnh (cn gi l phng thc th hin - instance methods: l phng ch gi c thng qua mt th hin ca lp) cha bit trc vo lc thit k (c ngha l ch bit vo lc chy). V d, gi s chng ta mun to mt lp ti cha n gin c tn l Pair (mt cp). Lp ny cha 2 i tng c sp xp. Chng ta khng bit trc c i tng no s c truyn vo cho mt th hin ca lp Pair, v vy khng th xy dng hm sp xp tt cho tt c cc trng hp. Tuy nhin ta s y trch nhim ny cho i tng bng cch to phng thc m cng vic sp xp c th y thc. Nh ta c th sp th th ca cc i tng cha bit bng cch y thc trch nhim ny chnh phng thc ca chng. Ta nh ngha mt delegate c tn WhichIsFirst trong lp Pair. Phng thc sort s nhn mt tham s kiu WhichIsFirst. Khi lp Pair cn bit th t ca i tng bn trong, n s gi delegate vi hai i tng lm tham s. Trch nhim quyt nh xem i tng no trong 2 i tng c th t trc c y thc cho phng thc c ng gi trong delegate. kim th delegate, ta to ra hai lp: Dog v Student. Lp Dog v Student khng ging nhau ngoi tr c hai cng ci t phng thc c th c ng gi bi WhichIsFirst, v vy c Dog ln Student u thch hp c gi trong i tng Pair. kim th chng trnh chng ta to ra mt cp i tng Student v mt cp i tng Dog v lu tr chng trong hai i tng Pair. Ta s to mt i tng delegate ng gi cho tng phng thc, sau ta yu cu i tng Pair sp xp i tng Dog v Student. Sau y l cc bc thc hin:
public class Pair { // cp i tng public Pair(object firstObject, object secondObject) { thePair[0] = firstObject; thePair[1] = secondObject; } // bin lu gi hai i tng private object[]thePair = new object[2];

K tip, ta override hm ToString()


public override string ToString( ) { return thePair[0].ToString() + ", " + thePair[1].ToString();

88

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

Chng ta c hai i tng trong lp Pair v c th in chng ra. By gi l phn sp xp chng v in kt qu sp xp. Chng ta khng th bit trc s c loi i tng no, v v vy chng ta s y thc quyn quyt nh i tng no c th t trc cho chnh cc i tng. Nh vy ta s yu cu i tng c xp th t trong lp Pair phi ci t phng thc cho bit trong hai i tng, i tng no c th t trc. Phng thc ny s nhn vo hai i tng (thuc bt k loi no) v tr v kiu lit k: theFirstComeFirst nu i tng u c th t trc v theSecondComeFirst nu i tng sau c th t trc. Nhng phng thc ny s c ng gi bi delegate WhichIsFirst nh ngha trong lp Pair.
public delegate comparisn WhichIsFirst(object obj1,object obj2)

Tr tr v thuc kiu kiu lit k comparison.


public enum comparison { theFirstComesFirst = 1, theSecondComesFirst = 2 }

Bt k mt phng thc tnh no nhn hai tham s kiu object v tr v kiu comparison u c th c ng gi bi delegate ny vo lc chy. By gi ta nh ngha phng thc Sort ca lp Pair
public void Sort(WhichIsFirst theDelegatedFunc) { if ( theDelegatedFunc(thePair[0],thePair[1]) == comparison.theSecondComesFirst ) { object temp = thePair[0]; thePair[0] = thePair[1]; thePair[1] = temp; } }

Phng thc ny nhn mt tham s delegate tn WhichIsFirst. Phng thc Sort y thc quyn quyt nh i tng no c th t trc cho phng thc c ng gi trong delegate. Trong thn hm Sort(), c li gi phng thc c y thc v xc nh gi tr tr v. Nu tr tr v l theSecondComesFirst, hai i tng trong Pair s hon chuyn v tr, ngc li khng c g xy ra. Chng ta s xp xp cc sinh vin theo th t tn. Chng ta phi vit mt phng thc tr v theFirstComesFirst nu tn ca sinh vin u c th t trc v ngc li theSecondComesFirst nu tn sinh vin sau c th t trc. Nu hm tr v theSecondComesFirst ta s thc hin vic o v tr ca hai sinh vin trong Pair.

89

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

By gi thm phng thc ReverseSort, sp cc i tng theo th t ngc.


public void ReverseSort(WhichIsFirst theDelegatedFunc) { if ( theDelegatedFunc(thePair[0], thePair[1]) == comparison.theFirstComesFirst ) { object temp = thePair[0]; thePair[0] = thePair[1]; thePair[1] = temp; } }

By gi chng ta cn vi i tng sp xp. Ta s to hai lp Student v Dog. Gn tn cho Student lc khi to


public class Student { public Student(string name) { this.name = name; }

Lp Student yu cu hai phng thc, mt override t hm ToString() v mt ng gi nh phng thc c y thc.


Student phi override hm ToString() phng thc ToString() trong lp Pair gi. Hm ch n gin tr v tn ca sinh vin.
public override string ToString() { return name; }

Cng cn phi ci t phng thc Pair.Sort() c th y thc quyn quyt nh th t hai i tng.
return (String.Compare(s1.name, s2.name) < 0 ? comparison.theFirstComesFirst : comparison.theSecondComesFirst );

Hm String.Compare l phng thc ca lp String trong th vin .Net Framework. Hm so snh hai chui v tr v s nh hn 0 nu chui u nh hn v tr v s ln hn 0 nu ngc li. Ch rng hm tr v nu chui u nh hn, v tr v theFirstComesFirst theSecondComesFirst nu chui sau nh hn. Lp th hai l Dog. Cc i tng Dog s c sp xp theo trng lng, con nh s ng trc con nng. y l khai bo y lp Dog:
public class Dog { public Dog(int weight) { this.weight=weight; } // dogs are ordered by weight

90

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

public static comparison WhichDogComesFirst( Object o1, Object o2 ) { Dog d1 = (Dog) o1; Dog d2 = (Dog) o2; return d1.weight > d2.weight ? theSecondComesFirst : theFirstComesFirst; } public override string ToString( ) { return weight.ToString( ); } private int weight;

Ch rng lp Dog cng override phng thc ToString() v ci t phng thc tnh vi nguyn mu hm c khai bo trong delegate. Cng ch rng hai phng thc chun b y thc ca hai lp Dog v Student khng cn phi trng tn. V d 12 - 1 l chng tnh hon chnh. Chng trnh ny gii thch cch cc phng thc y thc c gi. V d 12 - 1. Lm vic vi delegate
using System; namespace Programming_CSharp { public enum comparison { theFirstComesFirst = 1, theSecondComesFirst = 2 } // ti cha n gin cha 2 i yng public class Pair { // khai bo delegate public delegate comparison WhichIsFirst( object obj1, object obj2 ); // hm khi to nhn 2 i tng // ghi nhn theo ng trnh t nhn vo public Pair( object firstObject, object secondObject) { thePair[0] = firstObject; thePair[1] = secondObject; } // phng thc sp th t (tng) hai i tng // theo th t do chnh chng qui nh. public void Sort(WhichIsFirst theDelegatedFunc) { if ( theDelegatedFunc(thePair[0],thePair[1]) == comparison.theSecondComesFirst ) { object temp = thePair[0]; thePair[0] = thePair[1]; thePair[1] = temp; } }

91

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

} public class Dog { public Dog(int weight) { this.weight=weight; } // ch c sp theo trng lng public static comparison WhichDogComesFirst( object o1, object o2) { Dog d1 = (Dog) o1; Dog d2 = (Dog) o2; return d1.weight > d2.weight ? comparison.theSecondComesFirst : comparison.theFirstComesFirst; } public override string ToString() { return weight.ToString(); } private int weight; } public class Student { public Student(string name) { this.name = name; } // sinh vin sp theo th t tn public static comparison WhichStudentComesFirst( object o1, object o2 ) { Student s1 = (Student) o1; Student s2 = (Student) o2; return (String.Compare(s1.name, s2.name) < 0 ? comparison.theFirstComesFirst :

// phng thc sp th t ngc (gim) cc i tng // theo th t do chnh chng qui nh. public void ReverseSort( WhichIsFirst theDelegatedFunc) { if (theDelegatedFunc(thePair[0],thePair[1]) == comparison.theFirstComesFirst ) { object temp = thePair[0]; thePair[0] = thePair[1]; thePair[1] = temp; } } // kt hp hai hm ToString() ca hai i tng public override string ToString( ) { return thePair[0].ToString( ) + ", " + thePair[1].ToString( ); } // mng gi hai i tng private object[] thePair = new object[2];

92

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

comparison.theSecondComesFirst); } public override string ToString( ) { return name; } private string name; } public class Test { public static void Main( ) { // to hai i tng sinh vin v hai i tng ch // y chng vo 2 i tng Pair Student Jesse = new Student("Jesse"); Student Stacey = new Student ("Stacey"); Dog Milo = new Dog(65); Dog Fred = new Dog(12); Pair studentPair = new Pair(Jesse,Stacey); Pair dogPair = new Pair(Milo, Fred); Console.WriteLine("studentPair\t\t\t: {0}", studentPair.ToString( )); Console.WriteLine("dogPair\t\t\t\t: {0}", dogPair.ToString( )); // to th hin ca delegate Pair.WhichIsFirst theStudentDelegate = new Pair.WhichIsFirst(Student.WhichStudentComesFirst); Pair.WhichIsFirst theDogDelegate = new Pair.WhichIsFirst(Dog.WhichDogComesFirst); // sp xp s dng delegate studentPair.Sort(theStudentDelegate); Console.WriteLine("After Sort studentPair\t\t: {0}", studentPair.ToString( )); studentPair.ReverseSort(theStudentDelegate); Console.WriteLine("After ReverseSort studentPair\t:{0}", studentPair.ToString( )); dogPair.Sort(theDogDelegate); Console.WriteLine("After Sort dogPair\t\t: {0}", dogPair.ToString( )); dogPair.ReverseSort(theDogDelegate); Console.WriteLine("After ReverseSort dogPair\t: {0}", dogPair.ToString( )); } } Kt qu: studentPair : Jesse, Stacey dogPair : 65, 12 After Sort studentPair : Jesse, Stacey After ReverseSort studentPair : Stacey, Jesse After Sort dogPair : 12, 65 After ReverseSort dogPair : 65, 12 }

93

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

Chng trnh test to ra hai i tng Student v hai i tng Dog, sau a chng vo ti cha Pair. Hm khi to ca Student nhn vo tn sinh vin c hm khi to Dog nhn vo trng lng ca ch.
Student Jesse = new Student("Jesse"); Student Stacey = new Student ("Stacey"); Dog Milo = new Dog(65); Dog Fred = new Dog(12); Pair studentPair = new Pair(Jesse,Stacey); Pair dogPair = new Pair(Milo, Fred); Console.WriteLine("studentPair\t\t\t:{0}",studentPair.ToString()); Console.WriteLine("dogPair\t\t\t\t: {0}", dogPair.ToString( ));

Sau in ni dung ca hai ti cha Pair xem th t ca chng. Kt qu nh sau:


studentPair : Jesse, Stacey dogPair : 65, 12

Nh mong i th t ca cc i tng l th t chng c thm vo ti cha Pair. K tip chng ta khi to hai i tng delegate
Pair.WhichIsFirst theStudentDelegate = new Pair.WhichIsFirst( Student.WhichStudentComesFirst ); Pair.WhichIsFirst theDogDelegate = new Pair.WhichIsFirst( Dog.WhichDogComesFirst );

delegate th nht, theStudentDelegate, c to bng cch truyn phng thc tnh thch hp t lp Student. delegate th hai, theDogDelegate c truyn phng thc tnh ca lp Dog. Cc delegate by gi c th c truyn cho cc phng thc. Ta truyn delegate th nht cho phng thc Sort() ca i tng Pair, v sau l phng thc ReverseSort. Kt qu c in trn mn hnh Console nh sau.
After After After After Sort studentPair : Jesse, Stacey ReverseSort studentPair : Stacey, Jesse Sort dogPair : 12, 65 ReverseSort dogPair : 65, 12

12.1.2 Delegate tnh


im bt li ca v d 12-1 l n buc lp gi, trong trng hp ny l lp Test, phi khi to cc delegate n cn sp th t cc i tng trong mt cp. S tt hn nu nh c th ly cc delegate t lp Dog v Student. Chng ta c th lm iu ny bng cch to cho trong mi lp mt delegate tnh. i vi lp Student ta thm nh sau:
public static readonly Pair.WhichIsFirst OrderStudents = new Pair.WhichIsFirst(Student.WhichStudentComesFirst);

Dng lnh ny to mt delegate tnh, ch c c tn l OrderStudent Ta c th to tng t cho lp Dog


public static readonly Pair.WhichIsFirst OrderDogs = new Pair.WhichIsFirst(Dog. WhichDogComesFirst);

94

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

Nh vy mi lp c mt delegate ring, khi cn ta ly cc delegate ny v truyn nh tham s.


studentPair.Sort(theStudentDelegate); Console.WriteLine("After Sort studentPair\t\t: {0}", studentPair.ToString( )); studentPair.ReverseSort(Student.OrderStudents); Console.WriteLine("After ReverseSort studentPair\t: {0}", studentPair.ToString( )); dogPair.Sort(Dog.OrderDogs); Console.WriteLine("After Sort dogPair\t\t: {0}", dogPair.ToString( )); dogPair.ReverseSort(Dog.OrderDogs); Console.WriteLine("After ReverseSort dogPair.ToString( ));

Kt qu hon ton nh v d trn.

12.1.3 Delegate nh Property


Mt vn vi delagate tnh l n phi c khi to trc, cho d c c dng hay khng. Ta c th ci tin bng cch thay i bin thnh vin tnh thnh property i vi lp Student, ta b khai bo sau:
public static readonly Pair.WhichIsFirst OrderStudents = new Pair.WhichIsFirst(Student.WhichStudentComesFirst);

v thay th bng
public static Pair.WhichIsFirst OrderStudents { get{ return new Pair.WhichIsFirst(WhichStudentComesFirst); } }

Tng t thay th cho lp Dog


public static Pair.WhichIsFirst OrderDogs { get{ return new Pair.WhichIsFirst(WhichDogComesFirst);} }

Khi property OrderStudent c truy cp, delegate s c to:


return new Pair.WhichIsFirst(WhichStudentComesFirst);

Khc bit chnh y l delegate s ch c khi to khi c yu cu.

12.1.4 Th t thc thi vi mng cc cc delegate


Delegate c th gip ta xy dng mt h thng cho php ngi dng c th quyt nh mt cch ng trnh t thc thi cc thao tc. Gi s chng ta c h thng s l nh, h thng ny c th thao tc nh theo nhiu cch nh: lm m (blur) nh, lm sc nt, quay, lc v.vnh. Cng gi s rng trnh t p dng cc hiu ng trn nh hng ln n n cht lng ca nh. Ngi dng s mong mun chn cc hiu ng h ln trnh t ca chng t mt thc n, sau h thng s thc hin cc hiu ng ny theo trnh t h nh.

95

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

Ta c th to mt delegate cho mi thao tc (hiu ng) v y chng vo mt ti cha c th t, nh mt mng chng hn, theo ng trnh t n s c thc thi. Khi tt c cc delegate c to v thm vo ti cha, ta ch n gin duyt sut mng, gi cc delegate khi ti lt. Ta bt u to lp Image i din cho mt bc nh s c x l bi ImageProcessor:
public class Image { public Image( ) { Console.WriteLine("An image created"); } }

Lp ImageProcessor khai bo mt delegate khng tham s v tr v kiu


void
public delegate void DoEffect( );

Sau khai bo mt s phng thc thao tc nh c nguyn mu hm nh delegate khai bo trn.


public static void Blur( ) { Console.WriteLine("Blurring image"); } public static void Filter( ) { Console.WriteLine("Filtering image"); } public static void Sharpen( ) { Console.WriteLine("Sharpening image"); } public static void Rotate( ) { Console.WriteLine("Rotating image"); }

Lp ImageProccessor cn mt mng gi cc delegate ngi dng chn; mt bin gi s lng hiu ng mun x l v hin nhin mt bc nh image
DoEffect[] arrayOfEffects; Image image; int numEffectsRegistered = 0;

ImageProccessor cng cn mt phng thc thm delegate vo mng


public void AddToEffects(DoEffect theEffect) { if (numEffectsRegistered >= 10) { throw new Exception("Too many members in array"); } arrayOfEffects[numEffectsRegistered++] = theEffect; }

96

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

Mt phng thc gi thc thi cc hiu ng


public void ProcessImages( ) { for (int i = 0;i < numEffectsRegistered;i++) { arrayOfEffects[i]( ); } }

Cui cng ta khai bo cc delegate tnh client c th gi.


public public public public DoEffect DoEffect DoEffect DoEffect BlurEffect = new DoEffect(Blur); SharpenEffect = new DoEffect(Sharpen); FilterEffect = new DoEffect(Filter); RotateEffect = new DoEffect(Rotate);

Client s c cc on m tng tc vi ngi dng, nhng chng ta s lm l chuyn ny, mc nh cc hiu ng, thm chng vo mng v sau gi ProcessImage

V d 12-2. S dng mng cc deleage


using System; namespace Programming_CSharp { // nh ta s thao tc public class Image { public Image( ) { Console.WriteLine("An image created"); } } public class ImageProcessor { // khai bo delegate public delegate void DoEffect( ); // to cc delegate tnh gn vi cc phng thc thnh vin public DoEffect BlurEffect = new DoEffect(Blur); public DoEffect SharpenEffect = new DoEffect(Sharpen); public DoEffect FilterEffect = new DoEffect(Filter); public DoEffect RotateEffect = new DoEffect(Rotate); // hm dng khi to ng v mng public ImageProcessor(Image image) { this.image = image; arrayOfEffects = new DoEffect[10]; } public void AddToEffects(DoEffect theEffect) { if (numEffectsRegistered >= 10) { throw new Exception( "Too many members in array" ); } arrayOfEffects[numEffectsRegistered++] = theEffect; } // cc hiu ng nh public static void Blur( )

97

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

{ } {

Console.WriteLine("Blurring image"); public static void Filter( )

} // lp kim th public class Test { public static void Main( ) { Image theImage = new Image( ); // khng giao din lm n gin vn ImageProcessor theProc = new ImageProcessor(theImage); theProc.AddToEffects(theProc.BlurEffect); theProc.AddToEffects(theProc.FilterEffect); theProc.AddToEffects(theProc.RotateEffect); theProc.AddToEffects(theProc.SharpenEffect); theProc.ProcessImages( ); } } } Kt qu: An image created Blurring image Filtering image Rotating image Sharpening image

Console.WriteLine("Filtering image"); } public static void Sharpen( ) { Console.WriteLine("Sharpening image"); } public static void Rotate( ) { Console.WriteLine("Rotating image"); } public void ProcessImages( ) { for (int i = 0;i < numEffectsRegistered;i++) { arrayOfEffects[i]( ); } } // cc bin thnh vin private DoEffect[] arrayOfEffects; private Image image; private int numEffectsRegistered = 0;

Trong lp Test, ImageProcessor c khi to v cc hiu ng c thm vo. Nu ngi dng chn lm m nh (blur) trc khi lc nh (filter), ch cn n gin thay i th t ca chng trong mng Tng t, bt k mt hiu ng no cng c th c lp li bng cch thm vo ti cha delegate nhiu ln.

98

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

12.1.5 Multicasting
Multicasting l cch gi hai phng thc thng qua mt delegate n.

iu ny s tr nn quan trng khi qun l cc s kin. Mc tiu chnh l c mt delegate n c th gi nhiu phng thc cng mt lc. N khc vi mng cc delagte, trong mng delegate mi delegate ch gi mt phng thc. V d trc dng mt mng lm ti cha nhiu delegate khc nhau. Vi multicasting ta c th to mt delegate n ng gi nhiu phng thc. V d khi mt button c nhn, ta hn mun thao tc nhiu hnh ng cng mt lc. Ta c th ci t iu ny bng cch cho mi button mt mng cc delegate, nhng s d hn v r ngha hn khi to mt multicasting delegate. Bt k mt delegate no tr v void u l multicast delegate, mc d ta c th i x n nh single cast delegate (l delegate cp phn trn) nu mun. Hai multicast delegate c th kt ni vi nhau bng ton t cng (+). Kt qu l mt multicast delegate mi ng gi tt c cc phng thc ca hai delegate ton hng. V d, gi s Writer v Logger l cc delegate tr v kiu void, dng lnh sau s kt ni chng v to ra mt multicast delegate mi c tn l myMulticastDelegate
myMulticastDelegate = Writer + Logger;

Ta cng c th thm mt delegate vo mt multicast delegate bng ton t cng bng (+=). Gi s ta c Transmitter v myMulticastDelegate l cc delegate, dng lnh sau:
myMulticastDelegate += Transmitter;

tng t nh dng:
myMulticastDelegate = myMulticastDelegate + Transmitter;

xem cch multicast delegate c to v s dng, xem qua ton b v d 12-3. Trong v d ny ta to mt lp tn l MyClassWithDelegate, lp ny nh ngha mt delegate nhn mt tham s kiu chui v tr v kiu void.
public delegate void StringDelegate(string s);

Sau ta nh ngha mt lp tn l MyImplementingClass c ba phng thc, t c u tr v void v nhn mt tham s kiu chui: WriteString, LogString v TransmitString. Phng thc u vit mt chui ra mn hnh (u ra chun), phng thc th hai vit ra tp tin li (log file) v phng thc th ba chuyn chui ln Internet. Ta to cc delegate gi cc phng thc thch hp.
Writer("String passed to Writer\n"); Logger("String passed to Logger\n"); Transmitter("String passed to Transmitter\n");

xem cch kt hp cc delegate ta to ra mt delegate khc


MyClassWithDelegate.StringDelegate myMulticastDelegate;

99

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

v gn n bng kt qu ca php cng hai delegate tn ti


myMulticastDelegate = Writer + Logger;

Ta cng c th thm bng ton t cng bng


myMulticastDelegate += Transmitter;

Cui cng ta c th b mt delegate bng ton t tr bng (-=)


DelegateCollector -= Logger;

V d 12-3. Kt hp cc delegate
using System; namespace Programming_CSharp { public class MyClassWithDelegate { // khai bo delegate public delegate void StringDelegate(string s); } public class MyImplementingClass { public static void WriteString(string s) { Console.WriteLine("Writing string {0}", s); } public static void LogString(string s) { Console.WriteLine("Logging string {0}", s); } public static void TransmitString(string s) { Console.WriteLine("Transmitting string {0}", s); } } public class Test { public static void Main( ) { // nh ngha ba i tng StringDelegate MyClassWithDelegate.StringDelegate Writer,Logger,Transmitter; // nh ngha mt SringDelegate khc // hnh ng nh mt multicast delegate MyClassWithDelegate.StringDelegate myMulticastDelegate; // khi to 3 delegate u tin, // truyn vo cc phng thc nh ng gi Writer = new MyClassWithDelegate.StringDelegate( MyImplementingClass.WriteString); Logger = new MyClassWithDelegate.StringDelegate( MyImplementingClass.LogString); Transmitter = new MyClassWithDelegate.StringDelegate( MyImplementingClass.TransmitString); // gi phng thc ca delegate Writer Writer("String passed to Writer\n"); // gi phng thc ca delegate Logger Logger("String passed to Logger\n"); // gi phng thc ca delegate Transmitter Transmitter("String passed to Transmitter\n"); // thng bo kt ni hai deleagte

100

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

// thnh mt multicast deleagte Console.WriteLine("myMulticastDelegate = Writer + Logger"); // kt ni hai deleagte // thnh mt multicast deleagte myMulticastDelegate = Writer + Logger; // gi delegated, hai phng thc c gi myMulticastDelegate("First string passed to Collector"); // thng bo thm deleagte th ba // vo mt multicast deleagte Console.WriteLine("\nmyMulticastDelegate += Transmitter"); // thm delegate th ba myMulticastDelegate += Transmitter; // gi delegate, ba phng thc c gi myMulticastDelegate("Second string passed to Collector"); // thng bo loi b delegate logger Console.WriteLine("\nmyMulticastDelegate -= Logger"); // b delegate logger myMulticastDelegate -= Logger; // gi delegate, hai phng htc cn li c gi myMulticastDelegate("Third string passed to Collector"); } } } Kt qu: Writing string String passed to Writer Logging string String passed to Logger Transmitting string String passed to Transmitter myMulticastDelegate = Writer + Logger Writing string First string passed to Collector Logging string First string passed to Collector myMulticastDelegate += Transmitter Writing string Second string passed to Collector Logging string Second string passed to Collector Transmitting string Second string passed to Collector myMulticastDelegate -= Logger Writing string Third string passed to Collector Transmitting string Third string passed to Collector

Sc mnh ca multicast delegate s d hiu hn trong khi nim event.

12.2 Event (S kin)


Giao din ngi dng ha (Graphic user inteface - GUI), Windows v cc trnh duyt yu cu cc chng trnh p ng cc s kin. Mt s kin c th l mt button c nhn, mt nc thc n c chn, mt tp tin chuyn giao hon tt v.v. Ni ngn gn, l mt vic g xy ra v ta phi p tr li. Ta khng th tin on trc trnh t cc s kin s pht sinh. H thng s im lm cho n khi mt s kin xy ra, khi n s thc thi cc hnh ng p tr kin ny. Trong mi trng GUI, c rt nhiu iu khin (control, widget) c th pht sinh s kin V d, khi ta nhn mt button, n s pht sinh s kin Click. Khi ta thm vo mt drop-down list n s pht sinh s kin ListChanged.

101

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

Cc lp khc s quan tm n vic p tr cc s kin ny. Cch chng p tr nh th no khng c quan tm n (hay khng th) lp pht sinh s kin. Nt button s ni "Ti c nhn" v cc lp khc p tr ph hp.

12.2.1 Publishing v Subcribing


Trong C#, bt k mt lp no cng c th pht sinh (publish) mt tp cc s kin m cc lp khc s bt ly (subscribe). Khi mt lp pht ra mt s kin, tt c cc lp subscribe u c thng bo. Vi k thut ny, i tng ca ta c th ni "y l cc vn m ti c th thng bo cho anh bit" v cc lp khc s ni "Vng, hy bo cho ti khi n xy ra". V d nh, mt button s thng bo cho bt k cc lp no quan tm khi n c nhn. Button c gi l publisher bi v button publish s kin Click v cc lp khc s gi l subscribers bi v chng subscribe s kin Click

12.2.2 Event v Delegate


Event trong C# c ci t bng delegate. Lp publish nh ngha mt deleagte m cc lp subscribe phi ci t. Khi mt s kin pht sinh, phng thc ca lp subscribe s c gi thng qua delegate.

Cch qun l cc s kin c gi l event handler (trnh gii quyt s kin). Ta c th khai bo mt event handler nh l ta lm vi delegate. thun tin, event handler trong .NET Framework tr v kiu void v nhn vo 2 tham s. Tham s th nht cho bit ngun ca s kin; c ngha l i tng publish. Tham s th hai l mt i tng tha k t lp EventArgs. C li khuyn rng ta nn thit k theo mu c qui nh ny.
EventArgs l lp c s cho tt c cc d liu v s kin. Ngoi tr hm khi to, lp EventArgs tha k hu ht cc phng thc ca lp Object, mc d n cng c thm vo mt bin thnh vin empty i din cho mt s kin khng c trng thi ( cho php s dng c hiu qu hn cc s kin khng c trng thi). Cc lp con tha k t EventArgs cha cc thng tin v s kin. Events are properties of the class publishing the event. The keyword event controls how the event property is accessed by the subscribing classes. The event keyword is designed to maintain the publish/subscribe idiom.

Gi s ta mun to mt lp ng h (Clock) s dng event thng bo cc lp subscribe bit khi no thi gian thay i (theo n v giy). Gi s kin ny l OnSecondChange. Ta khai bo s kin v event handler theo c php sau y:
[attributes] [modifiers] event type member-name

V d nh:

102

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

public event SecondChangeHandler OnSecondChange;

V d ny khng c attribute (attribute s c cp trong chng 18). "modifier" c th l abstract, new, override, static, virtual hoc l mt trong bn acess modifier, trong trng hp ny l public T kha event theo sau modifier
type l kiu delegate lin kt vi event, trong trng hp ny l SecondChangeHandler member name l tn ca event, trong trng hp ny l OnSecondChange. Thng thng n c bt u bng t On (khng bt buc)

Tm li dng lnh ny khai bo mt event tn l OnSecondChange, ci t mt delegate c kiu l SecondChangeHandler. Khai bo ca SecondChangeHandler l
public delegate void SecondChangeHandler( object clock, TimeInfoEventArgs timeInformation );

Nh cp, cho thun tin mt event handler phi tr v kiu void v nhn vo hai tham s: ngun pht sinh s kin (trng hp ny l clock) v mt i tng tha k t lp EventArgs, trong trng hp ny l TimeInfoEventArgs. TimeInfoEventArgs c khai bo nh sau:
public class TimeInfoEventArgs : EventArgs { public TimeInfoEventArgs(int hour, int minute, int second) { this.hour = hour; this.minute = minute; this.second = second; } public readonly int hour; public readonly int minute; public readonly int second; }

Mt i tng TimeInfoEventArgs s c cc thng tin v gi, pht, giy hin hnh. N nh ngha mt hm dng v ba bin thnh vin kiu s nguyn (int), public v ch c. Lp Clock c ba bin thnh vin hour, minute v second v ch duy nht mt phng thc Run():
public void Run( ) { for(;;) { // ng 10 milli giy Thread.Sleep(10); // ly gi hin hnh System.DateTime dt = System.DateTime.Now; // nu bin giy thay i

103

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

// thng bo cho subscriber if (dt.Second != second) { // to i tng TimeInfoEventArgs // truyn cho subscriber TimeInfoEventArgs timeInformation = new TimeInfoEventArgs(dt.Hour,dt.Minute,dt.Second); // nu c subscribed, thng bo cho chng if (OnSecondChange != null) { OnSecondChange(this,timeInformation); } } // cp nht trng thi this.second = dt.Second; this.minute = dt.Minute; this.hour = dt.Hour; } }

Hm Run c vng lp for v tn lun lun kim tra gi h thng. Nu thi gian thay i n s thng bo n tt c cc subscriber. u tin l ng trong 10 mili giy
Thread.Sleep(10);

Sleep l phng thc tnh ca lp Thread, thuc v vng tn System.Threading. Li gi Sleep nhm ngn vng lp khng s dng ht ti

nguyn CPU ca h thng. Sau khi ng 10 mili giy, kim tra gi hin hnh
System.DateTime dt = System.DateTime.Now;

Khong sau 100 ln kim tra , gi tr giy s tng. Phng thc s thng bo thay i ny cho cc subscriber. thc hin iu ny, u tin to mt i tng TimeInfoEventArgs mi.
if (dt.Second != second) { TimeInfoEventArgs timeInformation = new TimeInfoEventArgs(dt.Hour,dt.Minute,dt.Second);

Sau thng bo cho cc subscriber bng cch pht ra s kin


OnSecondChange
if (OnSecondChange != null) { OnSecondChange(this,timeInformation); }

Nu khng c subsrciber no ng k, OnSecondChange c tr null, kim tra iu ny trc khi gi. Nh rng OnSecondChange nhn 2 tham s: ngun pht sinh s kin v i tng tha k t lp EventArgs. Quan st k ta thy phng thc dng t kha this lm tham s bi chnh clock l ngun pht sinh s kin.

104

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

Pht sinh mt s kin s gi tt c cc phng thc ng k vi Clock thng qua deleagte. Chng ta xem xt vn ny ngay by gi. Mi ln s kin pht sinh, ta cp nht trng thi ca lp Clock:
this.second = dt.Second; this.minute = dt.Minute; this.hour = dt.Hour;

Vn cn li l to lp subcriber. Ta s to ra 2 lp. Lp th nht l DisplayClock. Lp ny hin th thi gian ra mn hnh Console. V d ny n gin to ra 2 phng thc, phng thc th nht l Subscribe c nhim v subscribe s kin OnSecondChange. Phng thc th hai l mt event handler tn TimeHasChanged
public class DisplayClock { public void Subscribe(Clock theClock) { theClock.OnSecondChange += new Clock.SecondChangeHandler(TimeHasChanged); } public void TimeHasChanged( object theClock, TimeInfoEventArgs ti) { Console.WriteLine("Current Time: {0}:{1}:{2}", ti.hour.ToString( ), ti.minute.ToString( ), ti.second.ToString( )); } }

Khi phng thc u, Subscribe, c gi, n to mt delegate SecondChangeHandler truyn cho phng thc TimeHasChanged. Vic ny ng k delegate cho s kin OnSecondChange ca Clock Ta s to lp th hai, lp ny cng s p ng s kin, tn l LogCurrentTime. Lp ny ch n gin ghi li thi gian vo mt tp tin, nhng n gin lp ny cng xut ra mn hnh console.
public class LogCurrentTime { public void Subscribe(Clock theClock) { theClock.OnSecondChange += new Clock.SecondChangeHandler(WriteLogEntry); } // phng thc s ghi ln tp tin // nhng n gin ta cng ghi ra console public void WriteLogEntry( object theClock, TimeInfoEventArgs ti) { Console.WriteLine("Logging to file: {0}:{1}:{2}", ti.hour.ToString( ), ti.minute.ToString( ), ti.second.ToString( ));

105

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

Mc d trong v d ny hai lp tng t nh nhau, nhng bt k lp no cng c th subscribe mt event. Ch rng event c thm vo bng ton t +=. iu ny cho php cc s kin mi c thm vo s kin OnSecondChange ca i tng Clock m khng lm hng i cc s kin ng k trc . Khi LogCurrentTime subscribe vo s kin OnSecondChanged, ta khng cn quan tm rng DisplayClock subscribe hay cha. V d 12-4. Lm vic vi event
using System; using System.Threading; namespace Programming_CSharp { // lp gi thng tin v mt s kin // trong trng hp ny l thng tin v ng h // nhng tt hn l phi c thm thng tin trng thi public class TimeInfoEventArgs : EventArgs { public TimeInfoEventArgs(int hour, int minute, int second) { this.hour = hour; this.minute = minute; this.second = second; } public readonly int hour; public readonly int minute; public readonly int second; } // lp chnh ca ta. public class Clock { // delegate m subscribers phi ci t public delegate void SecondChangeHandler( object clock, TimeInfoEventArgs timeInformation); // s kin publish public event SecondChangeHandler OnSecondChange; // vn hnh ng h // hm s pht sinh s kin sau mi giy public void Run( ) { for(;;) { // ng 10 milli giy Thread.Sleep(10); // ly gi hin ti System.DateTime dt = System.DateTime.Now; // nu thi gian thay i // thng bo cho cc subscriber if (dt.Second != second) {

106

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

// to i tng TimeInfoEventArgs // truyn cho subscriber TimeInfoEventArgs timeInformation=new TimeInfoEventArgs( dt.Hour,dt.Minute,dt.Second); // nu c subscriber, thng bo cho chng if (OnSecondChange != null) { OnSecondChange( this,timeInformation ); } } // cp nht this.second this.minute this.hour = trng thi = dt.Second; = dt.Minute; dt.Hour;

} public class DisplayClock { // subscribe s kin SecondChangeHandler ca theClock public void Subscribe(Clock theClock) { theClock.OnSecondChange += new Clock.SecondChangeHandler(TimeHasChanged); } // phng thc ci t hm delegated public void TimeHasChanged( object theClock, ` TimeInfoEventArgs ti) { Console.WriteLine("Current Time: {0}:{1}:{2}", ti.hour.ToString( ), ti.minute.ToString( ), ti.second.ToString( )); } } public class LogCurrentTime { public void Subscribe(Clock theClock) { theClock.OnSecondChange += new Clock.SecondChangeHandler(WriteLogEntry); } // phng thc ny nn vit ln tp tin // nhng n gin ta xut ra mn hnh console public void WriteLogEntry(object theClock,TimeInfoEventArgs ti) { Console.WriteLine("Logging to file: {0}:{1}:{2}", ti.hour.ToString( ), ti.minute.ToString( ), ti.second.ToString( )); } } public class Test {

} } private int hour; private int minute; private int second;

107

Delegate v Event

Gvhd: Nguyn Tn Trn Minh Khang

public static void Main( ) { // to ng h mi Clock theClock = new Clock( ); // to mt displayClock // subscribe vi clock va to DisplayClock dc = new DisplayClock( ); dc.Subscribe(theClock); // to i tng Log // subscribe vi clock va to LogCurrentTime lct = new LogCurrentTime( ); lct.Subscribe(theClock); // bt u chy theClock.Run( ); } } } Kt qu: Current Time: 14:53:56 Logging to file: 14:53:56 Current Time: 14:53:57 Logging to file: 14:53:57 Current Time: 14:53:58 Logging to file: 14:53:58 Current Time: 14:53:59 Logging to file: 14:53:59 Current Time: 14:54:0 Logging to file: 14:54:0

12.2.3 Tch ri Publisher khi Subsciber


Lp Clock ch nn n gin in thi gian hn l phi pht sinh s kin, vy ti sao phi b lm phin bng vic s dng gin tip delegate? Thun li ca tng publish/subscribe l bt k lp no (bao nhiu cng c) cng c th c thng bo khi mt s kin pht sinh. Lp subscribe khng cn phi bit cch lm vic ca Clock, v Clock cng khng cn bit chuyn s xy ra khi mt s kin c p tr. Tng t mt button c th pht ra s kin OnClick v bt k lp no cng c th subscribe s kin ny, nhn v thng bo khi no button b nhn.
Publisher v Subscriber c tch bit nh delegate. iu ny c mong ch nht v n lm cho m ngun c mm do (flexible) v d hiu. Lp Clock

c th thay i cch n xc nh thi gian m khng nh hng ti cc lp subscriber. Tng t cc lp subscriber cng c th thay i cch chng p tr s kin m khng nh hng ti lp Clock. Hai lp ny hon ton c lp vi nhau, v n gip cho m ngun d bo tr hn.

108

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Chng 13 Lp trnh vi C#
Phn ny s gii thiu chi tit v cch vit cc chng trnh .NET, bao gm Windows Forms v Web Forms. Ngoi ra, chng ta s kho st thm v cch tng tc vi c s d liu (Database) v cc dch v Web (Web Services). Quan im v kin trc .NET l to s d dng, thun tin khi pht trin cc phn mm theo tnh hng i tng. Vi mc ch ny, tng trn cng ca kin trc .NET c thit k bao gm hai phn: ASP.NET v Windows Form. ASP.NET c dng cho hai mc ch chnh: hoc to cc ng dng Web vi Web Forms hoc to cc i tng Web (Web Objects) khng c giao din ngi dng (User Interface: UI) vi Web Services. Ta s kho st chi tit cc mc chnh sau : 1. Cch to ra cc ng dng Windows c tnh chuyn nghip cao trong mi trng pht trin Windows Form mt cch nhanh chng theo m hnh RAD ( Rapid Application Development ). 2. c th truy cp d liu trong cc h qun tr d liu, ta s tho lun chi tit v ADO.NET v cch tng tc vi Microsoft SQL Server v cc trnh cung cp d liu (Providers Data ) khc. 3. L s kt hp cng ngh RAD trong phn (1) v ADO.NET trong phn (2) minh ha vic to ra cc ng dng Web vi Web Forms. 4. Khng phi tt c mi ng dng u c giao din ngi dng thn thin. Web Services gip to cc ng dng nh vy, chng l nhng ng dng c tnh phn phi, cung cp cc chc nng da trn cc nghi thc Web chun, thng dng nht l XML v HTTP.

13.1 ng dng Windows vi Windows Form


Trc tin, chng ta cn phn bit s khc nhau gia hai kiu ng dng: Windows v Web. Khi cc ng dng Web u tin c to ra, ngi ta phn bit hai loi ng dng trn nh sau : ng dng Windows chy trn Desktop hay trn mt mng cc b LAN (Local-Area Network), cn ng dng Web th c chy trn Server xa v c truy cp bng trnh duyt Web (web browser). S phn bit ny khng cn r rng na v cc ng dng Windows hin nay c xu hng dng cc dch v ca Web. V d nh phn mm Outlook chuyn nhn th thng qua kt ni Web. Theo quan im ca Jesse Liberty, tc gi ca cun sch Programming C#, xut bn vo thng 7 nm 2001. ng cho rng im phn bit ch yu gia ng dng Windows v Web l ch : Ci g s hu UI ?, ng dng dng trnh duyt hin

109

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

th hay UI ca ng dng c xy dng thnh chng trnh c th chy trn Desktop. C mt s thun li i vi cc ng dng Web, ng dng c th c truy cp bi bt k trnh duyt no kt ni n Server, vic hiu chnh c thc hin trn Server, khng cn phi phn phi th vin lin kt ng (Dynamic Link Libraries DLLs) mi cn chy ng dng cho ngi dng. .NET cng c s phn bit ny, in hnh l c nhng b cng c thch hp cho tng loi ng dng: Windows hay Web. C hai loi ny u da trn khun mu Form v s dng cc iu khin (Control) nh l Buttons, ListBox, Text B cng c dng to ng dng Web c gi l Web-Form, c tho lun trong mc (3). Cn b cng c dng to ng dng Windows c gi l Windows-Form, s c tho lun ngay trong mc ny. Ch : Theo tc gi JesseLiberty, ng cho rng hin nay ng dng kiu Windows v Web c nhiu im ging nhau, v ng cho rng .NET nn gp li thnh mt b cng c chung cho c ng dng Windows v Web trong phin bn ti. Trong cc trang k, chng ta s hc cch to mt Windows Form n gin bng cch dng trnh son m hoc cng c thit k (Design Tool) trong Visual Studio .NET. K tip ta s kho st mt ng dng Windows khc phc tp hn, ta s hc cc dng b cng c ko th ca Visual Studio .NET v mt s k thut lp trnh C# m ta tho lun trong phn trc.

13.1.1 To mt Windows Form n gin


Windows Form l cng c dng to cc ng dng Windows, n mn cc u im mnh ca ngn ng Visual Basic : d s dng, h tr m hnh RAD ng thi kt hp vi tnh linh ng, hng i tng ca ngn ng C#. Vic to ng dng Windows tr ln hp dn v quen thuc vi cc lp trnh vin. Trong phn ny, ta s tho lun hai cch khi to mt ng dng Windows : Dng b son m g m trc tip hoc dng b cng c ko th ca IDE. ng dng ca chng ta khi chy s xut dng ch Hello World! ra mn hnh, khi ngi dng nhn vo Button Cancel th ng dng s kt thc.

13.1.1.1 Dng b son m ( Nodepad )


Mc d Visual Studio .NET cung cp mt b cc cng c phc v cho vic ko th, gip to cc ng dng Windows mt cc nhanh chng v hiu qu, nhng trong phn ny ta ch cn dng b son m.

110

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 13-1 ng dng minh ha vic hin th chui v bt s kin ca Button.

u tin, ta dng lnh using thm vng tn sau :


using System.Windows.Forms;

Ta s cho ng dng ca ta tha k t vng tn Form :


public class HandDrawnClass : Form

Bt k mt ng dng Windows Form no cng u tha k t i tng Form, ta c th dng i tng ny to ra cc ca s chun nh : cc ca s tri (floating form), thanh cng c (tools), hp thoi (dialog box) Mi iu khin trong b cng c ca Windows Form (Label, Button, Listbox ) u thuc vng tn ny. Ta s khai bo 2 i tng, mt Label gi chui Hello World ! v mt Button bt s kin kt thc ng dng.
private System.Windows.Forms.Label lblOutput; private System.Windows.Forms.Button btnCancel;

Tip theo ta s khi to 2 i tng trn trong hm khi to ca Form:


this.lblOutput = new System.Windows.Forms.Label( ); this.btnCancel = new System.Windows.Forms.Button( );

Sau ta gn chui tiu cho Form ca ta l Hello World :


this.Text = "Hello World";

Ch :Do cc lnh trn c t trong hm khi to ca Form HandDrawClass, v th t kha this s tham chiu ti chnh n. Gn v tr, chui v kch thc cho i tng Label :
lblOutput.Location = new System.Drawing.Point (16, 24); lblOutput.Text = "Hello World!"; lblOutput.Size = new System.Drawing.Size (216, 24);

V tr ca Label c xc nh bng mt i tng Point, i tng ny cn hai thng s : v tr so vi chiu ngang (horizontal) v ng (vertical) ca thanh cun. Kch thc ca Label cng c t bi i tng Size, vi hai thng s l chiu rng (width) v cao (height) ca Label. C hai i tng Point v Size u thuc vng tn System.Drawing : cha cc i tng v lp dng cho ha. Tng t lm vi i tng Button :
btnCancel.Location = new System.Drawing.Point (150,200); btnCancel.Size = new System.Drawing.Size (112, 32); btnCancel.Text = "&Cancel";

111

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

bt s kin click ca Button, i tng Button cn ng k vi trnh qun l s kin, thc hin iu ny ta dng delegate. Phng thc c y thc (s bt s kin) c th c tn bt k nhng phi tr v kiu void v phi c hai thng s : mt l i tng sender v mt l i tng System.EventArgs.
protected void btnCancel_Click( object sender, System.EventArgs e) { //... }

Ta ng k phng thc bt s kin theo hai bc. u tin, ta to mt trnh qun l s kin mi System.EventHandler, ri y tn ca phng thc bt s kin vo lm tham s :
new System.EventHandler (this.btnCancel_Click);

Tip theo ta s y thc trnh qun l va to trn cho s kin click ca Button bng ton t += M gp ca hai bc trn :
one:btnCancel.Click +=new System.EventHandler (this.btnCancel_Click);

kt thc vic vit m trong hm khi to ca Form, tng Label v button vo Form ca ta :
this.Controls.Add (this.btnCancel); this.Controls.Add (this.lblOutput);

ta s thm hai i

Sau khi ta nh ngha hm bt s kin click trn Button, ta s vit m thi hnh cho hm ny. Ta s dng hm tnh ( static ) Exit() ca lp Application kt thc ng dng :
protected void btnCancel_Click( object sender, System.EventArgs e) { Application.Exit(); }

Cui cng, ta s gi hm khi to ca Form trong hm Main(). Hm Main() l im vo u tin ca Form.


public static void Main( ) { Application.Run(new HandDrawnClass( )); }

Sau y l m hon chnh ca ton b ng dng


using System; using System.Windows.Forms; namespace ProgCSharp { public class HandDrawnClass : Form { // Label dng hin th chui Hello World private System.Windows.Forms.Label lblOutput; // Button nhn Cancel private System.Windows.Forms.Button btnCancel;

112

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

public HandDrawnClass( ) { // To cc i tng this.lblOutput = new System.Windows.Forms.Label ( ); this.btnCancel = new System.Windows.Forms.Button ( ); // Gn tiu cho Form this.Text = "Hello World"; // Hiu chnh Label lblOutput.Location = new System.Drawing.Point(16,24); lblOutput.Text = "Hello World!"; lblOutput.Size = new System.Drawing.Size (216, 24); // Hiu chnh Button btnCancel.Location = newSystem.Drawing.Point(150,20); btnCancel.Size = new System.Drawing.Size (112, 32); btnCancel.Text = "&Cancel"; // ng k trnh qun l s kin btnCancel.Click += new System.EventHandler (this.btnCancel_Click); //Thm cc iu khin vo Form this.Controls.Add (this.btnCancel); this.Controls.Add (this.lblOutput);

// Bt s kin nhn Button protected void btnCancel_Click(object sender, EventArgs e) { Application.Exit( ); } // Chy ng dng public static void Main() { Application.Run(new HandDrawnClass( )); } } }

13.1.1.2 Dng ko th trong Visual Studio .NET


Bn cnh trnh son m, .NET cn cung cp mt b cc cng c ko th lm vic trong mi trng pht trin tch hp IDE ( Intergrate Development Enviroment ), IDE cho php ko th ri t ng pht sinh m tng ng. Ta s to li ng dng trn bng cch dng b cng c trong Visual Studio, ta m Visual Studio v chn New Project. Trong ca s New Project, chn loi d n l Visual C# v kiu ng dng l Windows Applications, t tn cho ng dng l
ProgCSharpWindowsForm.

113

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 13-2 Mn hnh to ng dng Windows mi.

Vs.NET s to mt ng dng Windows mi v t chng vo IDE nh hnh di :


Hnh 13-3 Mi trng thit k ko th

Pha bn tri ca ca hnh trn l mt b cc cng c (Toolbox) ko th dnh cho cc ng dng Windows Form, chnh gia l mt Form c .NET to sn c tn Form1. Vi b cng c trn, ta c th ko v th mt Label hay Button trc tip vo Form, nh hnh sau :

114

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 13-4 Mi trng pht trin Windows Form.

Vi thanh cng c Toolbox bn tri, ta c th thm cc thnh phn mi vo n bng cc chn View/Add Reference. G bn phi pha trn l ca s duyt ton b cc tp tin trong gii php (Solution, mt gii php c mt hay nhiu d n con). Pha di l ca s thuc tnh, hin th mi thuc tnh v mc chn hin hnh. Ta c th gn gi tr chui hin th hoc thay i font cho Label mt cch trc tip trong ca s thuc tnh.

115

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 13-5 Thay i font trc tip bng hp thoi font.

Vi IDE ny, ta c th ko th mt Button v bt s kin click ca n mt cch d dng, ch cn Nhn p vo Button th t ng .NET s pht sinh ra cc m tng ng trong trang m ca Form (Code-Behind page) nh : khai bo, to Button v hm bt s kin click ca Button.

116

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 13-6 Sau khi nhn p vo nt Cancel.

By gi, ta ch cn g thm mt dng code na trong hm bt s kin ca Button l ng dng c th chy c y nh ng dng m ta to bng cch g code trong phn trn.
Application.Exit( );

Sau y l ton b m c pht sinh bi IDE v dng m bn mi g vo :


using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace ProgCSharpWindowsForm { /// <summary> /// Summary description for Form1. /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.Label lblOutput; private System.Windows.Forms.Button btnCancel; /// <summary> /// Required designer variable. /// </summary>

117

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

private System.ComponentModel.Container components; public Form1( ) { InitializeComponent( ); } public override void Dispose( ) { base.Dispose( ); if(components != null) components.Dispose( ); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent( ) { this.lblOutput = new System.Windows.Forms.Label( ); this.btnCancel = new System.Windows.Forms.Button( ); this.SuspendLayout( ); // // lblOutput // this.lblOutput.Font = new System.Drawing.Font("Arial", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point,((System.Byte)(0))); this.lblOutput.Location = new System.Drawing.Point(24, 16); this.lblOutput.Name = "lblOutput"; this.lblOutput.Size = new System.Drawing.Size(136, 48); this.lblOutput.TabIndex = 0; this.lblOutput.Text = "Hello World"; // btnCancel this.btnCancel.Location = new System.Drawing.Point(192, 208); this.btnCancel.Name = "btnCancel"; this.btnCancel.TabIndex = 1; this.btnCancel.Text = "Cancel"; this.btnCancel.Click += new System.EventHandler( this.btnCancel_Click ); this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(292, 273); this.Controls.AddRange(new System.Windows.Forms.Control[]{ this.btnCancel, this.lblOutput}); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false);

private void btnCancel_Click(object sender, System.EventArgs e) { Application.Exit( ); } #endregion

118

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

/// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main( ) { Application.Run(new Form1( )); } } }

So vi on m ta g vo trong ng dng trc th m do IDE pht sinh khng khc g nhiu. Cc dng ch thch c dng lm su liu bo co cho d n. (mc ny s c tho lun sau)
/// <summary> /// Summary description for Form1. /// </summary>

Cc m to v hiu chnh i tng thay v c t trc tip vo hm khi to ca Form, th y IDE t chng vo trong hm InitializeComponent(), Sau hm ny c gi bi hm khi to ca Form. Mi ng dng Windows Form u pht sinh ra hm ny.

13.1.2 To mt ng dng Windows Form khc


Trong ng dng trn ta tho lun s qua v ng dng Windows Form, phn ny ta s to mt ng dng Windows khc thc t hn. ng dng c tn l FileCopier, cho php chp hay xa mt hoc nhiu tp tin t v tr ny sang v tr khc. Mc ch ca ng dng l minh ha su hn v cc k nng lp trnh C# v gip ngi c hiu thm v namespace Windows.Forms. Giao din ca ng dng sau khi hon chnh s nh sau :

119

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 13-7 Giao din ngi dng ca ng dng FileCopier.

Giao din ca ng dng gm cc thnh phn sau : Labels: Cc tp tin ngun (Source Files) and Th mc ch (Target Directory). Buttons: B cc du chn trn cy bn tri (Clear), Copy, Delete, and Cancel. Checkbox : ghi ln nu c sn ( "Overwrite if exists" ) Checkbox : hin th ng dn ca mc c trn cy bn phi. Hai cy (TreeView) cha tp tin.

Khi ngi dng nhn vo Button Copy th tt cc tp tin c chn cy bn tri s c chp qua cy bn phi, cng nh khi nhn vo Button Delete th s xa cc tp tin c chn.

13.1.2.1 To giao din cho ng dng


u tin ta to mt d n Windows Form mi c tn FileCopier. IDE s hin th mn hnh thit k (Designer) ln, ta s thc hin ko th cc Label, Button, Checkbox v TreeView cho n khi thch hp nh hnh di y :

120

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 13-8 To giao din ng dng bng cch ko th dng Designer

Sau khi to giao din xong, ta t thuc tnh CheckBoxes cho cy bn tri c tn tvwSource thnh true, cn cy bn phi c tn tvwTargetDir thnh false, thc hin ta n gin ch chn v sa i trn ca s thuc tnh ca tng i tng. Khi ta nhn p ln bt k iu khin no th t ng Visual Studio .NET s pht sinh ra m tng ng bt s kin ca iu khin v t con tr ( Cursor ) vo ngay ti hm , ta nhn p vo Button Cancel v b sung m nh sau :
protected void btnCancel_Click( object sender, System.EventArgs e) { Application.Exit( ); }

13.1.2.2 Qun l iu khin TreeView


Trong ng dng ny, hai iu khin TreeView hot ng tng t nhau, ngoi tr iu khin cy bn tri tvwTargetDir c thuc tnh CheckBoxes l true v lit k c tp tin ln th mc, cn cy bn phi l false v ch lit ke th mc. Mc nhin th iu khin cy cho php chn nhiu mc mt lc, nhng ta s chnh li sao cho ch cy bn tri tvwSource mi c chn nhiu mc mt lc,bn phi th khng. Ta s to ra mt hm y d liu vo cy :
private void FillDirectoryTree(TreeView tvw, bool isSource)

C 2 tham s :
TreeView tvw: iu khin cy cn y d liu vo Bool isSource: c xc nh l d liu y cho cy. Nu isSource
l true th cy s lit k c tp tin v th mc, false th ch c tp tin.

Hm ny s c dng chung cho c hai iu khin cy :

121

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

FillDirectoryTree(tvwSource, true); FillDirectoryTree(tvwTargetDir, false);

i tng TreeNode iu khin TreeView c mt thuc tnh Nodes. thuc tnh ny nhn vo mt i tng TreeNodeCollection , i tng ny thc cht l mt mng cha cc i tng TreeNode, mi mt TreeNode l mt nt trn cy. Trc tin ta cn khi to cy v rng :
tvw.Nodes.Clear( );

Sau ta gi hm tnh GetLogicalDrives() ca i tng Enviroment ly v tt c cc a logic hin ang c trn my. i tng Enviroment cung cp cc thng tin nh : tn my tnh, phin bn h iu hnh, h thng th mc trn my tnh hin hnh.
string[] strDrives = Environment.GetLogicalDrives( );

strDrives s cha tn cc a logic hin c trn my. Sau ta s duyt qua tng a bng cch dng lnh foreach. Vi mi a logic, ta gi hm GetDirectories() ca i tng DirectoryInfo. Hm ny s tr v danh sch cc i tng DirectoryInfo, cha tt c cc tp tin v th mc trn a logic . Nhng ti y ta khng quan tm n kt qu m n tr v, mc ch ta gi hm ny ch yu l kim tra xem cc a c hp l hay khng, nu c bt k mt li no trn a th hm GetDirectories() s qung ra mt ngoi l. Ta s dng khi bt li trycatch bt li ny.
foreach (string rootDirectoryName in strDrives) { DirectoryInfo dir = new DirectoryInfo(rootDirectoryName); dir.GetDirectories( ); ... }

Khi a hp l, ta s to ra mt TreeNode ng vi rootDirectoryName a , chng hn nh : C:\, D:\ Ri thm TreeNode ny vo iu khin cy dng hm Add() thng qua thuc tnh Nodes ca cy.
TreeNode ndRoot = new TreeNode(rootDirectoryName); tvw.Nodes.Add(ndRoot);

Tip theo ta tin hnh duyt trn mi th mc con ca i tng TreeNode gc trn, lm iu ny ta gi hm GetSubDirectoriesNodes( ), hm ny cn nhn vo cc i s : TreeNode gc, tn ca n v c xc nh l c y c tp tin vo cy hay khng.
if (isSource) { GetSubDirectoryNodes(ndRoot, ndRoot.Text, true); } else { GetSubDirectoryNodes(ndRoot, ndRoot.Text, false); }

122

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Duyt qui trn cc th mc con Hm GetSubDirectoryNodes() bt u bng vic gi hm GetDirectories() nhn v mt danh sch cc i tng DirectoryInfo :
private void GetSubDirectoryNodes( TreeNode parentNode, string fullName, bool getFileNames) { DirectoryInfo dir = new DirectoryInfo(fullName); DirectoryInfo[] dirSubs = dir.GetDirectories( );

y ta thy node truyn vo c tn l parentNode ( nt cha ), ngha l nhng nt sau ny s c xem l nt con ca n. Bn s r hn khi tm hiu ht hm ny. Ta tin hnh duyt qua danh sch cc th mc con dirSubs, b qua cc mc c trng thi l n ( Hidden ).
foreach (Directory dirSub in dirSubs) { if ( (dirSub.Attributes & FileSystemAttributes.Hidden) != 0 ) { continue; }

FileSystemAttributes l bin c kiu enum, n cha mt s gi tr nh : Archive, Compressed, Encrypted, Hidden, Normal, ReadOnly Nu nh mc hin hnh khng trng thi n, ta s to ra mt TreeNode mi vi tham s l tn ca n. Sau Thm n vo nt cha parentNode :
TreeNode subNode = new TreeNode(dirSub.Name); parentNode.Nodes.Add(subNode);

Ta s gi li qui hm GetDirectoriesNodes() lit k ht mi mc con trn th nt hin hnh, vi ba thng s : nt c chuyn vo nh nt cha, tn ng dn y ca mc hin hnh v c trng thi.
GetSubDirectoryNodes(subNode,dirSub.FullName,getFileNames);

Ch : Thuc tnh dirSubs.FullName s tr v ng dn y ca mc hin hnh ( C:\dir1\dir2\file1 ), cn thuc tnh dirSubs.Name ch tr v tn ca mc hin hnh ( file1). Khi ta to ra mt nt con subNode, ta ch truyn cho n tn ca mc hin hnh, v ta ch mun hin th th tn ca n trn cy. Cn khi ta gi qui hm GetSubDirectoryNodes() th ta cn truyn cho n tn ng dn y ca mc hin hnh, c th lit k ton b mc con ca thc mc ang xt. n y chc bn hiu c s phn cp ca cu trc cy v ti sao hm GetSubDirectoryNodes() cn truyn c i s FullName. Ly v cc tp tin trong th mc Nu bin c getFileNames l True th ta s tin hnh ly v tt c cc tp tin thuc th mc. thc hin ta gi hm GetFiles() ca i tng DirectoryInfo, hm ny s tr v danh sch cc i tng FileInfo. Ta s duyt qua danh sch ny ly ra

123

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

tn ca tng tp tin mt, sau to ra mt nt TreeNode vi tn ny, nt ny s c thm vo nt cha parentNode hin hnh.

13.1.2.3 Qun l s kin trn iu khin cy


Trong ng dng ny, chng ta s phi qun l mt s s kin. u tin l s kin ngi dng nhn ln CheckBox chn cc tp tin hay th mc cy bn phi hay nhn cc nt cy bn phi. Tip theo l cc s kin nhn vo Button Cancel, Copy,Delete hay Clear. Ta s kho st s kin trn iu khin cy trc. S kin chn mt nt trn iu khin cy bn tri Khi ngi dng mun chn mt tp tin hay th mc chp hay xa. ng vi mi ln chn s pht sinh ra mt s s kin tng ng. Ta s bt s kin AfterCheck ca iu khin cy. Ta g vo cc on m sau :
tvwSource.AfterCheck += new TreeViewEventHandler( this.tvwSource_AfterCheck );

Ta vit lnh thc thi cho hm bt s kin AfterCheck c tn l tvwSource_AfterCheck, hm ny c hai tham s : u tin l bin Sender cha thng tin v i tng pht sinh ra s kin, th hai l i tng TreeViewEventArgs cha thng tin v s kin pht ra. Ta s nh du l chn cho th mc c chn v tt c cc tp tin hay th mc con ca th mc thng qua hm SetCheck() :
protected void tvwSource_AfterCheck ( object sender, System.Windows.Forms.TreeViewEventArgs e) { SetCheck(e.node,e.node.Checked); }

Hm SetCheck() s tin hnh thc hin qui trn nt hin hnh, hm gm hai tham s : nt cn nh du v c xc nh l nh du hay b nh du chn, nu thuc tnh Count bng khng ( ngha l nt ny l nt l ) th ta s nh du chn cho nt . Nu khng ta gi qui li hm SetCheck() :
private void SetCheck(TreeNode node, bool check) { node.Checked = check; foreach (TreeNode n in node.Nodes) { if (node.Nodes.Count == 0) { node.Checked = check; } else { SetCheck(n,check); } } }

124

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

S kin chn mt nt trn iu khin cy bn phi Khi ngi dng chn mt nt cy bn phi, ta s phi cho hin ng dn y ca nt ln TextBox gc phc trn bn phi. Ta s bt s kin AfterSelect ca cy. S kin ny s c gi sau khi ngi dng nhn mt nt no trn cy, hm bt s kin ny nh sau :
protected void tvwTargetDir_AfterSelect( object sender, System.Windows.Forms.TreeViewEventArgs e) { string theFullPath = GetParentString(e.node);

Sau khi ta c c ng dn y ca nt chn, ta s b i du \\ (Backslash) nu c. Ri cho hin th ln hp thoi TextBox.


if (theFullPath.EndsWith("\\")) { theFullPath =theFullPath.Substring(0,theFullPath.Length-1); } txtTargetDir.Text = theFullPath; }

Hm GetParentString() tr v ng dn y ca nt c truyn vo lm thng s. Hm ny cng tin hnh lp qui trn nt truyn vo nu nt ny khng l nt l v thm du \\ vo n. Qu lp s kt thc nu nt hin hnh l khng l nt cha.
private string GetParentString(TreeNode node) { if(node.Parent == null) { return node.Text; } else { return GetParentString(node.Parent) + node.Text + (node.Nodes.Count == 0 ? "" : "\\"); } }

Qun l s kin nhn nt b chn (Clear) Ta tin hnh b sung m lnh sau cho hm bt s kin nhn vo nt Clear :
protected void btnClear_Click( object sender, System.EventArgs e) { foreach ( TreeNode node in tvwSource.Nodes ) { SetCheck(node, false); } }

Hm ny ch n gin l duyt qua tt c cc nt thuc cy bn tri, sau gi li hm SetCheck() vi bin c l false, ngha l b chn tt c cc nt hin ang c chn trn iu khin cy. Qun l s kin nhn nt chp tp tin ( Copy ) Ci ta cn hon chnh thao tc ny l danh sch cc i tng FileInfo. c th qun l linh hot trn danh sch ny ta s dng i tng ArrayList, n cho php ta

125

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

thc hin hu ht mi thao tc trn danh sch mt cc d dng. lt v danh sch cc i tng FileInfo, ta s gi hm GetFileList() ca ta :
protected void btnCopy_Click( object sender, System.EventArgs e) { ArrayList fileList = GetFileList( );

Ly v danh sch cc tp tin

u tin ta s khi to mt i tng ArrayList lu tr danh sch tn cc tp tin c chn, c tn l fileNames :


private ArrayList GetFileList( ) { ArrayList fileNames = new ArrayList( );

Ta ly v danh sch tn cc tp tin c chn bng cch duyt ton b cc nt trong iu khin cy bn phi :
foreach (TreeNode theNode in tvwSource.Nodes) { GetCheckedFiles(theNode, fileNames); }

Hm GetCheckedFiles() thm danh sch tn cc tp tin c nh du ca nt hin hnh theNode vo i tng fileNames. Nu nt truyn vo l nt l v c nh du chn, ta s ly ng dn y ca nt v thm vo i tng fileNames:
private void GetCheckedFiles(TreeNode node, ArrayList fileNames) { if (node.Nodes.Count == 0) { if (node.Checked) { string fullPath = GetParentString(node); fileNames.Add(fullPath); } }

Nu khng l nt l, ta s lp qui tm nt l :
else { foreach (TreeNode n in node.Nodes) GetCheckedFiles(n,fileNames); } }

Sau khi thc hin ht hm ny (ngha l duyt ht cy tvwSource), i tng fileNames s cha ton b cc tp tin c nh du chn ca cy. Quay tr li kho st tip tc hm GetFileList(), ta to thm mt i tng ArrayList na, tn fileList. Mng ny s cha danh sch cc i tng FileInfo ng vi cc tn tp tin tm c trong mng fileNames. Thuc tnh Exists ca i tng FileInfo dng kim tra l tp tin hay th mc. Thuc tnh Exists l True th i tng FileInfo l tp tin v ta s thm vo mng fileList, ngc li l th mc th khng thm .
foreach (string fileName in fileNames)

126

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

FileInfo file = new File(fileName); if (file.Exists) fileList.Add(file);

13.1.2.4 Qun l s kin nhn chn nt xa ( Delete )


Trc tin ta cn m bo rng ngi dng chc chn mun xa bng cch cho hin ln mt hp thoi xc nhn xa. hin th hp thoi ta dng hm tnh Show() ca i tng MessageBox.
protected void btnDelete_Click( object sender, System.EventArgs e) { System.Windows.Forms.DialogResult result = MessageBox.Show( "Are you quite sure?",// Thng ip "Delete Files", // Tiu cho hp thoi MessageBox.Buttons.OKCancel,// nt nhn MessageBox.Icon.Exclamation,// biu tng hp thoi MessageBox.DefaultButton.Button2); // nt mc nh }

Khi ngi dng nhn nt OK hay Cancel, ta s nhn c gi tr tr v t i tng DialogResult thuc namespace Forms v tin hnh x l tng ng :
if (result == System.Windows.Forms.DialogResult.OK) {

Nu ngi dng chn nt OK th ta s ly v danh sch tn cc tp tin fileNames, sau duyt qua tng tn v xa chng i :
ArrayList fileNames = GetFileList( ); foreach (FileInfo file in fileNames) { try { lblStatus.Text = "Deleting " + txtTargetDir.Text + "\\" + file.Name + "..."; Application.DoEvents( ); file.Delete( ); } catch (Exception ex) { MessageBox.Show(ex.Message); } } lblStatus.Text = "Done."; Application.DoEvents( );

Sau y l m ca ton b ng dng :


using using using using using using using System; System.Collections; System.ComponentModel; System.Data; System.Drawing; System.IO; System.Windows.Forms;

127

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

/// <remarks> /// chp tp tin ng dng minh ha cho Windows Form /// </remarks> namespace FileCopier { /// <summary> /// Form minh ha cho ng dng Windows Form /// </summary> public class Form1 : System.Windows.Forms.Form { /// <summary> /// lp bn trong ca lp Form1, so snh 2 tp tin /// </summary> public class FileComparer : IComparer { public int Compare (object f1, object f2) { FileInfo file1 = (FileInfo) f1; FileInfo file2 = (FileInfo) f2; if (file1.Length > file2.Length) { return -1; } if (file1.Length < file2.Length) { return 1; } return 0; } } public Form1( ) { InitializeComponent( ); // y d liu vo cy bn tri v bn phi FillDirectoryTree(tvwSource, true); FillDirectoryTree(tvwTargetDir, false); } /// <summary> /// phng thc ny dng y d liu vo cy /// </summary> private void FillDirectoryTree(TreeView tvw, bool isSource) { // trc khi y d liu vo cy, ta phi xa b cc nt // hin ang tn ti trn cy. tvw.Nodes.Clear( ); // ly v danh sch cc a logic trn my tnh // sau y chng vo lm nt gc ca cy string[] strDrives = Environment.GetLogicalDrives( ); // Duyt qua cc a, dng khi // k li no xy ra trn a, nu // thm vo lm nt gc cho cy. // a khng hp l s khng thm // CD trng ... foreach (string rootDirectoryName try/catch bt bt a hp l th ta vo cy : a mm hay in strDrives)

128

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

if (rootDirectoryName != @"C:\") continue; try { // nu a khng hp l ta s qung ra mt li. DirectoryInfo dir = new DirectoryInfo(rootDirectoryName); dir.GetDirectories( ); TreeNode ndRoot = new TreeNode(rootDirectoryName); // thm nt gc vo cy tvw.Nodes.Add(ndRoot); // thm cc nt con vo cy, nu l cy bn tri // th thm c tp tin vo cy if (isSource) GetSubDirectoryNodes(ndRoot, ndRoot.Text, true); else GetSubDirectoryNodes(ndRoot, ndRoot.Text, false); } catch (Exception e) { // thng bo a c li MessageBox.Show(e.Message); }

} } // kt thc thao tc y d liu vo cy /// <summary> /// ly v tt c cc th mc con ca nt cha truyn vo, /// thm cc th mc con tm c vo cy /// hm ny c 3 i s : nt cha, tn y ca nt cha, /// v bin c getFileNames xc nh c ly tp tin khng /// </summary> private void GetSubDirectoryNodes( TreeNode parentNode, string fullName, bool getFileNames) { DirectoryInfo dir = new DirectoryInfo(fullName); DirectoryInfo[] dirSubs = dir.GetDirectories( ); // ng vi mi mc con ta thm vo cy nu n khng // trng thi n. foreach (DirectoryInfo dirSub in dirSubs) { // b qua cc th mc n if ( (dirSub.Attributes & FileAttributes.Hidden) != 0 ) { continue; } /// <summary> /// ta ch cn tn nt thm vo cy, cn ta phi /// truyn vo tn ng dn y ca nt trn cy /// cho hm lp qui GetSubDirectoryNodes() n c /// th tm c cc nt con ca nt /// </summary> TreeNode subNode = new TreeNode(dirSub.Name);

129

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

parentNode.Nodes.Add(subNode); // lp qui hm GetSubDirectoryNodes(). GetSubDirectoryNodes( subNode,dirSub.FullName,getFileNames); } if (getFileNames) { // ly mi tp tin thuc nt FileInfo[] files = dir.GetFiles( ); // thm cc tp tin v nt con foreach (FileInfo file in files) { TreeNode fileNode = new TreeNode(file.Name); parentNode.Nodes.Add(fileNode); } } } /// <summary> /// im vo chnh ca ng dng. /// </summary> [STAThread] static void Main( ) { Application.Run(new Form1( )); } /// <summary> /// to ra mt danh sch c th t cc tp tin c chn , /// chp chng sang cy bn phi /// </summary> private void btnCopy_Click(object sender, System.EventArgs e) { // ly v danh sch tp tin ArrayList fileList = GetFileList( ); // tin hnh chp tp tin foreach (FileInfo file in fileList) { try { lblStatus.Text = "Copying " + txtTargetDir.Text + "\\" + file.Name + "..."; Application.DoEvents( ); file.CopyTo(txtTargetDir.Text + "\\" + file.Name,chkOverwrite.Checked); } catch // (ta khng lm g y c) { } } lblStatus.Text = "Done."; Application.DoEvents( ); } /// <summary>

130

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

/// bt s kin kt thc ng dng /// </summary> private void btnCancel_Click(object sender, System.EventArgs e) { Application.Exit( ); } /// <summary> /// bt s kin xa b cc nt c chn trn cy bn tri /// </summary> private void btnClear_Click( object sender, System.EventArgs e) { // ly v nt gc trn cy bn tri v // tin hnh lp qui foreach (TreeNode node in tvwSource.Nodes) { SetCheck(node, false); } } /// <summary> /// m bo ngi dng mun xa nt /// </summary> private void btnDelete_Click(object sender, System.EventArgs e) { // xc nhn xa System.Windows.Forms.DialogResult result = MessageBox.Show( "Are you quite sure?", // thng ip "Delete Files", // tiu MessageBox.Buttons.OKCancel, // nt nhn MessageBox.Icon.Exclamation, // biu tng MessageBoxDefaultButton.Button2); // nt mc nh // nu ng xa if (result == System.Windows.Forms.DialogResult.OK) { // duyt danh sch cc tp tin v xo cc tp tin / c chn ArrayList fileNames = GetFileList( ); foreach (FileInfo file in fileNames) { try { // cp nht nhn lblStatus.Text = "Deleting " + txtTargetDir.Text + "\\" + file.Name + "..."; Application.DoEvents( ); file.Delete( ); } catch (Exception ex) { // hp thoi thng bo MessageBox.Show(ex.Message); } } lblStatus.Text = "Done."; Application.DoEvents( );

131

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

/// <summary> /// ly ng dn y ca nt c chn v gn vo /// iu khin TextBox txtTargetDir /// </summary> private void tvwTargetDir_AfterSelect( object sender, System.Windows.Forms.TreeViewEventArgs e) { // ly ng dn y ca nt string theFullPath = GetParentString(e.Node); // nu n khng l nt l, ta s xa 2 k t cui cng // i, v y l du // if (theFullPath.EndsWith("\\")) { theFullPath = theFullPath.Substring(0,theFullPath.Length-1); } // gn ng dn cho iu khin TextBox txtTargetDir.Text = theFullPath; } /// <summary> /// nh du chn nt hin hnh v cc nt con ca n /// </summary> private void tvwSource_AfterCheck(object sender, System.Windows.Forms.TreeViewEventArgs e) { SetCheck(e.Node,e.Node.Checked); } /// <summary> /// lp qui vic nh du chn hay loi b du chn trn /// nt trun vo da vo c check /// </summary> private void SetCheck(TreeNode node, bool check) { // set this node's check mark node.Checked = check; // tm tt c cc nt con ca nt foreach (TreeNode n in node.Nodes) { // nu l nt l th ta nh du chn hoc khng chn if (node.Nodes.Count == 0) node.Checked = check; // nu khng l l th ta lp qui else SetCheck(n,check); } } // ly v tt c cc tp tin c nh du chn thuc // nt private void GetCheckedFiles(TreeNode node,ArrayList fileNames) {

132

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

// nu l nt l if (node.Nodes.Count == 0) { // nu nt l nh du chn if (node.Checked) { // ly ng dn y ca nt v thm vo cy string fullPath = GetParentString(node); fileNames.Add(fullPath); } } else // khng l nt l { // thc hin trn tt c nt con foreach (TreeNode n in node.Nodes) { GetCheckedFiles(n,fileNames); } }

/// <summary> /// ly v ng dn y ca nt truyn vo /// </summary> private string GetParentString(TreeNode node) { // nu l nt gc th tr v tn nt ( c:\ ) if(node.Parent == null) return node.Text; else // nu l nt cha th thm du // vo chui tr v // nu nt l ta khng thm g c return GetParentString(node.Parent) + node.Text + (node.Nodes.Count == 0 ? "" : "\\"); } /// <summary> /// tr v danh sch cc tp tin c chn theo th t /// </summary> private ArrayList GetFileList( ) { // danh sch tn tp tin y khng c sp ArrayList fileNames = new ArrayList( ); // duyt tng nt ca cy v ly v danh sch cc tp // tin c chn foreach (TreeNode theNode in tvwSource.Nodes) { GetCheckedFiles(theNode, fileNames); } // danh sch cc i tng FileInfo ArrayList fileList = new ArrayList( ); // fileNames l tp tin th ta thm vo fileList foreach (string fileName in fileNames) { // to ra FileInfo tng ng vi fileName

133

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

FileInfo file = new FileInfo(fileName); if (file.Exists) fileList.Add(file); } // to ra mt th hin IComparer IComparer comparer = (IComparer) new FileComparer( ); // sp xp danh sch tp tin fileList.Sort(comparer); return fileList;

} } }

13.1.3 To su liu XML bng ch thch


Ngn ng C# h tr kiu ch thch mi, bng ba du gch cho ( /// ). Trnh bin dch C# dng phn ch thch ny to thnh su liu XML. Ta c th to tp tin su liu XML ny bng m lnh, v d nh to su liu cho ng dng FileCopier trn ta g cc lnh sau :
csc filecopier.cs /r:System.Windows.Forms.dll /r:mscorlib.dll /r:system.dll /r:system.configuration.dll /r:system.data.dll /r:system.diagnostics.dll /r:system.drawing.dll /r:microsoft.win32.interop.dll /doc:XMLDoc.XML

Ta cng c th to su liu XML trc tip ngay trong Visual Studio .NET, bng cch nhn chut phi ln biu tng ca d n v chn Properties hin ln hp thoi thuc tnh ca d n (Property Pages), sau chn mc Configuration Properties \ Build ri g tn tp tin su liu XML cn to ra vo dng XML Document File. Khi bin dch d n, tp tin su liu XML s t ng c to ra trong th mc cha d n. Di y l mt on m c trch ra t tp tin su liu XML c to ra t ng dng FileCopier trn :
<?xml version="1.0"?> <doc> <assembly> <name>FileCopier</name> </assembly> <members> <member name="T:FileCopier.Form1"> <summary> Form demonstrating Windows Forms implementation </summary> </member> <member name="F:FileCopier.Form1.components"> <summary> Required designer variable. </summary> </member> <member name="F:FileCopier.Form1.tvwTargetDir"> <summary> Tree view of potential target directories

134

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

</summary> </member> <member name="F:FileCopier.Form1.tvwSource"> <summary> Tree view of source directories includes check boxes for checking chosen files or directories </summary> </member> <member name="F:FileCopier.Form1.txtTargetDir">

Do on m trn c nh dng di kiu di dng XML, do khng thun tin lm khi quan st. Ta c th vit mt tp tin theo nh dng XSLT chuyn t nh dng XML sang HTML. Mt cch n gin hn to su liu XML thnh cc bo co HTML d c hn l dng chc nng Tool \ Build Command Web Page , VS.NET s t ng to ra mt tp cc tp tin su liu HTML tng ng vi tp tin XML. Di y l giao din ca mn hnh su liu ng dng FileCopier c to bi VS.NET :
Hnh 13-9 Su liu di dng Web c to bi Visual Studio .NET

13.1.4 Trin khai ng dng


Khi ng dng thc thi hon chnh, vn by gi l lm cch no c th trin khai n. Vi cc ng dng n gin, ch cn chp assembly ca ng dng sang my khc v chy.

135

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

V d ta dch ng dng FileCopier thnh tp tin chy FileCopier.exe, sau chp sang my khc v chy n. ng dng s thc thi tt.

13.1.4.1 Vic trin khai cc d n ( Deployment Projects )


i vi cc ng dng thng mi ln hn, khch hng mun ng dng c ci t vo mt th mc c th vi biu tng c trng ca h, khi cch n gin trn cha . Visual Studio .NET cung cp thm mt phn m rng khc h tr vic ci t v trin khai (Setup and Deployment Projects) ng dng. Gi s ta ang trong mt d n no , ta chn File\Add Project \ New Project \ Setup and Deployment Projects. Ta s thy hp thoi sau :
Hnh 13-10 Hp thoi to d n mi.

Ta c nhiu nhiu kiu d n trin khai khc nhau : Setup Project : To ra tp tin ci t, tp tin ny c th t ci t cc tp tin v ti nguyn ca ng dng. Cab Project :Ging nh mt tp tin ZIP, d n loi ny nn cc tp tin thnh mt gi ( Package ) . Chn la ny c th kt hp vi cc loi khc. Merge Module : Nu ng dng ca ta c nhiu d n cng dng chung mt s tp tin, th s chn la ny gip ta trn chng thnh cc module trung gian chung. Ta c th tch hp cc module ny vo cc d n khc. Setup Wizard : Gip thc hin mt trong cc loi d n trn c d dng. Web Setup Project : Gip trin khai cc d n Web.

136

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

hiu r, ta s th to mt d n trin khai kiu Cab Project, thng th khi d n ca ta c nhiu tp tin .Html, .Gif hay mt s loi ti nguyn khc m cn phi km theo vi ng dng th ta trin khai d n theo kiu ny. Thm d n loi Cab Project vo d n vi tn l FileCopierCabProject.
Hnh 13-11 D n c thm vo ng dng.

Hnh 13-12 Hai kiu thm trong d n loi CAB

Nhn chut phi trn d n trin khai FileCopierCabProject. C 2 dng ng gi tp tin CAB : Project Output v File . y ta chn Add \ Project Output, hp thoi chn la kiu kt xut cho d n ( Add Project Output Group ) xut hin :

137

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 13-13 La chn loi kt xut ng gi.

y, ta s chn loi Primary Output to tp tin FileCopier.exe cho ng dng FileCopier ca ta. Khi chy chng trnh th .NET s to ra mt gi c tn l FileCopierCabProject.CAB. Trong gi ny c cha 2 tp tin : FileCopier.exe Osd8c0.osd : tp tin chy ca ng dng : tp tin ny m t gi .CAB theo dng XML.

M m t XML tp tin .CAB


<?XML version="1.0" ENCODING='UTF-8'?> <!DOCTYPE SOFTPKG SYSTEM "http://www.microsoft.com/standards/osd/osd.dtd"> <?XML::namespace href="http://www.microsoft.com/standards/osd/msicd.dtd" as="MSICD"?> <SOFTPKG NAME="FileCopierCabProject" VERSION="1,0,0,0"> <TITLE> FileCopierCabProject </TITLE> <MSICD::NATIVECODE> <CODE NAME="FileCopier"> <IMPLEMENTATION> <CODEBASE FILENAME="FileCopier.exe"> </CODEBASE> </IMPLEMENTATION> </CODE> </MSICD::NATIVECODE> </SOFTPKG>

138

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

13.1.4.2 Vic ci t d n ( Setup Project )


to c chng trnh t ng ci t cho ng dng, ta thm d n khc v chn kiu l Setup Project, d n kiu ny kh linh ng. N to thnh tp tin c phn m rng l MSI, c th t ci t ng dng ca ta ln my tnh khc. UI phc v ch yu cho vic ci t l ca s View Menu :
Hnh 13-14 Giao din ngi dng View Menu.

ng vi mi chn la trn View Menu, ta s thy cc hin th tng ng trong hai ca s bn tri. Chng hn nh, khi ta chn View \ File System th bn tri s hin ra hai ca s nh nh hnh bn di, ta c th thm cc tp tin hay ti nguyn lin quan n ng dng theo mun :
Hnh 13-15 Ca s File System ca ng dng FileCopier

13.1.4.3 Trin khai trn cc v tr khc nhau


Mc nhin th ng dng s c ci t trn th mc sau :
[ProgramFilesFolder]\[Manufacturer]\[Product Name. ProgramFilesFolder: th mc Program Files trn my ngi dng Manufacturer: tn ca nh sn xut Product Name: tn ca ng dng

139

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Ta c th thay i cc thng s ny trong ca s thuc tnh FileCopierSetupProject hoc trong qu trnh ci t. To biu tng ca ng dng trn mn hnh Desktop. to biu tng cho ng dng, ta ch cn chn Application Folder\Primary output from FileCopier ( Active ) ca s bn tri, sau nhn chut phi v chn Create Shortcut to Primary output from FileCopier ( Active ). Ta hiu chnh ng dn ca biu tng cho thch hp. Thm cc mc vo th mc My Documents Ta cng c th thm cc ti liu cn thit vo th mc My Documents trn my ca ngi dng khi ci t, bng cch t chng vo th mc Users Personal Data Folder To biu trng trong ca s Start Menu thm cc thnh phn khc ca ng vo ca s Start / Programs, ta thm chng vo th mc Users Program Menu ca s bn phi.

13.1.4.4 Thm cc chc nng ci t khc cho ng dng trin khai


Ngoi bn mc c lit k trong hnh trn, ta c th b sung thm cc th mc khc, nh hnh di y :

140

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 13-16 B sung cc th mc trong ca s File System.

13.1.4.5 Cc thnh phn khc


Ta kho st qua cch ci t dng File System trong Menu View, nay ta tm hiu thm mt s cch khc. To cc thay i trong s ng k ( Registry ) Ca s ng k ca View Menu cho php lm cho trnh ci t ca chng ta to ra cc thay i trong s ng k chng trnh trn cc my ci t ng dng. Nhn chut phi trn cc th mc c lit trong hnh di y hiu chnh s ng k theo mun :

141

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 13-17 Hiu chnh s ng k.

Ch : Phi rt tht cn thn khi ci t s ng k. Trong hu ht cc ng dng .NET u khng cn thit phi lin quan n s ng k, .NET qun l ng dng khng cn dng s ng k (Registry). Qun l giao din ngi dng trong qu trnh ci t c th kim sot cc ch hay giao din ha hin th trong sut qu trnh ci t ng dng, ta chn mc User Interface trong View Menu. Hnh di y th hin lung cng vic trong qu trnh c t ng dng :
Hnh 13-18 Lung cng vic trong qu trnh ci t.

Khi ta nhn chut phi trn mt bc no trong tin trnh ci t v chn Properties th s hin ln mt ca s tng ng vi mc , nh hp thoi thuc tnh ny ta c th hiu chnh cc chui hay nh hin th thch hp. Ta cng c th

142

Lp trnh vi C#

Gvhd: Nguyn Tn Trn Minh Khang

thm hay bt i mt bc trong lung cng vic ci t. V d hp thoi thuc tnh ca mc Welcome.
Hnh 13-19 Ca s thuc tnh ca mc Welcome trong qu trnh ci t.

Hiu chnh thm cho qu trnh ci t Nu qu trnh ci t trong ca s User Interface vn khng tha mn nhu cu ci t ca ng dng, th ta c th t hiu chnh cc thng s cho tin trnh ci t : iu kin chy tin trnh ci t Ta chn mc Custom Option trong View Menu thc hin mc ch ny. Kt thc vic to chng trnh ci t Sau khi hon tt mi hiu chnh, ta ch cn chy ng dng v .NET s to ra mt tp tin ci t MSD ci t ng dng ca ta.

143

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

Chng 14 Truy cp d liu vi ADO.NET


Trong thc t, c rt nhiu ng dng cn tng tc vi c s d liu. .NET Framework cung cp mt tp cc i tng cho php truy cp vo c s d liu, tp cc i tng ny c gi chung l ADO.NET. ADO.NET tng t vi ADO, im khc bit chnh ch ADO.NET l mt kin trc d liu ri rc, khng kt ni (Disconnected Data Architecture). Vi kin trc ny, d liu c nhn v t c s d liu v c lu trn vng nh cache ca my ngi dng. Ngi dng c th thao tc trn d liu h nhn v v ch kt ni n c s d liu khi h cn thay i cc dng d liu hay yu cu d liu mi. Vic kt ni khng lin tc n c s d liu em li nhiu thun li, trong im li nht l vic gim i mt lu lng ln truy cp vo c s d liu cng mt lc, tit kim ng k ti nguyn b nh. Gim thiu ng k vn hng trm ngn kt ni cng truy cp vo c s d liu cng mt lc. ADO.NET kt ni vo c s d liu ly d liu v kt ni tr li cp nht d liu khi ngi dng thay i chng. Hu ht mi ng dng u s dng nhiu thi gian cho vic c v hin th d liu, v th ADO.NET cung cp mt tp hp con cc i tng d liu khng kt ni cho cc ng dng ngi dng c th c v hin th chng m khng cn kt ni vo c s d liu. Cc i tng ngt kt ni ny lm vic tng t i vi cc ng dng Web.

14.1 C s d liu v ngn ng truy vn SQL


c th hiu r c cch lm vic ca ADO.NET, chng ta cn phi nm c mt s khi nim c bn v c s d liu quan h v ngn ng truy vn d liu, nh: khi nim v dng, ct, bng, quan h gia cc bng, kha chnh, kha ngoi v cch truy vn d liu trn cc bng bng ngn ng truy vn SQL : SELECT, UPDATE, DELETE hay cch vit cc th tc ( Store Procedure) . Trong phm vi ca ti liu ny, chng ta s khng cp n cc mc trn. Trong cc v d sau, chng ta s dng c s d liu NorthWind, c cung cp bi Microsoft minh ha cho cc v d ca chng ta.

14.2 Mt s loi kt ni hin ang s dng


1982 ra i ODBC driver (Open Database Connectivity) ca Microsoft. Ch truy xut c thng tin quan h, khng truy xut c d liu khng quan h nh : tp tin vn bn, email Ta phi truy cp ODBC thng qua DSN.

144

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

truy cp c tt c Datastore, dng OLEDB provider thng qua ODBC. L v bc ca ODBC hoc khng. OLEDB d s dng hn ODBC, nhng ch c 1 s t ngn ng c th hiu c (C++), v th ra i ADO. OLEDB l giao din mc lp trnh h thng qun l d liu. OLEDB n gin ch l mt tp cc giao din COM ng gi thnh cc system service qun tr cc CSDL khc nhau. Gm 4 i tng chnh : Datasource, Session, Command, Rowset. ADO l mt COM, do c dng vi bt k ngn ng no tng thch vi COM. ADO khng c lp OS, nhng c lp ngn ng : C++,VB, JavaScript, VBScript L v bc ca OLEDB v ADO gm 3 i tng chnh : Connection, Command, Recordset. Remote Data Services ( RDS ) ca Microsoft cho php dng ADO thng qua cc giao thc HTTP, HTTPS v DCOM truy cp d liu qua Web. Microsoft Data Access Components (MDAC) l t hp ca ODBC, OLEDB, ADO v c RDS. Ta c th kt ni d liu bng mt trong cc cch: dng ODBC driver (DSN), dng OLEDB thng qua ODBC hoc OLEDB khng thng qua ODBC.

14.3 Kin trc ADO.NET


ADO.NET c chia ra lm hai phn chnh r rt, c th hin qua hnh
Hnh 14-1 Kin trc ADO.NET

D DataSet l thnh phn chnh cho c trng kt ni khng lin tc ca kin trc ADO.NET. DataSet c thit k c th thch ng vi bt k ngun d liu no. DataSet cha mt hay nhiu i tng DataTable m n c to t tp cc dng v ct d liu, cng vi kho chnh, kha ngoi, rng buc v cc thng tin lin

145

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

quan n i tng DataTable ny. Bn thn DataSet c dng nh mt tp tin XML. Thnh phn chnh th hai ca ADO.NET chnh l NET Provider Data, n cha cc i tng phc v cho vic thao tc trn c s d liu c hiu qu v nhanh chng, n bao gm mt tp cc i tng Connection, Command, DataReader v DataAdapter. i tng Connection cung cp mt kt ni n c s d liu, Command cung cp mt thao tc n c s d liu, DataReader cho php ch c d liu v DataAdapter l cu ni trung gian gia DataSet v ngun d liu.

14.4 M hnh i tng ADO.NET


C th ni m hnh i tng ca ADO.NET kh uyn chuyn, cc i tng ca n c to ra da trn quan im n gin v d dng. i tng quan trng nht trong m hnh ADO.NET chnh l Dataset. Dataset c th c xem nh l th hin ca c mt c s d liu con, lu tr trn vng nh cache ca my ngi dng m khng kt ni n c s d liu.

14.4.1 M hnh i tng ca Dataset


Hnh 14-2 M hnh i tng Dataset

DataSet bao gm mt tp cc i tng DataRelation cng nh tp cc i tng DataTable. Cc i tng ny ng vai tr nh cc thuc tnh ca DataSet.

146

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

14.4.2 i tng DataTable v DataColumn


Ta c th vit m C# to ra i tng DataTable hay nhn v t kt qu ca cu truy vn n c s d liu. DataTable c mt s thuc tnh dng chung ( public ) nh thuc tnh Columns, t thuc tnh ny ta c th truy cp n i tng DataColumnsCollection thng qua ch mc hay tn ca ct nhn v cc i tng DataColumn thch hp, mi DataColumn tng ng vi mt ct trong mt bng d liu. V d :
DataTable dt = new DataTable("tenBang"); DataColumn dc = dt.Columns["tenCot"];

14.4.3 i tng DataRelation


Ngoi tp cc i tng DataTable c truy cp thng qua thuc tnh Tables, DataSet cn c mt thuc tnh Relations. Thuc tnh ny dng truy cp n i tng DataRelationCollection thng qua ch mc hay tn ca quan h v s tr v i tng DataRelation tng ng. V d :
DataSet ds = new DataSet("tenDataSet"); DataRelation dre = ds.Relations["tenQuanHe"];

14.4.4 Cc bn ghi ( Rows )


Tng t nh thuc tnh Columns ca i tng DataTable, truy cp n cc dng ta cng c thuc tnh Rows. ADO. NET khng a ra khi nim RecordSet, thay vo duyt qua cc dng ( Row ), ta c th truy cp cc dng thng qua thuc tnh Rows bng vng lp foreach.

14.4.5 i tng SqlConnection v SqlCommand


i tng SqlConnection i din cho mt kt ni n c s d liu, i tng ny c th c dng chung cho cc i tng SqlCommand khc nhau. i tng SqlCommand cho php thc hin mt cu lnh truy vn trc tip : nh SELECT, UPDATE hay DELETE hay gi mt th tc (Store Procedure) t c s d liu.

14.4.6 i tng DataAdapter


ADO.NET dng DataAdapter nh l chic cu ni trung gian gia DataSet v DataSource ( ngun d liu ), n ly d liu t c s d liu sau dng phng Fill() y d liu cho i tng DataSet. Nh i tng DataAdapter ny m DataSet tn ti tch bit, c lp vi c s d liu v mt DataSet c th l th hin ca mt hay nhiu c s d liu. V d :
//To i tng SqlDataAdapter SqlDataAdapter sda = new SqlDataAdapter(); // cung cp cho sda mt SqlCommand v SqlConnection ... // ly d liu ... //to i tng DataSet mi DataSet ds = new DataSet("tenDataSet");

147

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

//y d liu trog sda vo ds bng hm Fill(); sda.Fill(ds);

14.5 Trnh cung cp d liu (.NET Data Providers)


.NET Framework h tr hai trnh cung cp d liu l SQL Server .NET Data Provider ( dnh cho phin bn SQL Server 7.0 ca Microsoft tr ln ) v OLE DB .NET Data Provider ( dnh cho cc h qun tr c s d liu khc ) truy cp vo c s d liu.
Hnh 14-3 So snh SQL Server .NET Data Provider v the OLE DB .NET Data Provider

SQL Server .NET Data Provider c cc c im : Dng nghi thc ring truy cp c s d liu Truy xut d liu s nhanh hn v hiu qu hn do khng phi thng qua lp OLE DB Provider hay ODBC Ch c dng vi h qun tr c s d liu SQL Server 7.0 tr ln. c Mircrosoft h tr kh hon chnh. OLE DB .NET Data Provider c cc c im : Phi thng qua 2 lp v th s chm hn Thc hin c cc dch v Connection Pool C th truy cp vo mi Datasource c h tr OLE DB Provider thch hp

14.6 Khi s vi ADO.NET


c th hiu r c ADO.NET, ngoi l thuyt ra, chng ta s kho st chi tit v cch chng hot ng ra bng m lnh c th. V d Windows Form di y s dng mt ListBox ly d liu t bng Custommers trong c s d liu NorthWind. u tin ta s to ra i tng DataAdapter :
SqlDataAdapter DataAdapter = new SqlDataAdapter( commandString, connectionString);

148

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

Hm khi to ca i tng ny gm hai tham s commandString v connectionString. commandString l chui cha cu lnh truy vn trn d liu m ta mun nhn v :
string commandString = "Select CompanyName, ContactName from Customers";

Bin connectString cha cc thng s kt ni n c s d liu. ng dng ca ta dng h qun tr c s d liu SQL Server, v th n gin ta s i s password l trng, uid l sa, my ch server l localhost v tn c s d liu l NorthWind :
string connectionString = "server=localhost; uid=sa; pwd=; database=northwind";

Vi i tng DataAdapter c to trn, ta s to ra mt i tng DataSet mi v y d liu vo n bng phng thc Fill() ca i tng DataAdapter.
DataSet dataSet = new DataSet( ); DataAdapter.FillDataSet(dataSet,"Customers");

i tng DataSet cha mt tp cc DataTable, nhng y ta ch cn ly d liu ca bng u tin l Customers :


DataTable dataTable = dataSet.Tables[0];

Ta s duyt qua tng dng ca bng bng vng lp foreach ly v tng DataRow mt, sau s truy cp n trng cn ly d liu thng qua tn ct, ri thm vo ListBox.
foreach (DataRow dataRow in dataTable.Rows) { lbCustomers.Items.Add( dataRow["CompanyName"] + " (" + dataRow["ContactName"] + ")" ); }

Sau y l on m y ca ng dng :
using using using using using using using System; System.Drawing; System.Collections; System.ComponentModel; System.Windows.Forms; System.Data; System.Data.SqlClient;

namespace ProgrammingCSharpWinForm { public class ADOForm1 : System.Windows.Forms.Form { private System.ComponentModel.Container components; private System.Windows.Forms.ListBox lbCustomers; public ADOForm1( ) { InitializeComponent( ); // kt ni n my ch, c s d liu northwind string connectionString = "server=localhost; uid=sa; pwd=; database=northwind";

149

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

// ly cc dng d liu t bng Customers string commandString = "Select CompanyName, ContactName from Customers"; // to ra i tng DataAdapter v DataSet SqlDataAdapter DataAdapter = new SqlDataAdapter(commandString, connectionString); DataSet DataSet = new DataSet( ); // y d liu vo DataSet DataAdapter.Fill(DataSet,"Customers"); // ly v mt bng d liu DataTable dataTable = DataSet.Tables[0]; // duyt tng dng ly d liu thm vo ListBox foreach (DataRow dataRow in dataTable.Rows) { lbCustomers.Items.Add(dataRow["CompanyName"] + " (" + dataRow["ContactName"] + ")" ); }

public override void Dispose( ) { base.Dispose( ); components.Dispose( ); } private void InitializeComponent( ) { this.components = new System.ComponentModel.Container(); this.lbCustomers = new System.Windows.Forms.ListBox(); lbCustomers.Location = new System.Drawing.Point(48, 24); lbCustomers.Size = new System.Drawing.Size(368, 160); lbCustomers.TabIndex = 0; this.Text = "ADOFrm1"; this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(464, 273); this.Controls.Add(this.lbCustomers); } public static void Main(string[] args) { Application.Run(new ADOForm1( )); }

} }

Ch vi mt s dng m ta c th ly d liu v hin th trong hp ListBox :

150

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 14-4 Kt xut ca v d trn.

hon chnh giao tc trn, ta cn thc hin tm dng m chnh : To ra chui kt ni vo c s d liu
string connectionString = "server=myServer; uid=sa; pwd=; database=northwind";

To cu lnh truy vn chn d liu


string commandString = "Select CompanyName, ContactName from Customers";

To i tng DataAdapter v chuyn cho n chui truy vn v kt ni


SqlDataAdapter DataAdapter = new SqlDataAdapter( commandString, connectionString);

To i tng DataSet mi
DataSet dataSet = new DataSet( );

y bng d liu Customers ly t DataAdapter vo dataSet


DataAdapter.Fill(dataSet,"Customers");

Trch i tng DataTable t dataSet trn


DataTable dataTable = DataSet.Tables[0];

y d liu trong bng dataTable vo ListBox


foreach (DataRow dataRow in dataTable.Rows) { lbCustomers.Items.Add(dataRow["CompanyName"] + " (" + dataRow["ContactName"] + ")" ); }

14.7 S dng trnh cung cp d liu c qun l


v d trn chng ta kho st qua cch truy cp d liu thng qua trnh cung cp d liu SQL Server .NET Data Provider. Trong phn ny chng ta s tip tc kho st sang trnh cung cp d liu OLE DB .NET Data Provider, vi trnh cung cp d liu ny ta c th kt ni n bt k h qun tr c s d liu no c h tr trnh cung cp d liu OLE DB Providers, c th l Microsoft Access. So vi ng dng trn, ta ch cn thay i mt vo dng m l c th hot ng c. u tin l chui kt ni :
string connectionString = "provider=Microsoft.JET.OLEDB.4.0; " + "data source = c:\\northwind.mdb";

151

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

Chui trn s kt ni n c s d liu northwind trn a C. K tip ta thay i i tng DataAdapter t SqlDataAdapter sang OleDbDataAdapter
OleDbDataAdapter DataAdapter = new OleDbDataAdapter( commandString, connectionString);

Chng ta phi m bo l namespace OleDb c thm vo ng dng :


using System.Data.OleDb;

Phn m cn li th tng t nh ng dng trn, sau y s trch ra mt on m chnh phc v cho vic kt ni theo cch ny :
public ADOForm1( ) { InitializeComponent( ); // chui kt ni n c s d liu string connectionString = "provider=Microsoft.JET.OLEDB.4.0;" + "data source = c:\\nwind.mdb"; // chui truy vn d liu string commandString = "Select CompanyName, ContactName from Customers"; // to i tng OleDbDataAdapter v DataSet mi OleDbDataAdapter DataAdapter = new OleDbDataAdapter( commandString, connectionString); DataSet dataSet = new DataSet( ); // y d liu vo dataSet DataAdapter.Fill(DataSet,"Customers"); // ly v bng d liu Customers DataTable dataTable = DataSet.Tables[0]; // duyt qua tng dng d liu foreach (DataRow dataRow in dataTable.Rows) { lbCustomers.Items.Add(dataRow["CompanyName"] + " (" + dataRow["ContactName"] + ")" ); } }

14.8 Lm vic vi cc iu khin kt buc d liu


ADO.NET h tr kh hon chnh cho cc iu khin kt buc d liu (DataBound), cc iu khin ny s nhn vo mt DataSet, sau khi gi hm DataBind() th d liu s t ng c hin th ln iu khin.

14.8.1 y d liu vo iu khin li DataGrid


V d sau s dng iu khin li DataGrid thc hin kt buc d liu, iu khin li ny c h tr cho c ng dng Windows Forms v WebForms.

152

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

Trong ng dng trc, ta phi duyt qua tng dng ca i tng DataTable ly d liu, sau hin th chng ln iu khin ListBox. Trong ng dng ny cng vic hin th d liu ln iu khin c thc hin n gin hn, ta ch cn ly v i tng DataView ca DataSet, sau gn DataView ny cho thuc tnh DataSource ca iu khin li, sau gi hm DataBind() th t ng d liu s c y ln iu khin li d liu.
CustomerDataGrid.DataSource = DataSet.Tables["Customers"].DefaultView;

Trc tin ta cn to ra i tng li trn Form bng cch ko th, t tn li cho iu khin li l CustomerDataGrid. Sau y l m hon chnh ca ng dng kt buc d liu cho iu khin li :
using using using using using using using System; System.Drawing; System.Collections; System.ComponentModel; System.Windows.Forms; System.Data; System.Data.SqlClient;

namespace ProgrammingCSharpWindows.Form { public class ADOForm3 : System.Windows.Forms.Form { private System.ComponentModel.Container components; private System.Windows.Forms.DataGrid CustomerDataGrid; public ADOForm3( ) { InitializeComponent( ); // khi to chui kt ni v chui truy vn d liu string connectionString = "server=localComputer; uid=sa; pwd=;database=northwind"; string commandString = "Select CompanyName, ContactName, ContactTitle, " + "Phone, Fax from Customers"; // to ra mt SqlDataAdapter v DataSet mi, // y d liu cho DataSet SqlDataAdapter DataAdapter = new SqlDataAdapter(commandString, connectionString); DataSet DataSet = new DataSet( ); DataAdapter.Fill(DataSet,"Customers"); // kt buc d liu ca DataSet cho li CustomerDataGrid.DataSource= DataSet.Tables["Customers"].DefaultView; } public override void Dispose( ) { base.Dispose( ); components.Dispose( ); }

153

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

private void InitializeComponent( ) { this.components = new System.ComponentModel.Container(); this.CustomerDataGrid = new DataGrid(); CustomerDataGrid.BeginInit(); CustomerDataGrid.Location = new System.Drawing.Point (8, 24); CustomerDataGrid.Size = new System.Drawing.Size (656, 224); CustomerDataGrid.DataMember = ""; CustomerDataGrid.TabIndex = 0; CustomerDataGrid.Navigate += new NavigateEventHandler(this.dataGrid1_Navigate); this.Text = "ADOFrm3"; this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size (672, 273); this.Controls.Add (this.CustomerDataGrid); CustomerDataGrid.EndInit ( ); } public static void Main(string[] args) { Application.Run(new ADOForm3()); } } }

iu khin li s hin th y ht mi d liu hin c trong bng Customers, tn ca cc ct trn li cng chnh l tn ca cc ct trong bn d liu. Giao din ca ng dng sau khi chy chng trnh :
Hnh 14-5 Kt buc d liu cho iu khin li DataGrid.

14.8.2 To i tng DataSet


Trong v d trc, to ra i tng SqlDataAdapter bng cch gn trc tip chui kt ni v chui truy vn vo n. i tng Connection v Command s c to v tch hp vo trong i tng DataAdapter ny. Vi cch ny, ta s b hn ch trong cc thao tc lin quan n c s d liu.

154

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

SqlDataAdapter DataAdapter = new SqlDataAdapter(commandString, connectionString);

V d sau y s minh ha vic ly v i tng DataSet bng cch to ra cc i tng Connection v Command mt cch ring bit, khi ta cn dng li chng hay mun thc hin hon chnh mt thao tc th s thun li hn. u tin ta s khai bo bn bin thnh vin thuc lp, nh sau :
private private private private System.Data.SqlClient.SqlConnection myConnection; System.Data.DataSet myDataSet; System.Data.SqlClient.SqlCommand myCommand; System.Data.SqlClient.SqlDataAdapter DataAdapter;

i tng Connection s c to ring vi chun kt ni :


string connectionString = "server=localhost; uid=sa; pwd=; database=northwind"; myConnection = new System.Data.Sql.SqlConnection(connectionString);

Sau ta s m kt ni :
myConnection.Open( );

Ta c th thc hin nhiu giao tc trn c s d liu khi kt ni c m v sau khi dng xong ta ch n gin ng kt ni li. Tip theo ta s to ra i tng DataSet:
myDataSet = new System.Data.DataSet( );

V tip tc to i tng Command, gn cho n i tng Connection m v chui truy vn d liu :


myCommand = new System.Data.SqlClient.SqlCommand( ) myCommand.Connection=myConnection; myCommand.CommandText = "Select * from Customers";

Cui cng ta cn to ra i tng SqlDataAdapter, gn i tng SqlCommand va to trn cho n, ng thi phi tin hnh nh x bng d liu n nhn c t cu truy vn ca i tng Command to s ng nht v tn cc ct khi y bng d liu ny vo DataSet.
DataAdapter = new System.Data.SqlClient.SqlDataAdapter( ); DataAdapter.SelectCommand= myCommand; DataAdapter.TableMappings.Add("Table","Customers"); DataAdapter.Fill(myDataSet);

By gi ta ch vic gn DataSet vo thuc tnh DataSoucre ca iu khin li:


dataGrid1.DataSource=myDataSet.Tables["Customers"].DefaultView;

Di y l m hon chnh ca ng dng ny :


using using using using using using using System; System.Drawing; System.Collections; System.ComponentModel; System.Windows.Forms; System.Data; System.Data.SqlClient;

namespace ProgrammingCSharpWindows.Form {

155

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

public class ADOForm1 : System.Windows.Forms.Form { private System.ComponentModel.Container components; private System.Windows.Forms.DataGrid dataGrid1; private System.Data.SqlClient.SqlConnection myConnection; private System.Data.DataSet myDataSet; private System.Data.SqlClient.SqlCommand myCommand; private System.Data.SqlClient.SqlDataAdapter DataAdapter; public ADOForm1( ) { InitializeComponent( ); // to i tng connection v m n string connectionString = "server=Neptune; uid=sa; pwd=oWenmEany;" + "database=northwind"; myConnection = new SqlConnection(connectionString); myConnection.Open(); // to i tng DataSet mi myDataSet = new DataSet( ); // to i tng command mi v gn cho i tng // connectio v chui truy vn cho n myCommand = new System.Data.SqlClient.SqlCommand( ); myCommand.Connection=myConnection; myCommand.CommandText = "Select * from Customers"; // to i tng DataAdapter vi i tng Command va // to trn, ng thi thc hin nh x bng d liu DataAdapter = new SqlDataAdapter( ); DataAdapter.SelectCommand= myCommand; DataAdapter.TableMappings.Add("Table","Customers"); // y d liu vo DataSet DataAdapter.Fill(myDataSet); // gn d liu vo li dataGrid1.DataSource = myDataSet.Tables["Customers"].DefaultView;

public override void Dispose() { base.Dispose(); components.Dispose(); } private void InitializeComponent( ) { this.components = new System.ComponentModel.Container(); this.dataGrid1 = new System.Windows.Forms.DataGrid(); dataGrid1.BeginInit(); dataGrid1.Location = new System.Drawing.Point(24, 32); dataGrid1.Size = new System.Drawing.Size(480, 408); dataGrid1.DataMember = ""; dataGrid1.TabIndex = 0;

156

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

this.Text = "ADOFrm1"; this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(536, 501); this.Controls.Add(this.dataGrid1); dataGrid1.EndInit( ); } public static void Main(string[] args) { Application.Run(new ADOForm1()); }

} }

Giao din ca v d ny cng tng t nh cc v d trn.

14.8.3 Kt hp gia nhiu bng


Cc v d trn ch n thun ly d liu t trong mt bng. v d ny ta s tm hiu v cch ly d liu trn hai bng. Trong c s d liu ca ta, mt khch hng c th c nhiu ha n khc nhau, v th ta s c quan h mt nhiu gia bng khch hng (Customers)v bng ha n (Orders). Bng Orders s cha thuc tnh CustomersId ca bng Customers, thuc tnh ny ng vai tr l kha chnh i bng Customers v kha ngoi i vi bng Orders. ng dng ca ta s hin th d liu ca hai bng Customers v Orders trn cng mt li v th hin quan h mt nhiu ca hai bng ngay trn li. lm c iu ny ta ch cn dng chung mt i tng Connetion, hai i tng tng SqlDataAdapter v hai i tng SqlCommand. Sau khi to i tng SqlDataAdapter cho bng Customers tng t nh v d trn, ta tin to tip i tng SqlDataAdapter cho bng Orders :
myCommand2 = new System.Data.SqlClient.SqlCommand(); DataAdapter2 = new System.Data.SqlClient.SqlDataAdapter(); myCommand2.Connection = myConnection; myCommand2.CommandText = "SELECT * FROM Orders";

Lu l y i tng DataAdapter2 c th dng chung i tng Connection trn, nhng i tng Command th khc. Sau gn i tng Command2 cho DataAdapter2, nh x bng d liu v y d liu vo DataSet trn.
DataAdapter2.SelectCommand = myCommand2; DataAdapter2.TableMappings.Add ("Table", "Orders"); DataAdapter2.Fill(myDataSet);

Ti thi im ny, ta c mt i tng DataSet nhng cha hai bng d liu : Customers v Orders. Do ta cn th hin c quan h ca hai bng ngay trn iu khin li, cho nn ta cn phi nh ngha quan h ny cho i tng DataSet ca chng ta. Nu khng lm iu ny th i tng DataSet s b qua quan h gia 2 bng ny. Do ta cn khai bo thm i tng DataRelation :
System.Data.DataRelation dataRelation;

157

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

Do mi bng Customers v Orders u c cha mt thuc tnh CustomersId, nn ta cng cn khi bo thm hai i tng DataColumn tng ng vi hai thuc tnh ny.
System.Data.DataColumn dataColumn1; System.Data.DataColumn dataColumn2;

Mi mt DataColumn s gi gi tr ca mt ct trong bng ca i tng DataSet :


dataColumn1 = myDataSet.Tables["Customers"].Columns["CustomerID"]; dataColumn2 = myDataSet.Tables["Orders"].Columns["CustomerID"];

Ta tin hnh to quan h cho hai bng bng cch gi hm khi to ca i tng DataRelation, truyn vo cho n tn quan h v hai ct cn to quan h :
dataRelation = new System.Data.DataRelation("CustomersToOrders", dataColumn1, dataColumn2);

Sau khi to c i tng DataRelation, ta thm vo DataSet ca ta. Sau ta cn to mt i tng qun l khung nhn DataViewManager cho DataSet, i tng khung nhn ny s c gn cho li iu khin hin th:
myDataSet.Relations.Add(dataRelation); DataViewManager DataSetView = myDataSet.DefaultViewManager; dataGrid1.DataSource = DataSetView;

Do iu khin li phi hin th quan h ca hai bng d liu, nn ta phi ch cho n bit l bng no s l bng cha. y bng cha l bng Customers :
dataGrid1.DataMember= "Customers";

Sau y l m hon chnh ca ton b ng dng :


using using using using using using using System; System.Drawing; System.Collections; System.ComponentModel; System.Windows.Forms; System.Data; System.Data.SqlClient;

namespace ProgrammingCSharpWindows.Form { public class ADOForm1 : System.Windows.Forms.Form { private System.ComponentModel.Container components; private System.Windows.Forms.DataGrid dataGrid1; private System.Data.SqlClient.SqlConnection myConnection; private System.Data.DataSet myDataSet; private System.Data.SqlClient.SqlCommand myCommand; private System.Data.SqlClient.SqlCommand myCommand2; private System.Data.SqlClient.SqlDataAdapter DataAdapter; private System.Data.SqlClient.SqlDataAdapter DataAdapter2; public ADOForm1( ) { InitializeComponent( ); // to kt ni string connectionString = "server=Neptune; uid=sa;" + " pwd=oWenmEany; database=northwind";

158

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

myConnection = new SqlConnection(connectionString); myConnection.Open( ); // to DataSet myDataSet = new System.Data.DataSet( ); // to i tng Command v DataSet cho bng Customers myCommand = new System.Data.SqlClient.SqlCommand( ); myCommand.Connection=myConnection; myCommand.CommandText = "Select * from Customers"; DataAdapter =new System.Data.SqlClient.SqlDataAdapter(); DataAdapter.SelectCommand= myCommand; DataAdapter.TableMappings.Add("Table","Customers"); DataAdapter.Fill(myDataSet); // to i tng Command v DataSet cho bng Orders myCommand2 = new System.Data.SqlClient.SqlCommand( ); DataAdapter2=new System.Data.SqlClient.SqlDataAdapter(); myCommand2.Connection = myConnection; myCommand2.CommandText = "SELECT * FROM Orders"; DataAdapter2.SelectCommand = myCommand2; DataAdapter2.TableMappings.Add ("Table", "Orders"); DataAdapter2.Fill(myDataSet); // thit lp quan h gia 2 bng System.Data.DataRelation dataRelation; System.Data.DataColumn dataColumn1; System.Data.DataColumn dataColumn2; dataColumn1 = myDataSet.Tables["Customers"].Columns["CustomerID"]; dataColumn2 = myDataSet.Tables["Orders"].Columns["CustomerID"]; dataRelation = new System.Data.DataRelation( "CustomersToOrders", dataColumn1, dataColumn2); // thm quan h trn vo DataSet myDataSet.Relations.Add(dataRelation); // t khung nhn v bng hin th trc cho li DataViewManager DataSetView = myDataSet.DefaultViewManager; dataGrid1.DataSource = DataSetView; dataGrid1.DataMember= "Customers";

public override void Dispose( ) { base.Dispose( ); components.Dispose( ); } private void InitializeComponent( ) { this.components = new System.ComponentModel.Container(); this.dataGrid1 = new System.Windows.Forms.DataGrid(); dataGrid1.BeginInit( ); dataGrid1.Location = new System.Drawing.Point(24, 32); dataGrid1.Size = new System.Drawing.Size(480, 408);

159

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

dataGrid1.DataMember = ""; dataGrid1.TabIndex = 0; this.Text = "ADOFrm1"; this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size (536, 501); this.Controls.Add (this.dataGrid1); dataGrid1.EndInit ( ); } public static void Main(string[] args) { Application.Run(new ADOForm1( )); }

} }

Khi chy ng dng s c giao din nhu sau :


Hnh 14-6 Quan h mt nhiu gia hai bng Customers v Orders

160

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 14-7 Danh sch cc ha n tng ng vi khch hng c chn

14.9 Thay i cc bn ghi ca c s d liu


Ti lc ny, chng ta hc cch ly d liu t c s d liu sau hin th chng ra mn hnh da vo cc iu khin c hay khng kt buc d liu. Phn ny chng ta s tm hiu cch cp nht vo c s d liu. Cc thao tc trn c s d liu nh : Thm, xa v sa mt dng trong cc bng d liu. Sau y l lung cng vic hon chnh khi ta c mt thao tc cp nht c s d liu : 1. y d liu ca bng vo DataSet bng cu truy vn SQL hay gi th tc t c s d liu 2. Hin th d liu trong cc bng c trong DataSet bng cch kt buc hay duyt qua cc dng d liu. 3. Hiu chnh d liu trong cc bng DataTable vi cc thao tc thm, xa hay sa trn dng DataRow. 4. Gi phng thc GetChanges() ly v mt DataSet khc cha tt c cc thay i trn d liu. 5. Kim tra li trn DataSet mi c to ny bng thuc tnh HasErrors. Nu c li th ta s tin hnh kim tra trn tng bng DataTable ca DataSet, khi gp mt bng c li th ta tip tc dng hm GetErrors() ly v cc dng DataRow c li, ng vi tng dng ta s dng thuc tnh RowError trn dng xc nh xem dng c li hay khng c th a ra x l thch hp. 6. Trn hai DataSet li thnh mt. 7. Gi phng thc Update() ca i tng DataAdapter vi i s truyn vo l DataSet va c trong thao tc trn trn cp nht cc thay i vo c s d liu.

161

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

8. Gi phng thc AcceptChanges() ca DataSet cp nht cc thay i vo DataSet ny hay phng thc RejectChanges() nu t chi cp nht thay i cho DataSet hin hnh. Vi lung cng vic trn, cho php ta c th kim sot tt c vic thay i trn c s d liu hay vic g li cng thun tin hn. Trong v d di y , ta s cho hin th d liu trong bng Customers ln mt ListBox, sau ta tin hnh cc thao tc thm, xa hay sa trn c s d liu. d hiu, ta gim bt mt s thao tc qun l ngoi l hay li, ch tp trung vo mc ch chnh ca ta. Giao din chnh ca ng dng sau khi hon chnh :
Hnh 14-8 Hiu chnh d liu trn bng Customers.

Trong Form ny, ta c mt ListBox lbCustomers lit k cc khch hng, mt Button btnUpdate cho vic cp nht d liu, mt Button Xa, ng vi nt thm mi ta c tm hp thoi TextBox nhn d liu g vo t ngi dng. ng thi ta c thm mt lblMessage hin th cc thng bo ng vi cc thao tc trn.

14.9.1 Truy cp v hin th d liu


Ta s to ra ba bin thnh vin : DataAdapter, DataSet v Command :
private SqlDataAdapter DataAdapter; private DataSet DataSet; private DataTable dataTable;

Vic khai bo cc bin thnh vin nh vy s gip ta c th dng li cho cc phng thc khc nhau. T khai bo chui kt ni v truy vn :
string connectionString = "server=localhost; uid=sa; pwd=; database=northwind"; string commandString = "Select * from Customers";

Cc chui c dng lm i s to i tng DataAdapter :


DataAdapter=new SqlDataAdapter(commandString,ConnectionString);

162

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

To ra i tng DataSet mi, sau y d liu t DataAdapter vo cho n:


DataSet = new DataSet(); DataAdapter.Fill(DataSet,"Customers");

hin th d liu, ta s gi hm PopulateDB() y d liu vo ListBox:


dataTable = DataSet.Tables[0]; lbCustomers.Items.Clear( ); foreach (DataRow dataRow in dataTable.Rows) { lbCustomers.Items.Add(dataRow["CompanyName"] + " (" + dataRow["ContactName"] + ")" ); }

14.9.2 Cp nht mt dng d liu


Khi ngi dng nhn Button Update (cp nht), ta s ly ch mc c chn trn ListBox, v ly ra dng d liu DataRow trong bng ng vi ch mc trn. Sau cp nht DataSet vi dng d liu mi ny nu sau khi kim tra thy chng khng c li no c. Chi tit v qu trnh thc hin cp nht : u tin ta s ly v dng d liu ngi dng mun thay i t i tng dataTable m ta khai bo lm bin thnh vin ngay t u :
DataRow targetRow = dataTable.Rows[lbCustomers.SelectedIndex];

Hin th chui thng bo cp nht dng d liu cho ngi dng bit. lm iu ny ta s gi phng thc tnh DoEvents() ca i tng Application, hm ny s gip sn mi li mn hnh vi thng ip hay cc thay i khc.
lblMessage.Text = "Updating " + targetRow["CompanyName"]; Application.DoEvents();

Gi hm BeginEdit() ca i tng DataRow, chuyn dng d liu sang ch hiu chnh ( Edit ) v EndEdit() kt thc ch hiu chnh dng.
targetRow.BeginEdit(); targetRow["CompanyName"] = txtCustomerName.Text; targetRow.EndEdit();

Ly v cc thay i trn i tng DataSet kim tra xem cc thay i c xy ra bt k li no khng. y ta s dng mt bin c c kiu true/false xc nh l c li l true, khng c li l false.Kim tra li bng cch dng hai vng lp tun t trn bng v dng ca DataSet mi ly v trn, ta dng thuc tnh HasErrors kim tra li trn bng, phng thc GetErrors() ly v cc dng c li trong bng.
DataSet DataSetChanged; DataSetChanged = DataSet.GetChanges(DataRowState.Modified); bool okayFlag = true; if (DataSetChanged.HasErrors) { okayFlag = false; string msg = "Error in row with customer ID "; foreach (DataTable theTable in DataSetChanged.Tables) { if (theTable.HasErrors)

163

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

DataRow[] errorRows = theTable.GetErrors( ); foreach (DataRow theRow in errorRows) msg = msg + theRow["CustomerID"];

} } lblMessage.Text = msg; }

Nu bin c okagFlag l true,th ta s trn DataSet ban u vi DataSet thay i thnh mt, sau cp nht DataSet sau khi trn ny vo c s d liu.
if (okayFlag) { DataSet.Merge(DataSetChanged); DataAdapter.Update(DataSet,"Customers");

Tip theo hin th cu lnh truy vn cho ngi dng bit, v cp nht nhng thay i cho DataSet u tin, ri hin th d liu mi ln i tng ListBox.
lblMessage.Text = DataAdapter.UpdateCommand.CommandText; Application.DoEvents( ); DataSet.AcceptChanges( ); PopulateLB( );

Nu c okayFlag l false, c ngha l c li trong qu trnh hiu chnh d liu, ta s t chi cc thay i trn DataSet.
else DataSet.RejectChanges( );

14.9.3 Xa mt dng d liu


M thc thi ca s kin xa th n gin hn mt cht, ta nhn v dng cn xa :
DataRow targetRow = dataTable.Rows[lbCustomers.SelectedIndex];

Gi li dng cn xa dng lm thng ip hin th cho ngi dng bit trc khi xa dng ny khi c s d liu.
string msg = targetRow["CompanyName"] + " deleted. ";,

Bt u thc hin xa trn bng d liu, cp nht thay i vo DataSet v cp nht lun vo c s d liu :
dataTable.Rows[lbCustomers.SelectedIndex].Delete( ); DataSet.AcceptChanges( ); DataAdapter.Update(DataSet,"Customers");

Khi gi hm AccceptChanges() cp nht thay i cho DataSet th n s ln lt gi hm ny cho cc DataTable, sau cho cc DataRow cp nht chng. Ta cng cn ch khi gi hm xa trn bng Customers, dng d liu DataRow ca khch hng ny ch c xa nu n khng vi phm rng buc trn cc bng khc, y khch hng ch c xa nu nu khch hng khng c mt ha n no trn bng Orders. Nu c ta phi tin hnh xa trn bng ha n trc, sau mi xa trn bng Customers.

164

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

14.9.4 To mt dng d liu mi


Sau khi ngi dng cung cp cc thng tin v khch hng cn to mi v nhn Button to mi ( New ), ta s vit m thc thi trong hm bt s kin nhn nt to mi ny. u tin ta s to ra mt dng mi trn i tng DataTable, sau gn d liu trn cc TextBox cho cc ct ca dng mi ny :
DataRow newRow = dataTable.NewRow( ); newRow["CustomerID"] = txtCompanyID.Text; newRow["CompanyName"] = txtCompanyName.Text; newRow["ContactName"] = txtContactName.Text; newRow["ContactTitle"] = txtContactTitle.Text; newRow["Address"] = txtAddress.Text; newRow["City"] = txtCity.Text; newRow["PostalCode"] = txtZip.Text; newRow["Phone"] = txtPhone.Text;

Thm dng mi vi d liu vo bng DataTable, cp nht vo c s d liu, hin th cu truy vn, cp nht DataSet, hin th d liu mi ln hp ListBox. Lm trng cc iu khin TextBox bng hm thnh vin ClearFields().
dataTable.Rows.Add(newRow); DataAdapter.Update(DataSet,"Customers"); lblMessage.Text = DataAdapter.UpdateCommand.CommandText; Application.DoEvents( ); DataSet.AcceptChanges( ); PopulateLB( ); ClearFields( );

hiu r hon chnh ng, ta s xem m hon chnh ca ton ng dng :


using using using using using using using System; System.Drawing; System.Collections; System.ComponentModel; System.Windows.Forms; System.Data; System.Data.SqlClient;

namespace ProgrammingCSharpWindows.Form { public class ADOForm1 : System.Windows.Forms.Form { private System.ComponentModel.Container components; private System.Windows.Forms.Label label9; private System.Windows.Forms.TextBox txtPhone; private System.Windows.Forms.Label label8; private System.Windows.Forms.TextBox txtContactTitle; private System.Windows.Forms.Label label7; private System.Windows.Forms.TextBox txtZip; private System.Windows.Forms.Label label6; private System.Windows.Forms.TextBox txtCity; private System.Windows.Forms.Label label5; private System.Windows.Forms.TextBox txtAddress; private System.Windows.Forms.Label label4; private System.Windows.Forms.TextBox txtContactName; private System.Windows.Forms.Label label3; private System.Windows.Forms.TextBox txtCompanyName;

165

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

private private private private private private private private private private

System.Windows.Forms.Label label2; System.Windows.Forms.TextBox txtCompanyID; System.Windows.Forms.Label label1; System.Windows.Forms.Button btnNew; System.Windows.Forms.TextBox txtCustomerName; System.Windows.Forms.Button btnUpdate; System.Windows.Forms.Label lblMessage; System.Windows.Forms.Button btnDelete; System.Windows.Forms.ListBox lbCustomers; SqlDataAdapter DataAdapter;

// bit thnh vin DataSet v dataTable cho php ta s // dng trn nhiu hm khc nhau private DataSet DataSet; private DataTable dataTable; public ADOForm1( ) { InitializeComponent( ); string connectionString = "server=Neptune; uid=sa;" + " pwd=oWenmEany; database=northwind"; string commandString = "Select * from Customers"; DataAdapter = new SqlDataAdapter(commandString, connectionString); DataSet = new DataSet( ); DataAdapter.Fill(DataSet,"Customers"); PopulateLB( ); } // y d liu vo iu khin ListBox private void PopulateLB( ) { dataTable = DataSet.Tables[0]; lbCustomers.Items.Clear( ); foreach (DataRow dataRow in dataTable.Rows) { lbCustomers.Items.Add( dataRow["CompanyName"] + " (" + dataRow["ContactName"] + ")" ); } } public override void Dispose( ) { base.Dispose( ); components.Dispose( ); } private void InitializeComponent( ) { this.components = new System.ComponentModel.Container(); this.txtCustomerName=new System.Windows.Forms.TextBox(); this.txtCity = new System.Windows.Forms.TextBox(); this.txtCompanyID = new System.Windows.Forms.TextBox(); this.lblMessage = new System.Windows.Forms.Label(); this.btnUpdate = new System.Windows.Forms.Button(); this.txtContactName= new System.Windows.Forms.TextBox(); this.txtZip = new System.Windows.Forms.TextBox(); this.btnDelete = new System.Windows.Forms.Button();

166

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

this.txtContactTitle=new System.Windows.Forms.TextBox(); this.txtAddress = new System.Windows.Forms.TextBox(); this.txtCompanyName=new System.Windows.Forms.TextBox( ); this.label5 = new System.Windows.Forms.Label( ); this.label6 = new System.Windows.Forms.Label( ); this.label7 = new System.Windows.Forms.Label( ); this.label8 = new System.Windows.Forms.Label( ); this.label9 = new System.Windows.Forms.Label( ); this.label4 = new System.Windows.Forms.Label( ); this.lbCustomers = new System.Windows.Forms.ListBox( ); this.txtPhone = new System.Windows.Forms.TextBox( ); this.btnNew = new System.Windows.Forms.Button( ); this.label1 = new System.Windows.Forms.Label( ); this.label2 = new System.Windows.Forms.Label( ); this.label3 = new System.Windows.Forms.Label( ); txtCustomerName.Location = new System.Drawing.Point(256, 120); txtCustomerName.TabIndex = 4; txtCustomerName.Size = new System.Drawing.Size(160, 20); txtCity.Location = new System.Drawing.Point(384, 245); txtCity.TabIndex = 15; txtCity.Size = new System.Drawing.Size (160, 20); txtCompanyID.Location = new System.Drawing.Point (136, 216); txtCompanyID.TabIndex = 7; txtCompanyID.Size = new System.Drawing.Size (160, 20); lblMessage.Location = new System.Drawing.Point(32, 368); lblMessage.Text = "Press New, Update or Delete"; lblMessage.Size = new System.Drawing.Size (416, 48); lblMessage.TabIndex = 1; btnUpdate.Location = new System.Drawing.Point (32, 120); btnUpdate.Size = new System.Drawing.Size (75, 23); btnUpdate.TabIndex = 0; btnUpdate.Text = "Update"; btnUpdate.Click += new System.EventHandler (this.btnUpdate_Click); txtContactName.Location = new System.Drawing.Point(136, 274); txtContactName.TabIndex = 11; txtContactName.Size = new System.Drawing.Size (160, 20); txtZip.Location = new System.Drawing.Point (384, 274); txtZip.TabIndex = 17; txtZip.Size = new System.Drawing.Size (160, 20); btnDelete.Location = new System.Drawing.Point(472, 120); btnDelete.Size = new System.Drawing.Size(75, 23); btnDelete.TabIndex = 2; btnDelete.Text = "Delete"; btnDelete.Click += new System.EventHandler (this.btnDelete_Click); txtContactTitle.Location = new System.Drawing.Point(136, 303); txtContactTitle.TabIndex = 19; txtContactTitle.Size = new System.Drawing.Size(160, 20); txtAddress.Location = new System.Drawing.Point(384, 216); txtAddress.TabIndex = 13; txtAddress.Size = new System.Drawing.Size (160, 20); txtCompanyName.Location= new System.Drawing.Point (136, 245); txtCompanyName.TabIndex = 9;

167

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

txtCompanyName.Size = new System.Drawing.Size (160, 20); label5.Location = new System.Drawing.Point (320, 252); label5.Text = "City"; label5.Size = new System.Drawing.Size (48, 16); label5.TabIndex = 14; label6.Location = new System.Drawing.Point (320, 284); label6.Text = "Zip"; label6.Size = new System.Drawing.Size (40, 16); label6.TabIndex = 16; label7.Location = new System.Drawing.Point (40, 312); label7.Text = "Contact Title"; label7.Size = new System.Drawing.Size (88, 16); label7.TabIndex = 18; label8.Location = new System.Drawing.Point (320, 312); label8.Text = "Phone"; label8.Size = new System.Drawing.Size (56, 16); label8.TabIndex = 20; label9.Location = new System.Drawing.Point (120, 120); label9.Text = "New Customer Name:"; label9.Size = new System.Drawing.Size (120, 24); label9.TabIndex = 22; label4.Location = new System.Drawing.Point (320, 224); label4.Text = "Address"; label4.Size = new System.Drawing.Size (56, 16); label4.TabIndex = 12; lbCustomers.Location = new System.Drawing.Point(32, 16); lbCustomers.Size = new System.Drawing.Size (512, 95); lbCustomers.TabIndex = 3; txtPhone.Location = new System.Drawing.Point (384, 303); txtPhone.TabIndex = 21; txtPhone.Size = new System.Drawing.Size (160, 20); btnNew.Location = new System.Drawing.Point (472, 336); btnNew.Size = new System.Drawing.Size (75, 23); btnNew.TabIndex = 5; btnNew.Text = "New"; btnNew.Click += new System.EventHandler(this.btnNew_Click); label1.Location = new System.Drawing.Point (40, 224); label1.Text = "Company ID"; label1.Size = new System.Drawing.Size (88, 16); label1.TabIndex = 6; label2.Location = new System.Drawing.Point (40, 252); label2.Text = "Company Name"; label2.Size = new System.Drawing.Size (88, 16); label2.TabIndex = 8; label3.Location = new System.Drawing.Point (40, 284); label3.Text = "Contact Name"; label3.Size = new System.Drawing.Size (88, 16); label3.TabIndex = 10; this.Text = "Customers Update Form"; this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size (584, 421); this.Controls.Add (this.label9); this.Controls.Add (this.txtPhone); this.Controls.Add (this.label8); this.Controls.Add (this.txtContactTitle); this.Controls.Add (this.label7); this.Controls.Add (this.txtZip); this.Controls.Add (this.label6);

168

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add this.Controls.Add

(this.txtCity); (this.label5); (this.txtAddress); (this.label4); (this.txtContactName); (this.label3); (this.txtCompanyName); (this.label2); (this.txtCompanyID); (this.label1); (this.btnNew); (this.txtCustomerName); (this.btnUpdate); (this.lblMessage); (this.btnDelete); (this.lbCustomers);

// Qun l s kin nhn nt to mi (New) protected void btnNew_Click( object sender, System.EventArgs e) { // to mt dng mi DataRow newRow = dataTable.NewRow( ); newRow["CustomerID"] = txtCompanyID.Text; newRow["CompanyName"] = txtCompanyName.Text; newRow["ContactName"] = txtContactName.Text; newRow["ContactTitle"] = txtContactTitle.Text; newRow["Address"] = txtAddress.Text; newRow["City"] = txtCity.Text; newRow["PostalCode"] = txtZip.Text; newRow["Phone"] = txtPhone.Text; // thm mt dng mi vo bng dataTable.Rows.Add(newRow); // cp nht vo c s d liu DataAdapter.Update(DataSet,"Customers"); // thng bo cho ngi dng bit cu truy vn thay i lblMessage.Text = DataAdapter.UpdateCommand.CommandText; Application.DoEvents( ); DataSet.AcceptChanges( ); // hin th li d liu cho iu khin ListBox PopulateLB( ); // Xo trng cc TextBox ClearFields( );

// Xa trng cc TextBox private void ClearFields( ) { txtCompanyID.Text = ""; txtCompanyName.Text = ""; txtContactName.Text = ""; txtContactTitle.Text = ""; txtAddress.Text = "";

169

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

txtCity.Text = ""; txtZip.Text = ""; txtPhone.Text = ""; } // qun l s kin nht nt chn cp nht (Update) protected void btnUpdate_Click( object sender, EventArgs e) { // ly v dng c chn trn ListBox DataRow targetRow = dataTable.Rows[lbCustomers.SelectedIndex]; // thng bo cho ngi bit dng cp nht lblMessage.Text = "Updating " + targetRow["CompanyName"]; Application.DoEvents( ); // hiu chnh dng targetRow.BeginEdit( ); targetRow["CompanyName"] = txtCustomerName.Text; targetRow.EndEdit( ); // ly v cc dng thay i DataSet DataSetChanged = DataSet.GetChanges(DataRowState.Modified); // m bo khng c dng no c li bool okayFlag = true; if (DataSetChanged.HasErrors) { okayFlag = false; string msg = "Error in row with customer ID "; // kim tra li trn tng bng foreach (DataTable theTable in DataSetChanged.Tables) { // nu bng c li th tm li trn dng c th if (theTable.HasErrors) { // ly cc dng c li DataRow[] errorRows = theTable.GetErrors( ); // duyt qua tng dng c li thng bo. foreach (DataRow theRow in errorRows) { msg = msg + theRow["CustomerID"]; }

} } lblMessage.Text = msg; }

// nu khng c li if (okayFlag) { // trn cc thay i trong 2 DataSet thnh mt DataSet.Merge(DataSetChanged); // cp nht c s d liu

170

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

DataAdapter.Update(DataSet,"Customers"); // thng bo cu truy vn cho ngi dng lblMessage.Text = DataAdapter.UpdateCommand.CommandText; Application.DoEvents( ); // cp nht DataSet v // hin th d liu mi cho ListBox DataSet.AcceptChanges( ); PopulateLB( ); } else // nu c li DataSet.RejectChanges( );

// qun l s kin xa protected void btnDelete_Click( object sender, EventArgs e) { // ly v dng c chn trn ListBox DataRow targetRow = dataTable.Rows[lbCustomers.SelectedIndex]; // chun b thng bo cho ngi dng string msg = targetRow["CompanyName"] + " deleted. "; // xa dng c chn dataTable.Rows[lbCustomers.SelectedIndex].Delete( ); // cp nht thay i cho DataSet DataSet.AcceptChanges( ); // cp nht c s d liu DataAdapter.Update(DataSet,"Customers"); // hin th li ListBox vi d liu thay i PopulateLB( ); // thng bo cho ngi dng bit lblMessage.Text = msg; Application.DoEvents( ); } public static void Main(string[] args) { Application.Run(new ADOForm1( )); } } }

Giao din thc thi ca ng dng :

171

Truy cp d liu vi ADO.NET

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 14-9 Cung cp d liu cho cc TextBox thm mi mt dng

Hnh 14-10 Sau khi thm mt dng vo cui ListBox

172

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

Chng 15 ng dng Web vi Web Forms


Cng ngh .NET c dng xy dng cc ng dng Web l ASP.NET, n cung cp hai vng tn kh mnh v y phc v cho vic to cc ng dng Web l System.Web v System.Web.UI. Trong phn ny chng ta s tp trung ch yu vo vic dng ngn ng C# lp trnh vi ASP.NET. B cng c Web Form cng c thit k h tr m hnh pht trin nhanh (RAD). Vi Web Form, ta c th ko th cc iu khin trn Form thit k cng nh c th vit m trc tip trong tp tin .aspx hay .aspx.cs. ng dng Web s c trin khai trn my ch, cn ngi dng s tng tc vi ng dng thng qua trnh duyt. .NET cn h tr ta b cung c to ra cc ng dng tun theo m hnh n - lp (tng - n tier), gip ta c th qun l c ng dng c d dng hn v nh th nng cao hiu sut pht trin phn mm.

1.1 Tm hiu v Web Forms


Web Form l b cng c cho php thc thi cc ng dng m cc trang Web do n to ng ra c phn phi n trnh duyt thng qua mng Internet. Vi Web Forms, ta to ra cc trang HTML vi ni dung tnh v dng m C# chy trn Server x l d liu tnh ny ri to ra trang Web ng, gi trang ny v trnh duyt di m HTML chun. Web Forms c thit chy trn bt k trnh duyt no, trang HTML gi v s c gt gia sao cho thch hp vi phin bn ca trnh duyt. Ngoi dng C#, ta cng c th dng ngn ng VB.NET to ra cc ng dng Web tng t. Web Forms chia giao din ngi dng thnh hai phn : phn thy trc quan ( hay UI ) v phn trang m pha sau ca UI. Quan im ny th tng t vi Windows Form, nhng vi Web Forms, hai phn ny nm trn hai tp tin ring bit. Phn giao din UI c lu tr trong tp tin c phn m rng l .aspx, cn m c lu tr trong tp tin c phn m rng l .aspx.cs. Vi mi trng lm vic c cung cp bi b Visual Studio .NET, to cc ng dng Web n gin ch l m Form mi, ko th v vit m qun l s kin thch hp. Web Forms c tch hp thm mt lot cc iu khin thc thi trn Server, c th t kim tra s hp l ca d liu ngay trn my khch m ta khng phi vit m m t g c.

173

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

15.1 Cc s kin ca Web Forms


Mt s kin (Events) c to ra khi ngi dng nhn chn mt Button, chn mt mc trong ListBox hay thc hin mt thao tc no trn UI. Cc s kin cng c th c pht sinh h thng bt u hay kt thc. Phng thc p ng s kin gi l trnh qun l s kin, cc trnh qun l s kin ny c vit bng m C# trong trang m (code-behind) v kt hp vi cc thuc tnh ca cc iu khin thuc trang. Trnh qun l s kin l mt Delegate, phng thc ny s tr v kiu void, v c hai i s. i s u tin l th hin ca i tng pht sinh ra s kin, i s th hai l i tng EventArg hay mt i tng khc c dn xut t i tng EventArgs. Cc s kin ny c qun l trn Server.

15.1.1 S kin PostBack v Non-PostBack


PostBack l s kin s khin Form c gi v Server ngay lp tc, chng hn s kin trnh mt Form vi phng thc Post. i lp vi PostBack l NonPostBack, s kin ny khng gi Form nn Server m n lu s kin trn vng nh Cache cho ti khi c mt s kin PostBack na xy ra. Khi mt iu khin c thuc tnh AutoPostBack l true th s kin PostBack s c tc dng trn iu khin : mc nhin thuc tnh AutoPostBach ca iu khin DropDownList l false,ta phi t li l true th s kin chn mt mc khc trong DropDownList ny mi c tc dng.

15.1.2 Trng thi ca ng dng Web (State)


Trng thi ca ng dng Web l gi tr hin hnh ca cc iu khin v mi bin trong phin lm vic hin hnh ca ngi dng. Web l mi trng khng trng thi, ngha l mi s kin Post ln Server u lm mt i mi thng tin v phin lm vic trc . Tuy nhin ASP.NET cung cp c ch h tr vic duy tr trng thi v phin ca ngi dng. Bt k trang no khi c gi ln my ch Server u c my ch tng hp thng tin v ti to li sau mi gi xung trnh duyt cho my khch. ASP.NET cung cp mt c ch gip duy tr trng thi ca cc iu khin pha my ch ( Server Control ) mt cch t ng. V th nu ta cung cp cho ngi dng mt danh sch d liu ListBox, v ngi dng thc hin vic chn la trn ListBox ny, s kin chn la ny s vn c duy tr sau khi trang c gi ln my ch v gi v cho trnh duyt cho my khch.

15.1.3 Chu trnh sng ca mt Web-Form


Khi c yu cu mt trang Web trn my ch Web s to ra mt chui cc s kin my ch , t lc bt u cho n lc kt thc mt yu cu s hnh thnh mt chu trnh sng ( Life-Cycle ) cho trang Web v cc thnh phn thuc n. Khi mt trang

174

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

Web c yu cu, my ch s tin hnh m ( Load ) n v khi hon tt yu cu my ch s ng trang ny li, kt xut ca yu cu ny l mt trang HTML tng ng s c gi v cho trnh duyt. Di y s lit k mt s s kin, ta c th bt cc s kin x l thch hp hay b qua ASP.NET x l mc nh. Khi to (Initialize) L s kin u tin trong chu trnh sng ca trang, ta c th khi bt k cc thng s cho trang hay cc iu khin thuc trang. M trng thi vng quan st (Load View State) c gi khi thuc tnh ViewState ca iu khin c cng b hay g. Cc gi tr trong ViewState s c lu tr trong mt bin n ( Hidden Field ), ta c th ly gi tr ny thng qua hm LoadViewState() hay ly trc tip. Kt thc (Dispose) Ta c th dng s kin ny gii phng bt k ti nguyn nguyn no : b nh hay hy b cc kt ni n c s d liu.

15.2 Hin th chui ln trang


u tin ta cn chy Visual Studio .NET, sau to mt d n mi kiu Web Application, ngn ng chn l C# v ng dng s c tn l ProgrammingCSharpWeb. Url mc nhin ca ng dng s c tn l http://localhost/ ProgrammingCSharpWeb.
Hnh 15-1 Ca s to ng dng Web mi

Visual Studio .NET s t hu ht cc tp tin n to ra cho ng dng trong th mc Web mc nh trn my ngi dng, v d : D:\Inetpub\wwwroot\ProgrammingCSharpWeb. Trong .NET, mt gii php

175

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

(Solution) c mt hay hiu d n (Project), mi d n s to ra mt th vin lin kt ng (DLL) hay tp tin thc thi (EXE). c th chy c ng dng Web Form, ta cn phi ci t IIS v FrontPage Server Extension trn my tnh. Khi ng dng Web Form c to, .NET to sn mt s tp tin v mt trang Web c tn mc nh l WebForm1.aspx ch cha m HTML v WebForm1.cs cha m qun l trang. Trang m .cs khng nm trong ca s Solution Explorer, hin th n ta chn Project\Show All Files, ta ch cn nhn p chut tri trn trang Web l ca s son tho m (Editor) s hin nn, cho php ta vit m qun l trang. chuyn t ca s thit k ko th sang ca s m HTML ca trang, ta chn hai Tab gc bn tri pha di mn hnh. t tn li cho trang Web bng cch nhn chut phi ln trang v chn mc Rename i tn trang thnh HelloWeb.aspx, .NET cng s t ng i tn trang m ca trang thnh HelloWeb.cs. NET cng to ra mt s m HTML cho trang :
Hnh 15-2

.NET pht sinh ra mt s m ASP.NET :


<%@ Page language="c#" Codebehind="HelloWeb.cs" AutoEventWireup="false" Inherits="ProgrammingCSharpWeb.WebForm1" %>

Thuc tnh language ch ra ngn ng lp trnh c dng trong trang m qun l trang, y l C#. Codebehide xc nh trang m qun l c tn HelloWeb.cs v thuc tnh Inherits ch trang Web c tha k t lp WebForm1 c vit trong HelloWeb.cs :
public class WebForm1 : System.Web.UI.Page

Ta thy trang ny c tha k t lp System.Web.UI.Page, lp ny do ASP.NET cung cp, xc nh cc thuc tnh, phng thc v cc s kin chung cho cc trang pha my ch. M HTML pht sinh nh dng thuc tnh ca Form :
<form id="Form1" method="post" runat="server">

176

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

Thuc tnh id lm nh danh cho Form, thuc tnh method c gi tr l POST ngha l Form s c gi ln my ch ngay lp tc khi nhn mt s kin do ngi dng pht ra ( nh s kin nhn nt ) v c IsPostBack trn my ch khi s c gi tr l true. Bin c ny c gi tr l false nu Form c trnh vi phng thc GET hay ln u tin trang c gi. Bt k iu khin no hay Form c thuc tnh runat=server th iu khin hay Form ny s c x l bi ASP.NET Framework trn my ch. Thuc tnh MS_POSITIONING = GridLayout trong th <Body>, cho bit cch b tr cc iu khin trn Form theo dng li, ngoi ra ta cn c th b tr cc iu khin tri li trn trang, bng cch gn thuc tnh MS_POSITIONING thnh FlowLayout. Hin gi Form ca ta l trng, hin th mt chui g ln mn hnh, ta g dng m sau trong th <body> :
Hello World! It is now <% = DateTime.Now.ToString( ) %>

Ging vi ASP, phn nm trong du <% %> c xem nh l m qun l cho trang, y l m C#. Du = ch ra mt gi tr nhn c t mt bin hay mt i tng no , ta cng c th vit m trn li nh sau vi cng chc nng :
Hello World! It is now <% Response.Write(DateTime.Now.ToString( )); %>

Thc thi trang ny ( Ctrl-F5 ), kt qu s hin trn trnh duyt nh sau :


Hnh 15-3 Hin th chui thi gian

thm cc iu khin cho trang, hoc l ta c th vit m trong ca s HTML hoc l ko th cc iu khin trn b cng ca Web Form vo ca s thit k trang. ASP.NET s t ng pht sinh ra kt qu t m HTML thnh cc iu khin cng nh t cc iu khin trn trang thit thnh m HTML tng ng. V d, ko hai RadioButton vo trang v gn cng mt gi tr no cho thuc tnh GroupName ca c hai iu khin, thuc tnh ny s lm cho cc nt chn loi tr ln nhau. M HTML ca trang trong th <Form> do ASP.NET pht sinh s nh sau :

177

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 15-4

Cc iu khin ca ASP.NET, c thm ch asp: pha trc tn ca iu khin , c thit k mang tnh hng i tng nhiu hn.
<asp:RadioButton> <asp:CheckBox> <asp:Button> <asp:TextBox rows="1"> <asp:TextBox rows="5">

Ngoi cc iu khin ca ASP.NET, cc iu khin HTML chun cng c ASP.NET h tr. Tuy nhin cc iu khin khng to s d c trong m ngun do tnh i tng trn chng khng r rng, cc iu khin HTML chun ng vi nm iu khin trn l :
<input type = "radio"> <input type="checkbox"> <input type="button"> <input type="text"> <textarea>

15.3 iu khin xc nhn hp


ASP.NET cung cp mt tp cc iu khin xc nhn hp l d liu nhp pha my ch cng nh di trnh duyt ca my khch. Tuy nhin vic xc nhn hp l di my khch ch l mt chn la, ta c th tt n i, nhng vic xc nhn hp l trn my ch thng qua cc iu khin ny l bt buc, nhm phng nga mt s trng hp d liu nhp l gi mo. Vic kim tra hp l ca m trn my ch l phng cc trng hp. Mt s loi xc nhn hp l : d liu khng c rng, tha mt nh dng d liu no Cc iu khin xc nhn hp l phi c gn lin vi mt iu khin nhn d liu HTML no , cc iu khin nhp c lit trong bng sau :
Bng 15-1 Cc iu khin nhp HTML dng xc nhn hp l
Cc iu khin nhp Thuc tnh xc nhn hp l

178

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

Cc iu khin nhp

Thuc tnh xc nhn hp l

ng vi mt iu khin nhp HTML, ta c th gn nhiu iu khin xc nhn hp l cho n, bng di y s lit k cc iu khin nhp hin c :
Bng 15-2 Cc iu khin xc nhn hp l
iu khin CompareValidator CustomValidator RangeValidator RegularExpressionvalidator Mc ch So snh cc gi tr ca hai iu khin xem c bng nhau hay khng Gi mt hm do ngi dng nh ngha thi hnh vic kim tra Kim tra xem mt mc c nm trong mt min cho hay khng Kim tra ngi dng c sa i mt mc ( m gi tr ca n khc vi mt gi tr ch nh ban u, ngm nh gi tr ban u l mt chui trng ) hay khng Thng bo s hp l trn cc iu khin

ValidationSummary

15.4 Mt s v d mu minh ha
Mt cch thun tin nht hc mt cng ngh mi chnh l da vo cc v d, v vy trong phn ny chng ta s kho st mt vi v d minh ha cho phn l thuyt ca chng ta. Nh ta bit, ta c th vit m qun l theo hai cch : hoc l vit trong tp tin .cs hoc l vit trc tip trong trang cha m HTML. y d tp trung vo cc v d ca chng ta, ta s vit m qun l trc tip trn trang HTML.

15.4.1 Kt buc d liu


15.4.1.1 Khng thng qua thuc tnh DataSource
ng dng ca chng ta n gin ch hin ln trang tn khch hng v s ha n bng cch dng hm DataBind(). Hm ny s kt buc d liu ca mi thuc tnh hay ca bt k i tng.
<html> <head> // m qun l C# s c vit trong th <script> ny

179

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

<script language="C#" runat="server"> // trang s gi hm ny u tin, ta s thc hin kt buc // trc tip trong hm ny void Page_Load(Object sender, EventArgs e) { Page.DataBind(); } // ly gi tr ca thuc tnh thng qua thuc tnh // get string custID{ get { return "ALFKI"; } } int orderCount{ get { return 11; } } </script> </head> <body> <h3><font face="Verdana"> Ket buoc khong dung DataSource </font></h3> <form runat=server> Khach hang: <b><%# custID %></b><br> So hoa don: <b><%# orderCount %></b> </form> </body> </html>

Hnh 15-5 Giao din ca v d

15.4.1.2 iu khin DataList vi DataSource


Trong v d ny, ta s dng thuc tnh DataSource ca iu khin <asp:DataList> kt buc d liu, ta s cung cp cho thuc tnh DataSource ny mt bng d liu gi, sau dng hm DataBinder.Eval() kt buc d liu trong DataSource theo mt nh dng ( Format ) thch hp mong mun. D liu s c hin th ln mn hnh di dng mt bng cc ha n sau khi ta gi hm DataBind().

180

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

//Khng gian tn cha cc i tng ca ADO.NET <%@ Import namespace="System.Data" %> <html> <head> <script language="C#" runat="server"> void Page_Load(Object sender, EventArgs e) { // nu trang c gi ln u tin if (!Page.IsPostBack) { // to ra mt bng d liu mi gm 4 ct , sau thm d // liu gi cho bng DataTable dt = new DataTable(); DataRow dr; // thm 4 ct DataColumn vo bng, mi ct c cc // kiu d liu ring dt.Columns.Add(new DataColumn("IntegerValue", typeof(Int32))); dt.Columns.Add(new DataColumn("StringValue", typeof(string))); dt.Columns.Add(new DataColumn("DateTimeValue", typeof(DateTime))); dt.Columns.Add(new DataColumn("BoolValue", typeof(bool))); // thm 9 dng d liu cho bng bng cch to ra // mt dng mi dng phng thc NewRow() ca i // tng DataTable, sau gn d liu gi cho // dng ny v thm dng d liu ny vo bng for (int i = 0; i < 9; i++) { dr = dt.NewRow(); dr[0] = i; dr[1] = "Item " + i.ToString(); dr[2] = DateTime.Now; dr[3] = (i % 2 != 0) ? true : false; dt.Rows.Add(dr); } // gn bng d liu cho thuc tnh DataSource ca iu // khin DataList, sau thc hin kt buc bng hm // DataBind() dataList1.DataSource = new DataView(dt); dataList1.DataBind(); } } </script> </head> <body> <h3><font face="Verdana">Ket buoc du lieu dung DataSource thong qua ham DataBind.Eval() </font></h3> <form runat=server> // iu khin // linh ng, // thch hp, trang <asp:DataList danh sch cho php ta kt buc d liu kh ta ch cn cung cp cho n mt DataSource sau gi hm DataBind() hin th d liu // ln id="dataList1" runat="server" RepeatColumns="3" Width="80%"

181

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

BorderColor="black" BorderWidth="1" GridLines="Both" CellPadding="4" CellSpacing="0"> // y l mt thuc tnh ca li, khi gi hm // DabaBind(), d liu trong DataSource s c trch ra // (nu l danh cc i tng th mi ln trch s ly ra // mt phn t kiu i tng , sau dng hm // DataBinder.Eval() gn gi tr, cn nu l mt bng // d liu th mi ln kt buc s ly ra mt dng d // liu, hm DataBind.Eval() s ly d liu ca tng // trng) kt buc ln trang. N s lp li thao tc // ny cho ti khi d liu c kt buc ht. <ItemTemplate> //ly d liu trn ct u tin kt buc Ngay hoa don: <%# DataBinder.Eval(Container.DataItem, "DateTimeValue", "{0:d}") %> //ly d liu trn ct th 2 So luong: <%# DataBinder.Eval(Container.DataItem, "IntegerValue", "{0:N2}") %> //ct th 3 Muc: <%# DataBinder.Eval(Container.DataItem, "StringValue") %> //ct th 4 Ngay hoa don: <asp:CheckBox id=chk1 Checked='<%# (bool)DataBinder.Eval(Container.DataItem, "BoolValue") %>' runat=server/><p> </ItemTemplate> </asp:Datalist> </form> </body> </html>

182

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 15-6 Giao din ca v d sau khi thc thi

15.4.1.3 Kt buc vi iu khin DataGrid


Trong v trc, ta tm hiu s qua v cch y d liu vo thuc tnh DataSource ca iu khin DataList thng qua hm kt buc DataBind().V d ny chng ta s kho st thm v cch kt buc trn iu khin li DataGrid v cch dng iu khin xc nhn hp l trn d liu. Khi ng dng chy s hin th mt bng d liu ln trang, ngi dng c th hiu chnh bt k mt dng no trn bng d liu bng cch nhn vo chui lnh hiu chnh ( Edit ) trn li, g vo cc d liu cn hiu chnh, khi mun hy b thao tc hiu chnh ta nhn chn chui b qua (Cancel). tp trung vo mc ch ca v d, chng ta s dng bng d liu gi, cch lm s tng t trn bng d liu ly ra t c s d liu. Sau y l m ca v d :
//khng gian tn cn thit truy cp n cc i tng ADO.NET <%@ Import Namespace="System.Data" %> <html> <script language="C#" runat="server"> //khai bo i tng bng v khung nhn DataTable Cart; DataView CartView; // ly d liu trong Session, nu khng c th ta s to ra mt // bng d liu khc

183

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

void Page_Load(Object sender, EventArgs e) { if (Session["DG6_ShoppingCart"] == null) Cart = new DataTable(); //bng s c 3 ct u Cart.Columns.Add(new Cart.Columns.Add(new Cart.Columns.Add(new

c kiu l chui DataColumn("Qty", typeof(string))); DataColumn("Item", typeof(string))); DataColumn("Price", typeof(string)));

//y nh danh ca bng vo phin lm vic hin thi Session["DG6_ShoppingCart"] = Cart; // to d liu mu cho bng for (int i=1; i<5; i++) { DataRow dr = Cart.NewRow(); dr[0] = ((int)(i%2)+1).ToString(); dr[1] = "Item " + i.ToString(); dr[2] = ((double)(1.23 * (i+1))).ToString(); Cart.Rows.Add(dr);

} }

else { //nu bng c sn trong Session, ta s ly ra dng Cart = (DataTable)Session["DG6_ShoppingCart"];

} // to ra khung nhn cho bng, sau sp xp khung nhn theo // ct Item CartView = new DataView(Cart); CartView.Sort = "Item"; // nu trang c gi ln u tin th kt buc d liu thng // qua hm BindGrid()ca ta if (!IsPostBack) { BindGrid(); } } // s kin nhn chui hiu chnh (Edit) trn li, ta s ly ch // mc ca dng cn hiu chnh thng qua i tng // DataGridCommandEventArgs, sau truyn ch mc ny cho iu // khin li ca ta v gi hm kt buc ca ta y d liu // ln li public void MyDataGrid_Edit(Object sender, DataGridCommandEventArgs e) { MyDataGrid.EditItemIndex = (int)e.Item.ItemIndex; BindGrid(); } //s kin nhn b qua trn li (Cancel) public void MyDataGrid_Cancel(Object sender, DataGridCommandEventArgs e) { MyDataGrid.EditItemIndex = -1; BindGrid(); } //sau khi hiu chnh d liu, ngi dng tin hnh cp nht public void MyDataGrid_Update(Object sender, DataGridCommandEventArgs e) {

184

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

// ly d liu trn TextBox string item = e.Item.Cells[1].Text; string qty = ((TextBox)e.Item.Cells[2].Controls[0]).Text; string price = ((TextBox)e.Item.Cells[3].Controls[0]).Text; // y, do chng ta dng d liu gi lu trn b nh chnh, // nu dng c s d liu th chng ta s tin hnh hiu chnh // trc tip trong c s d liu bng cc cu truy vn : // UPDATE, SELECT, DELETE //xa dng c CartView.RowFilter = "Item='"+item+"'"; if (CartView.Count > 0) { CartView.Delete(0); } CartView.RowFilter = ""; //to dng mi v thm vo bng DataRow dr = Cart.NewRow(); dr[0] = qty; dr[1] = item; dr[2] = price; Cart.Rows.Add(dr); MyDataGrid.EditItemIndex = -1; BindGrid();

//kt buc d liu thng qua thuc tnh DataSource ca li public void BindGrid() { MyDataGrid.DataSource = CartView; MyDataGrid.DataBind(); } </script> <body style="font: 10pt verdana"> <form runat="server"> <h3><font face="Verdana">Using an Edit Command Column in DataGrid</font></h3> //Khai bo cc thng s cho li, cc s kin trn li : OnEditCommand : khi ngi dng nhn chui hiu chnh (Edit) OnCancelCommand : nhn chui b qua hiu chnh (Cancel) OnUpdateCommand : nhn chui cp nht hiu chnh (Update) <asp:DataGrid id="MyDataGrid" runat="server" BorderColor="black" BorderWidth="1" CellPadding="3" Font-Name="Verdana" Font-Size="8pt" HeaderStyle-BackColor="#aaaadd" OnEditCommand="MyDataGrid_Edit" OnCancelCommand="MyDataGrid_Cancel" OnUpdateCommand="MyDataGrid_Update" AutoGenerateColumns="false" >

185

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

// cc thng s hiu chnh trn ct, y ta ch cho ngi // dng hiu chnh trn ct s lng v gi ha n <Columns> <asp:EditCommandColumn EditText="Edit" CancelText="Cancel" UpdateText="Update" ItemStyle-Wrap="false" HeaderText="Edit Command Column" HeaderStyle-Wrap="false" /> <asp:BoundColumn HeaderText="Item" ReadOnly="true" DataField="Item"/> <asp:BoundColumn HeaderText="Quantity" DataField="Qty"/> <asp:BoundColumn HeaderText="Price" DataField="Price"/> </Columns> </asp:DataGrid> </form> </body> </html>

Giao din ca v d khi chy :


Hnh 15-7 Hiu chnh trc tip trn li d liu

Sau khi ngi dng chn nt Edit trn li, mn hnh ng dng s nh sau :

186

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 15-8 Ngi dng sau khi nhn chui Edit

15.4.2 iu khin xc nhn hp l


Vic xc nhn hp l l cn thit vi cc ng dng cn yu cu nhp liu, vic a ra cc iu khin c kh nng xc nhn hp l trc tip di my khch ln trn my ch, y c th l mt tnh nng mi ca ASP.NET, ta khng cn phi vit m kim tra g c, m kim tra di trnh duyt ( chng hn nh Java Script ) s c ASP.NET t ng pht sinh. gn mt iu khin bt li vo mt iu khin cn bt li ta ch cn gn thuc tnh ControlToValidate ca iu khin bt li bng gi tr nh danh id ca iu khin cn bt li, v d : bt li iu khin TextBox khng c trng, ta vit m nh sau :
//iu khin cn bt li <ASP:TextBox id=TextBox1 runat=server /> //iu khin bt li hp nhp liu TextBox1 <asp:RequiredFieldValidator id="RequiredFieldValidator2" ControlToValidate="TextBox1" ErrorMessage="Card Number. " Display="Static" Width="100%" runat=server> * </asp:RequiredFieldValidator>

V d ca chng ta s cho hin th 2 hp thoi DropDownList, 2 nt chn RadioButton v mt hp thoi nhp TextBox, nu tn ti mc nhp no trng khi nhn nt xc nhn Validate, th cc iu khin xc nhn hp l s hin th li tng ng. Thng ip li c th c hin th theo ba cch khc nhau : lit k theo danh sch (List), lit k trn cng mt dng ( Single Paragraph ), lit k danh sch vi du chm trn u ( Bullet List ). M hon chnh ca v d c lit k nh sau :
// khng cho php iu khin xc nhn hp l di my khch bng // cch gn thuc tnh clienttarget = downlevel <%@ Page clienttarget=downlevel %>

187

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

<html> <head> <script language="C#" runat=server> // thay i ch hin th li bng cch chn 1 trong 3 mc // trong hp thoi ListBox void ListFormat_SelectedIndexChanged(Object Sender, EventArgs E ) { valSum.DisplayMode = (ValidationSummaryDisplayMode) ListFormat.SelectedIndex; } </script> </head> <body> <h3><font face="Verdana">V d v xc nhn iu khin hp l ValidationSummary</font></h3> <p> <form runat="server"> <table cellpadding=10><tr> <td> <table bgcolor="#eeeeee" cellpadding=10><tr><td colspan=3> <font face=Verdana size=2><b>Credit Card Information</b></font></td></tr> <tr> <td align=right> <font face=Verdana size=2>Card Type:</font></td> <td> // danh sch cc nt chn c bt li bi iu //khin xc nhn hp l RequireFieldValidator1 <ASP:RadioButtonList id=RadioButtonList1 RepeatLayout="Flow" runat=server> <asp:ListItem>MasterCard</asp:ListItem> <asp:ListItem>Visa</asp:ListItem> </ASP:RadioButtonList> </td> //iu khin xc nhn hp l cho cc nt chn //RadioButtonList1 <td align=middle rowspan=1> <asp:RequiredFieldValidator id="RequiredFieldValidator1" ControlToValidate="RadioButtonList1" ErrorMessage="Card Type. " Display="Static" InitialValue="" Width="100%" runat=server> * </asp:RequiredFieldValidator> </td></tr> <tr> <td align=right> <font face=Verdana size=2>Card Number:</font> </td> <td> <ASP:TextBox id=TextBox1 runat=server /> </td> <td>

188

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

//iu khin xc nhn hp l trn hp thoi //nhp liu TextBox, nu chui l trng khi //nhn nt Validate th s b bt li. <asp:RequiredFieldValidator id="RequiredFieldValidator2" ControlToValidate="TextBox1" ErrorMessage="Card Number. " Display="Static" Width="100%" runat=server> * </asp:RequiredFieldValidator> </td> </tr> <tr> <td align=right> <font face=Verdana size=2>Expiration Date:</font> </td> <td> //hp thoi DropDownList dng hin th //danh sch cc ngy, nu ngi dng chn //mc trng trong DropDownList ny th s b //iu khin xc nhn hp l //RequireFieldValidator3 bt li <ASP:DropDownList id=DropDownList1 runat=server> <asp:ListItem></asp:ListItem> <asp:ListItem >06/00</asp:ListItem> <asp:ListItem >07/00</asp:ListItem> <asp:ListItem >08/00</asp:ListItem> <asp:ListItem >09/00</asp:ListItem> <asp:ListItem >10/00</asp:ListItem> <asp:ListItem >11/00</asp:ListItem> <asp:ListItem >01/01</asp:ListItem> <asp:ListItem >02/01</asp:ListItem> <asp:ListItem >03/01</asp:ListItem> <asp:ListItem >04/01</asp:ListItem> <asp:ListItem >05/01</asp:ListItem> <asp:ListItem >06/01</asp:ListItem> <asp:ListItem >07/01</asp:ListItem> <asp:ListItem >08/01</asp:ListItem> <asp:ListItem >09/01</asp:ListItem> <asp:ListItem >10/01</asp:ListItem> <asp:ListItem >11/01</asp:ListItem> <asp:ListItem >12/01</asp:ListItem> </ASP:DropDownList> </td> <td> //iu khin xc nhn hp l trn //DropDownList1 hin th ngy ht hn, nu //ngi dng chn mt mc trng trn //DropDownList th iu khin ny s pht //sinh ra li <asp:RequiredFieldValidator id="RequiredFieldValidator3" ControlToValidate="DropDownList1" ErrorMessage="Expiration Date. " Display="Static" InitialValue="" Width="100%" runat=server> * </asp:RequiredFieldValidator></td> </tr> <tr>

189

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

<td> //nt nhn xc nh hp l <ASP:Button id=Button1 text="Validate" runat=server /></td></tr> </table> </td> <td valign=top> <table cellpadding=20><tr><td> //iu khin dng hin th cc li ln trang, //n s bt bt k li no c pht sinh bi cc //iu khin DropDownList hin th <asp:ValidationSummary ID="valSum" runat="server" HeaderText="You must enter a value in the following fields:" Font-Name="verdana" Font-Size="12" /> </td></tr></table> </td> </tr> </table> <font face="verdana" size="-1">Select the type of validation summary display you wish: </font> //Danh sch lit k 3 cch hin th li <asp:DropDownList id="ListFormat" AutoPostBack=true OnSelectedIndexChanged="ListFormat_SelectedIndexChanged" runat=server > <asp:ListItem>List</asp:ListItem> <asp:ListItem selected>Bulleted List</asp:ListItem> <asp:ListItem>Single Paragraph</asp:ListItem> </asp:DropDownList> </form> </body> </html>

Giao din ca v d khi chy :

190

ng dng Web vi Web Forms

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 15-9 Khi cha nhn nt xc nhn Validate

Hnh 15-10 Hin th li do b trng trn TextBox theo dng du chm trn Bullet

191

Cc dch v Web

Gvhd: Nguyn Tn Trn Minh Khang

Chng 16 Cc dch v Web


Hin nay, vn cn mt s hn ch ln trong cc ng dng Web. Ngi dng b gii hn ch thc hin c nhng ni dung c cu trc cho mt trang c th v xem d liu thng qua mt s giao din c th no c thit k trn my ch. Do ngi dng mun ly c thng tin c linh ng v hiu qu hn. Hn na, thay v ta hin th thng tin thng qua trnh duyt Web, ta mun chy mt phn mm trc tip trn my khch m c th trao i d liu trn my ch tu . Cng ngh .NET cho php xy dng cch dch v Web ( Web Services ) p ng c cc yu cu trn. tng chnh l : thay v lit k cc thng tin theo dng HTML, trang to sn mt lot cc lnh gi hm. Cc lnh gi hm ny c th trao i thng tin qua li gia cc h c s d liu trn my ch. Cc hm ny c th chp nhn cc tham s v c th tr v mt gi tr ty . Cc dch v Web vn da trn giao thc HTTP truyn d liu, ng thi n cn phi s dng thm mt loi giao thc phc v cho vic gi hm. Hin nay c hai giao thc c dng ch yu l : SOAP ( Simple Object Access Protocol ) v SDL ( Service Description Language, y l giao thc ring ca Microsoft ). C hai giao thc ny u c xy dng da trn XML, mc ch chung ca chng l gip nh ngha cc lnh gi hm, tham s v gi tr. Ngoi ra, Microsoft cng a ra thm mt tng mi v tp tin Discovery File, c phn m rng l .disco. Tp tin dng ny dng cung cp cc thng tin cho cc trnh duyt cc trnh duyt ny c th xc nh c cc trang trn cc my ch m c cha cc dch v Web. Sau y, ta s tm hiu mt v d nhm minh ha vic to ra mt dch v Web, ng vai tr l mt th vin cha mt tp cc hm tin ch. Trang Web ca chng ta s s dng cc hm ca dch v ny. Dch v Web ca chng s c tn MathService, n gin l nh ngha bn phng thc cng, tr, nhn, chia trn hai s thc bt k. Mi phng thc u nhn vo hai i s kiu s thc v tr v kt qu cng c kiu s thc. u tin ta cn to mt d n kiu Web Service bng cch chn : New Project\Visual C# Project\ASP.NET Web Service v t tn cho d n l MathService v i tn dch v thnh MathService.asmx. NET c to sn cho chng ta mt s tp tin nh : Service1.asmx : c trnh duyt yu cu, tng t vi tp tin .aspx. WebService1.cs: trang cha m C# qun l. DiscoFile1.disco: tp tin khm ph.

192

Cc dch v Web

Gvhd: Nguyn Tn Trn Minh Khang

Trong v d ny, chng ta s to ra mt Web Form mi v thit giao din nh sau :

Web Form s gi thc thi cc hm ca dch v Web.

D n ca ta s tha k namespace l System.Web.Services.WebService,ni cha cc thuc tnh v phng thc cn thit to dch v Web.
public class MathService : System.Web.Services.WebService

Trn mi phng thc ta cn khai bo thuc tnh [WebMethod], ch ra y l phng thc s c s dng cho dch v Web. M ca tp tin dch v s nh sau :
using using using using using using using System; System.Collections; System.ComponentModel; System.Data; System.Diagnostics; System.Web; System.Web.Services;

namespace MathService { public class MathService :System.Web.Services.WebService { public MathService() { InitializeComponent(); } #region Component Designer generated code private IContainer components = null; private void InitializeComponent() { } protected override void Dispose( bool disposing )

193

Cc dch v Web

Gvhd: Nguyn Tn Trn Minh Khang

if(disposing && components != null) { components.Dispose(); } base.Dispose(disposing);

#endregion //4 hm ton hc ca dch v Web, trn mi phng thc //ta cn khai bo thuc tnh [WebMethod] ch y l //phng thc dnh cho dch v Web. [WebMethod] public float Add(float a, float b) { return a + b; } [WebMethod] public float Subtract(float a, float b) { return a - b; } [WebMethod] public float Multiply(float a, float b) { return a * b; } [WebMethod] public float Divide(float a, float b) { if (b==0) return -1; return a / b; }

} }

By gi chng ta s vit m thc thi cho trang Web. Trang Web ca chng ta s gi cc hm ca dch v tng ng vi cc php cng, tr, nhn, chia . Sau y l m ca trang Web:
<%@ Import Namespace="MathService" %> <html> <script language="C#" runat="server"> float operand1 = 0; float operand2 = 0; public void Submit_Click(Object sender, EventArgs E) { try { operand1 = float.Parse(Operand1.Text); operand2 = float.Parse(Operand2.Text); } catch (Exception) { /* b qua li nu c */ }

194

Cc dch v Web

Gvhd: Nguyn Tn Trn Minh Khang

//to ra mt i tng dch v MathService c th truy cp n //cc hm thnh vin ca chng. MathService service = new MathService(); switch (((Control)sender).ID) { case "Add" : Result.Text = "<b>Result</b> = " + service.Add(operand1, operand2).ToString(); break; case "Subtract" : Result.Text = "<b>Result</b> = service.Subtract(operand1, operand2).ToString(); break; case "Multiply" : Result.Text = "<b>Result</b> = service.Multiply(operand1, operand2).ToString(); break; case "Divide" : Result.Text = "<b>Result</b> = service.Divide(operand1, operand2).ToString(); break; } } </script> <body style="font: 10pt verdana"> <h4>Using a Simple Math Service </h4> <form runat="server"> <div style="padding:15,15,15,15;backgroundcolor:beige;width:300;border-color:black;borderwidth:1;border-style:solid"> Operand 1:<br> <asp:TextBox id="Operand1" Text="15" runat="server" /><br> Operand 2:<br> <asp:TextBox id="Operand2" /><p> Text="5" runat="server" " " " + + +

<input type="submit" id="Add" value="Add" OnServerClick="Submit_Click" runat="server"> <input type="submit" id="Subtract" value="Subtract" OnServerClick="Submit_Click" runat="server"> <input type="submit" id="Multiply" value="Multiply" OnServerClick="Submit_Click" runat="server"> <input type="submit" id="Divide" value="Divide" OnServerClick="Submit_Click" runat="server"> <p> <asp:Label id="Result" runat="server" /> </div> </form> </body> </html>

195

Assemblies v Versioning

Gvhd: Nguyn Tn Trn Minh Khang

Chng 17 Assemblies v Versioning


n v c bn trong lp trnh .NET l Assembly. Mt Assembly l mt tp hp cc tp tin m i vi ngi s dng, h ch thy l mt tp tin DLL hay EXE. .NET nh ngha Assembly l mt n v c kh nng ti s dng (re-use), mang s hiu phin bn (versioning), bo mt (security) v cui cng l kh nng trin khai (deployment) Asssembly c th cha ng nhiu thnh phn khc ngoi m chng trnh ng dng nh ti nguyn (resource, v d tp tin .GIF), thng tin m t kiu (type definition), siu d liu (metadata) v m v d liu.

17.1 Tp tin PE
Assembly c lu tr trn da t theo dng thc tp tin Portable Executable (PE). Dng thc tp tin PE ca .NET cng ging nh tp tin PE bnh thng ca Windows NT. Dng thc PE c ci t thnh dng thc tp tin DLL v EXE. V mt logic, assembly cha ng mt hay nhiu module. Mi module c t chc thnh mt DLL v ng thi mi module l mt cu thnh ca assembly. Cc module t bn thn chng khng th chy c, cc module phi kt hp vi nhau thnh assembly th mi c th lm c vic g hu ch.

17.2 Metadata
Metadata l thng tin c lu tr bn trong assembly vi mc ch l m t cc kiu d liu, cc phng thc v cc thng tin khc v assembly. Do c cha metadata nn assembly c kh nng t m t.

17.3 Ranh gii an ninh


Assembly to ra mt ranh gii an ninh (security boundary). Cc kiu d liu nh ngha bn trong assembly b gii hn phm vi ti ranh gii assembly. c th s dng chung mt kiu d liu gia 2 assembly, cn phi ch nh r bng tham chiu (reference) trong IDE hoc dng lnh.

17.4 S hiu phin bn (Versioning)


Mi assembly c s hiu phin bn ring. Mt phin bn m ch ton b ni dung ca mt assembly bao gm c kiu d liu v resource.

17.5 Manifest
Manifest chnh l mt thnh phn ca metadata. Manifest m t mt assembly cha nhng g, v d nh: thng tin nhn dng (tn, phin bn), danh sch cc kiu d

196

Assemblies v Versioning

Gvhd: Nguyn Tn Trn Minh Khang

liu, danh sch cc resource, danh sch cc assembly khc c assembly ny tham chiu n,

17.5.1 Cc module trong manifest


Mt assembly c th cha nhiu module, do manifest trong assembly cn c th cha m bm (hash code) ca mi module lp ghp thnh assembly bo m rng khi thc thi, ch c th np cc module ng phin bn. Ch cn mt s thay i rt rt nh trong module l m bm s thay i.

17.5.2 Manifest trong module


Mi module cng cha ring phn manifest m t cho chnh n ging nh assembly cha manifest m t cho assembly vy.

17.5.3 Cc assembly cn tham chiu


Manifest ca assembly cng c th cha tham chiu n cc assembly khc. Mi tham chiu cha ng tn, phin bn, vn ha (culture), ngun gc (originator), Thng tin v ngun gc chnh l ch k s (digital signature) ca lp trnh vin hay ca cng ty ni cung cp assembly m assembly hin ti ang tham chiu n. Vn ha l mt i tng cha thng tin v ngn ng, cch trnh by ca mi quc gia. V d nh cch th hin ngy thng: D/M/Y hay M-D-Y

17.6 a Module Assembly


Mt assembly n module l mt assembly ch gm mt module, module ny c th l mt tp tin EXE hoc DLL. Manifest cho assembly n module c nhng vo trong module. Mt assembly a module l mt assembly bao gm nhiu tp tin (t nht mt tp tin EXE hoc DLL). Manifest cho assembly a module c th c lu tr thnh mt tp tin ring bit hoc c nhng vo mt module no bt k.

17.6.1 Li ch ca a module assembly


Nu mt d n c nhiu lp trnh vin m d n ch xy dng bng mt assembly, vic kim li, bin dch d n, l mt c mng v tt c cc lp trnh vin phi hp tc vi nhau, phi kim tra phin bn, phi ng b ha m ngun, Nu mt ng dng ln c xy dng bng nhiu assembly, khi cn cp nht (update) sa li chng hn, th ch cn cp nht mt / vi assembly m thi. Nu mt ng dng ln c t chc t nhiu assembly, ch c nhng phn m chng trnh thng s dng / quan trng thuc mt vi assembly l c np vo b nh, do lm gim bt chi ph b nh, tng hiu sut h thng.

197

Assemblies v Versioning

Gvhd: Nguyn Tn Trn Minh Khang

17.7 Assembly ni b (private assembly)


C 2 loi Assembly: ni b (private) v chia s (shared). Assembly ni b c d nh l ch dng cho mt ng dng, cn assembly chia s th ngc li, dng cho nhiu ng dng. Cc assembly ni b c ghi trn da t thnh mt tp tin EXE hoc DLL trong cng th mc vi assembly chnh hoc trong cc th mc con ca th mc cha assembly chnh. thc thi trn my khc ch cn sao chp ng cu trc th mc l , khng cn phi ng k vi Registry.

17.8 Assembly chia s (shared assembly)


Khi vit ra mt assembly i loi nh mt control chng hn, nu tc gi ca control c nh chia s cho cc lp trnh vin khc th anh / ch ta phi xy dng assembly p ng cc yu cu sau: Assembly phi c tn mnh (strong name). Tn mnh c ngha l chui biu din tn phi l duy nht (globally unique) Phi c thng tin v phin bn trnh hin tng cc phin bn dm chn ln nhau c th chia s assembly, assembly phi c t vo ni gi l Global Assembly Cache (GAC). y l ni c quy nh bi Common Language Runtime (CLR) dng cha assembly chia s.

17.8.1 Chm dt a ngc DLL


Gi s bn ci t mt ng dng A ln mt my v n chy tt. Sau bn ci t ng dng B, bng nhin ng dng A khng chu hot ng. Sau qu trnh tm hiu, cui cng nguyn nhn l do ng dng B ci mt phin bn khc ln mt tp tin DLL m ng dng A s dng. Tnh hung trn gi l a ngc DLL S ra i ca assembly chm dt tnh trng trn.

17.8.2 Phin bn
Assembly chia s trong .NET c nh v bng tn duy nht (unique) v phin bn. Phin bn c biu din bi 4 s phn cch bng du : v d nh 1:2:6:1246
S S S S u tin m t phin bn chnh (major version) th 2 m t phin bn ph (minor version) th 3 m t th t bn xy dng (build) cui cng m t ln xem xt cp nht (revision) sa li

198

Assemblies v Versioning

Gvhd: Nguyn Tn Trn Minh Khang

17.8.3 Tn mnh
Mt tn mnh l mt chui cc k t hexa mang thuc tnh l duy nht trong ton cu (globally unique). Ngoi ra chui cn c m ha bng thut ton kha cng khai 1 bo m rng assembly khng b thay i v tnh hay c . to ra tn mnh, mt cp kha cng khai-b mt c to ra cho assembly. Mt m bm (hash code) c to ra t tn, ni dung ca cc tp tin bn trong assembly v chui biu din kha cng khai. Sau m bm ny c m ha bng kha b mt, kt qu m ha c ghi vo manifest. Qu trnh trn c gi l k xc nhn vo assembly (signing the assembly). Khi assembly c CLR np vo b nh, CLR s dng kha cng khai trong manifest gii m m bm xc nh xem assembly c b thay i khng.

17.8.4 Global Assembly Cache (GAC)


Sau khi to tn mnh v ghi vo assembly, vic cn li thc hin chia s assembly l t assembly vo th mc GAC. l mt th mc c bit dng cha assembly chia s. Trn Windows, l th mc \WinNT\assembly.

M ha kha cng khai b mt: l mt thut ton m ha c bit, u tin dng mt thut ton ring to ra 2 kha, mt kha ph bin rng ri nn gi l kha cng khai, kha cn li do ch nhn ca n ct ni an ton nn gi l b mt. Sau dng thut ton m ha m ha d liu. Mt khi d liu b m ha bng mt kha th d liu ch c th c gii m bng kha kia v ngc li.

199

Attributes v Reflection

Gvhd: Nguyn Tn Trn Minh Khang

Chng 18 Attributes v Reflection


Xin c nhc li rng mt ng dng .NET bao gm m chng trnh, d liu, metadata. Metadata chnh l thng tin v d liu m ng dng s dng nh kiu d liu, m thc thi, assembly, Attributes l c ch to ra metadata. V d nh ch th cho trnh bin dch, nhng d liu khc lin quan n d liu, phng thc, lp, Reflection l qu trnh mt ng dng c li metadata ca chnh n c cch th hin, ng x thch hp cho tng ngi dng.

18.1 Attributes
Mt attribute l mt i tng, trong i tng cha mt mu d liu, m lp trnh vin mun nh km vi mt phn t (element) no trong ng dng. Phn t (element) m lp trnh vin mun nh km attribute gi l mc tiu (target) ca attribute. V d attribute: [NoIDispatch] c nh km vi mt lp hay mt giao din ni rng lp ch (target class) nn c tha k t giao din IUnknown ch khng phi tha k t IDispatch.

18.2 Attribute mc nh (intrinsic attributes)


C 2 loi attribute: Attribute mc nh: l attribute c CLR cung cp sn. Attribute do lp trnh vin nh ngha (custom attribute)

18.2.1 ch ca Attribute
Mi attribute ch ng hng n mt ch (target) m n khai bo. ch c th l lp, giao din, phng thc Bng sau lit k tt c cc ch
Bng 18-1 Cc ch ca attribute
Loi All Assembly Class ClassMembers ngha p dng cho tt c cc loi bn di p dng cho chnh assembly p dng cho mt th hin ca lp p dng cho cc loi t sau hng ny tr i

200

Attributes v Reflection

Gvhd: Nguyn Tn Trn Minh Khang

Constructor Delegate Enum Event Field Interface Method Module Parameter Property ReturnValue Struct

p dng vi hm dng p dng cho delegate p dng cho kiu lit k p dng cho s kin p dng cho bin thnh vin (tnh ln khng tnh) p dng cho giao din p dng cho phng thc p dng cho module p dng cho tham s p dng cho property p dng cho tr tr v p dng cho cu trc

18.2.2 p dng Attribute


Lp trnh vin p dng attribute ln mc tiu bng cch t attribute trong ngoc vung [] lin trc mc tiu. V d attribute Assembly c p dng:
[assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile(keyfile.snk)]

Cch sau cng tng ng vi cch trn:


[assembly: AssemblyDelaySign(false), assembly: AssemblyKeyFile(keyfile.snk)]

Attribute thng dng trong lp trnh C# l Serializable


[serializable] class MySerClass

Attribute trn bo cho compiler bit rng lp MySerClass cn c bo m trong vic ghi ni dung, trng tht xung da t hay truyn qua mng.

18.3 Attribute do lp trnh vin to ra


Lp trnh vin hon ton t do trong vic to ra cc attribute ring v em s dng chng vo ni no cm thy thch hp.

18.3.1 Khai bo Attribute t to


u tin l tha k mt lp t lp System.Attribute:
Public class XYZ : System.Attribute

Sau l bo cho compiler bit attribute ny c th em p dng ln mc tiu no.


[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]

201

Attributes v Reflection

Gvhd: Nguyn Tn Trn Minh Khang

Attribute AttributeUsage trn c mc tiu p dng l Attribute khc: gi l meta-attribute.

18.3.2 t tn mt attribute
Lp trnh vin hon ton t do trong vic t tn cho attribute. Tuy nhin, compiler ca .NET cn c thm kh nng t ni thm chui Attribute vo tn. iu c ngha l nu lp trnh vin nh ngha mt attribute c tn l MyBugFix th khi tm kim hoc truy xut attribute trn, lp trnh vin c th vit tn attribute: MyBugFix hoc MyBugFixAttribute. Nu mt attribute c tn l MyBugFixAttribute th lp trnh vin cng c th ghi tn attribute l MyBugFix hoc MyBugFixAttribute. V d:
[MyBugFix(123, "Jesse Liberty", "01/01/05", Comment="Off by one")]

18.3.3 Khi to Attribute


Mi attribute phi c t nht mt contructor. Attribute nhn 2 kiu i s: kiu v tr (positional) v kiu tn (named). Trong v d MyBugFix phn trc, phn tn v ngy thng l kiu v tr, phn ghi ch (comment) l kiu tn. Cc i s kiu v tr phi c truyn vo contructor ng theo th t khai bo. V d:
public BugFixAttribute(int bugID, string programmer, string date) { this.bugID = bugID; this.programmer = programmer; this.date = date; }

i s kiu tn th c ci t nh l properties:
public string Comment { get { return comment; } set { comment = value; } }

18.3.4 S dng Attribute


Mt khi nh ngha attribute, lp trnh vin s dng n bng cch t n ngay trc mc tiu (target) ca n. V d:
[BugFixAttribute(121,"Jesse Liberty","01/03/05")] BugFixAttribute(107,"Jesse Liberty","01/04/05", Comment="Fixed off by one errors")] public class MyMath

V d trn p dng attribute MyBugFix vo lp MyMath.

202

Attributes v Reflection

Gvhd: Nguyn Tn Trn Minh Khang

18.4 Reflection
cho vic lu attribute trong metadata c ch, cn phi c c ch truy xut chng vo lc chy. Cc lp trong vng tn (namespace) Reflection, cng vi cc lp trong System.Type v System.TypeReference, cung cp s h tr truy xut metadata. Reflection l mt khi nim chung cho bt k thao tc no trong cc thao tc sau y: Xem xt metadata Tm hiu kiu d liu (type discovery): lp, interface, phng thc, i s ca phng thc, properties, event, field, Ni kt tr cc phng thc v properties (late binding to methods and properties) To ra mt kiu d liu mi ngay trong lc thc thi. Lp trnh vin c th nh ngha mt assembly mi ngay lc chy, c th lu xung da t dng li.

203

Marshaling v Remoting

Gvhd: Nguyn Tn Trn Minh Khang

Chng 19 Marshaling v Remoting


Ngy nay, cc ng dng khng cn n thun ch gm mt module, khi thc thi th ch cn chy trong mt process m l mt tp hp nhiu thnh phn (component) phc tp. Cc thnh phn khng ch phn cch vi nhau bng ranh gii gia cc process m cn c th phn cch vi nhau qua ranh gii my - mng - my. Tin trnh di chuyn mt i tng vt qua mt ranh gii (process, my, ) c gi l Remoting. Tin trnh chun b mt i tng thc hin remoting c gi l Marshaling. Gi s i tng A nm trn my X mun s dng dch v ca i tng B nm trn my Y. phc v i tng A, i tng B chuyn cho A mt i tng proxy. Nhng yu cu t i tng A s c proxy chuyn v cho B, nhng kt qu tr li ca B c gi n proxy, proxy s gi li cho i tng A. Gia i tng A v i tng B c nhiu i tng sink, cng vic ca cc i tng sink l p t an ninh ln knh lin lc gia 2 i tng. Cc thng ip c chuyn ti gia A v B trn mt i tng channel. i tng channel li yu cu s gip ca i tng formatter. Cng vic ca formatter l nh dng li thng ip 2 pha c th hiu nhau (v d chuyn m ha endian ca dy byte).

19.1 Min ng Dng (Application Domains)


Theo l thuyt, mt process l mt ng dng ang thc thi (ang chy). Mi mt application thc thi trong mt process ring ca n. Nu trn my hin c Word, Excel, Visual Studio th tng ng trn my ang c 3 process. Bn trong mi process, .NET chia nh ra thnh cc phn nh hn gi l min ng dng (Application Domains vit tt l app domains). C th xem mi min ng dng l mt process nh cn, min ng dng hnh x y nh l mt process nhng im khc bit l n s dng t ti nguyn hn process. Cc min ng dng trong mt process c th khi ng (started) hay b treo (halted) c lp vi nhau. Min ng dng cung cp kh nng chu li (fault tolerance); nu khi ng mt i tng trong mt min ng dng khc vi min ng dng chnh v i tng va khi ng gy li, n ch lm crash min ng dng ca n ch khng lm crash ton b ng dng. Mi process lc bt u thc thi c mt min ng dng ban u (initial app domain) v c th to thm nhiu min ng dng khc nu lp trnh vin mun. Thng thng, ng dng ch cn mt min ng dng l . Tuy nhin, trong nhng ng dng ln cn s dng nhng th vin do ngi khc vit m th vin khng

204

Marshaling v Remoting

Gvhd: Nguyn Tn Trn Minh Khang

c tin cy lm th cn to ra mt min ng dng khc dng cha th vin khng tin cp , tch th vin khi min ng dng chnh c lp li, nu li xy ra th khng lm crash ng dng. Min ng dng khc vi thread. Mt thread lun chy bn trong mt min ng dng. Trong mt min ng dng c th tn ti nhiu thread.

19.1.1 Marshaling vt qua bin min ng dng


Marshaling l qu trnh chun b mt i tng di chuyn qua mt ranh gii no . Marshaling c th c tin hnh theo 2 cch: bng gi tr (by value) v bng tham chiu (by reference). Khi mt i tng c marshaling bng gi tr, mt bn sao ca i tng c to ra v truyn n ni nhn. Nhng thay i trn bn sao ny khng lm thay i i tng gc ban u. Khi mt i tng c marshaling bng tham chiu, mt i tng c bit gi l proxy c gi n ni nhn. Nhng thay i, nhng li gi hm trn i tng proxy s c chuyn v cho i tng ban u x l.

19.1.1.1 Tm hiu marshaling v proxy


Khi marshaling i tng bng reference, .NET CLR cung cp cho i tng ang thc hin li gi t xa mt i tng proxy trong sut (transparent proxy - TP). Cng vic ca i tng TP l nhn tt c nhng thng tin g lin quan n vic gi hm (gi tr tr v, thng s nhp, ) t trong stack ri ng gi vo mt i tng ring m i tng ci t giao din IMessage. Sau i tng IMessage c trao cho i tng RealProxy. RealProxy l mt lp c s tru tng (abstract base class) m t cc i tng proxy tha k. Lp trnh vin c th t to ra cc i tng proxy mi tha k t RealProxy. i tng proxy mc nh ca h thng s trao IMessage cho mt chui cc i tng sink. S lng cc sink ph thuc vo s lng chnh sch bo an (policy) m nh qun tr mun duy tr, tuy nhin i tng sink cui cng l i tng t IMessage vo Channel. Channel c chia ra thnh channel pha client v channel pha server, cng vic chnh ca channel l di chuyn thng ip (message) vt qua mt ranh gii (boundary). Channel chu trch nhim tm hiu nghi thc truyn thng (transport protocol). nh dng tht s ca thng ip di chuyn qua ranh gii c qun l bi formatter. Khung ng dng (framework) .NET cung cp 2 formatter: Simple Object Access Protocol (SOAP) dng cho HTTP channel Binary dng cho TCP/IP channel Lp trnh vin cng c th to i tng formatter ring v nu mun cng c th to ra channel ring.

205

Marshaling v Remoting

Gvhd: Nguyn Tn Trn Minh Khang

Mt khi message vt qua ranh gii, n c nhn bi channel v formatter pha server. Channel pha server s ti to li i tng IMessage, sau channel pha server trao i tng IMessage cho mt hay nhiu i tng sink pha server. i tng sink cui cng trong chui sink l mt i tng StackBuilder, cng vic ca StackBuilder l nhn IMessage ri ti to li stack frame c th thc hin li gi hm.

19.1.1.2 Ch nh phng php Marshaling


Mt i tng bnh thng hon ton khng c kh nng marshaling. marshaling mt i tng bng gi tr (by value), ch cn nh du attribute Serializable lc nh ngha i tng.
[Serializable] public class Point

marshaling mt i tng bng tham chiu (by reference), i tng cn tha k t MarshalByRefObject.
public class Shape : MarshalByRefObject

19.2 Context
Min ng dng (app domain) n lt n li c chia ra thnh cc context. Context c th xem nh mt ranh gii m cc i tng bn trong context c cng quy tc s dng (usage rules). Cc quy tc s dng nh: ng b ha giao dch (synchronization transaction),

19.2.1 i tng loi Context-Bound v Context-Agile


Cc i tng c th l Context-Bound hoc Context-Agile. Nu cc i tng l Context-Bound, chng tn ti trong mt context ring, khi giao tip ln nhau, cc thng ip ca chng c marshaling vt qua bin context. Nu cc i tng l Context-Agile, chng hot ng bn trong context ca i tng yu cu (calling). Do , khi mt i tng A triu gi phng thc ca i tng B, phng thc ca B c thc thi bn trong context ca A. V vy vic marshaling l khng cn thit. Gi s i tng A cn giao tip vi c s d liu, gi s i tng A c thit lp v giao dch (transaction). Do A cn to mt context. Tt c cc phng thc ca A s c thc thi trong context ca transaction. Gi s c mt i tng B khc thuc loi context-agile. Gi s rng i tng A trao mt tham chiu c s d liu cho i tng B v triu gi mt phng thc X ca B. Li gi s rng phng thc X ca B m A triu gi li gi mt phng thc Y khc ca A. Bi v B thuc loi context-agile do phng thc X ca B c thc thi trong context ca i tng A. V context ca A c s bo v ca giao

206

Marshaling v Remoting

Gvhd: Nguyn Tn Trn Minh Khang

dch nn nu A c roll-back c s d liu th nhng thay i m phng thc X ca B ln c s d liu cng s c roll-back. Gi s i tng C triu gi mt phng thc Z ca B, phng thc Z c thc hin thay i c s d liu, do B thuc loi Context-Agile nn Z c thc thi trong context ca C. V vy nhng thay i m Z thc hin ln c s d liu s khng th c roll-back. Nu B thuc loi Context-Bound, khi A to ra B, context ca B s c tha k t context ca A. Khi C triu gi phng thc Z ca B, li triu gi c marshaling t context ca C n context ca B ri c thc hin trong context ca B (tha k t A). Do phng thc Z thc thi trong s bo v ca transaction. Nhng thay i m Z thc hin ln c s d liu c th c rooll-back. Mt i tng c th c 3 la chn v Context: Context-Agile Context-Bound khng ch nh attribute. Thc hin bng cch tha k t ContextBoundObject. Phng thc ca i tng thuc loi ny thc thi trong Context tha k t Context ca i tng to ra n Context-Bound c ch nh attribute Context. Cc phng thc hot ng trong Context do n to ring.

19.2.2 Marshaling vt qua ranh gii Context


Khi truy cp i tng Context-Agile trong cng min ng dng th khng cn proxy. Khi mt i tng A trong mt context truy cp mt i tng ContextBound B trong mt context khc, i tng A truy cp i tng B thng qua proxy ca B. i tng c marshaling khc nhau vt qua ranh gii context ph thuc vo cch n c to ra: i tng bnh thng khng c marshaling; bn trong min ng dng cc i tng thuc loi context-agile i tng c nh du attribute Serializable th thuc loi context-agile v c marshaling bi gi tr (by value) vt qua ranh gii min ng dng i tng tha k t MarshalByRefObject th thuc loi context-agile v c marshaling bi tham chiu (by reference) vt qua ranh gii min ng dng i tng tha k t ContextBoundObject c marshaling bi tham chiu vt qua ranh gi min ng dng v ranh gii context

207

Marshaling v Remoting

Gvhd: Nguyn Tn Trn Minh Khang

19.3 Remoting
Cng vi vic marshaling i tng vt qua ranh gii context v min ng dng, i tng c th c marshaling vt qua ranh gii process v thm ch qua ranh gii my - mng - my. Khi mt i tng c marshaling vt qua ranh gii process hay my - mng my, n c gi l Remoted.

19.3.1 Tm hiu cc kiu d liu pha Server


C 2 kiu i tng pha server phc v cho vic Remoting trong .NET: ni ting (well-known) v client kch hot (client activated). Knh lin lc vi i tng ni ting c thit lp mi khi client gi thng ip (message). Knh lin lc khng c gi thng trc nh trong trng hp ca i tng client kch hot. i tng ni ting chia thnh 2 loi nh: singleton v single-call. i tng ni ting kiu singleton: tt c cc thng ip t client gi n i tng c phn phi (dispatch) cho mt i tng ang chy trn server. i tng ny c to ra khi server khi ng v nm ch trn server phc v cho bt k client no. V vy i tng loi ny phi c contructor khng tham s. i tng ni ting kiu single-call: mi thng ip mi t client gi i c gii quyt bi mt i tng mi. M hnh ny thng dng cn bng ti h thng. i tng client kch hot thng c s dng bi cc lp trnh vin c cng vic chnh l to ra cc server ring phc v cho vic lp trnh, i tng client kch hot duy tr kt ni vi client cho n khi no ton b yu cu ca client c p ng.

19.3.2 M t mt server bng Interface


Sau y l v d xy dng mt lp my tnh (calculator) vi 4 chc nng. To mt tp tin ICalc.cs vi ni dung
namespace Programming_CSharp using System; public interface ICalc { double Add(double x, double y); double Sub(double x, double y); double Mult(double x, double y); double Div(double x, double y); }

To mt project mi kiu C# Class Library, m menu Build, ra lnh Build. Kt qu l mt tp tin Icalc.DLL

208

Marshaling v Remoting

Gvhd: Nguyn Tn Trn Minh Khang

19.3.3 Xy dng mt Server


To mt project kiu C# Console Application, to mt tp tin mi CalcServer.cs, sau ra lnh Build. Lp Calculator tha k t MarshalByRefObect nn n s trao cho client mt proxy khi c triu gi.
public class Calculator : MarshalByRefObject, ICalc

Cng vic u tin l to channel v ng k, s dng HTTPChannel cung cp bi .NET:


HTTPChannel chan = new HTTPChannel(65100);

ng k channel vi .NET Channel Services:


ChannelServices.RegisterChannel(chan);

ng k i tng (cn cung cp endpoint cho hm ng k; endpoint chnh l tn lin kt vi i tng)


Type calcType = Type.GetType("Programming_CSharp.Calculator");

ng k kiu Singleton
RemotingConfiguration.RegisterWellKnownServiceType ( calcType, "theEndPoint",WellKnownObjectMode.Singleton );

Sau y l ton b ni dung:


using using using using System; System.Runtime.Remoting; System.Runtime.Remoting.Channels; System.Runtime.Remoting.Channels.Http;

namespace Programming_CSharp { // implement the calculator class public class Calculator : MarshalByRefObject, ICalc { public Calculator( ) { Console.WriteLine("Calculator constructor"); } // implement the four functions public double Add(double x, double y) { Console.WriteLine("Add {0} + {1}", x, y); return x+y; } public double Sub(double x, double y) { Console.WriteLine("Sub {0} - {1}", x, y); return x-y; } public double Mult(double x, double y)

209

Marshaling v Remoting

Gvhd: Nguyn Tn Trn Minh Khang

{ }

Console.WriteLine("Mult {0} * {1}", x, y); return x*y;

public double Div(double x, double y) { Console.WriteLine("Div {0} / {1}", x, y); return x/y; } } public class ServerTest { public static void Main( ) { // to mt channel v ng k n HttpChannel chan = new HttpChannel(65100); ChannelServices.RegisterChannel(chan); Type calcType = Type.GetType("Programming_CSharp.Calculator"); // register our well-known type and tell the server // to connect the type to the endpoint "theEndPoint" RemotingConfiguration.RegisterWellKnownServiceType ( calcType, "theEndPoint", WellKnownObjectMode.Singleton ); // "They also serve who only stand and wait."); (Milton) Console.WriteLine("Press [enter] to exit..."); Console.ReadLine( ); } }

19.3.4 Xy dng Client


Client cng phi ng k channel, tuy nhin client khng lng nghe trn channel nn client s dng channel 0 (zero)
HTTPChannel chan = new HTTPChannel(0); ChannelServices.RegisterChannel(chan);

Client kt ni vi dch v t xa, trao cho hm kt ni kiu i tng m n cn cng vi URI ca lp ci t dch v
MarshalByRefObject obj = RemotingServices.Connect( typeof(Programming_CSharp.ICalc), "http://localhost:65100/theEndPoint");

V i tng t xa c th khng sn sng (mng t, my cha i tng khng tn ti,) nn gi hm cn khi th


try { Programming_CSharp.ICalc calc = obj as Programming_CSharp.ICalc; double sum = calc.Add(3,4);

By gi client c i tng proxy ca i tng Calculator. Sau y l ton b m ngun

210

Marshaling v Remoting

Gvhd: Nguyn Tn Trn Minh Khang

namespace Programming_CSharp { using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; public class CalcClient { public static void Main( ) { int[] myIntArray = new int[3]; Console.WriteLine("Watson, come here I need you..."); // create an Http channel and register it // uses port 0 to indicate won't be listening HttpChannel chan = new HttpChannel(0); ChannelServices.RegisterChannel(chan); // get my object from across the http channel MarshalByRefObject obj = (MarshalByRefObject) RemotingServices.Connect (typeof(Programming_CSharp.ICalc), "http://localhost:65100/theEndPoint"); try { // cast the object to our interface Programming_CSharp.ICalc calc = obj as Programming_CSharp.ICalc; // use the interface to call methods double sum = calc.Add(3.0,4.0); double difference = calc.Sub(3,4); double product = calc.Mult(3,4); double quotient = calc.Div(3,4); // print the results Console.WriteLine("3+4 = {0}", sum); Console.WriteLine("3-4 = {0}", difference); Console.WriteLine("3*4 = {0}", product); Console.WriteLine("3/4 = {0}", quotient); } catch( System.Exception ex ) { Console.WriteLine("Exception caught: "); Console.WriteLine(ex.Message); } } } } Kt xut pha client Watson, come here I need you... 3+4 = 7 3-4 = -1 3*4 = 12 3/4 = 0.75 Kt xut pha server: Calculator constructor Press [enter] to exit... Add 3 + 4 Sub 3 - 4 Mult 3 * 4

211

Marshaling v Remoting

Gvhd: Nguyn Tn Trn Minh Khang

Div 3 / 4

19.3.5 S dng SingleCall


thy s khc bit gia Singleton v Single Call, thay i mt dng trong m ngun Calculator.cs
RemotingServices. RegisterWellKnownServiceType( "CalcServerApp","Programming_CSharp.Calculator", "theEndPoint",WellKnownObjectMode.Singleton );

thnh
RemotingServices. RegisterWellKnownServiceType( "CalcServerApp","Programming_CSharp.Calculator", "theEndPoint",WellKnownObjectMode.SingleCall );

V y l kt qu kt xut pha server


Calculator constructor Press [enter] to exit... Calculator constructor Add 3 + 4 Calculator constructor Sub 3 - 4 Calculator constructor Mult 3 * 4 Calculator constructor Div 3 / 4

19.3.6 Tm hiu RegisterWellKnownServiceType


Khi gi phng thc RegisterWellKnownServiceType, iu g xy ra ? Xin nh li rng bn to mt i tng Type cho lp Calculator
Type.GetType("Programming_CSharp.Calculator");

Sau bn gi RegisterWellKnownServiceType(), trao cho phng thc i tng Type, endpoint v Singleton. iu bo cho CLR bit phi to mt th hin ca Calculator v lin kt endpoint vi th hin . Bn c th t lm li qu trnh bng cch thay i hm Main() nh sau:
V d 19-1 Manually instantiating and associating Calculator with an endpoint
public static void Main( ) { // create a channel and register it HttpChannel chan = new HttpChannel(65100); ChannelServices.RegisterChannel(chan); // make your own instance and call Marshal directly Calculator calculator = new Calculator( ); RemotingServices.Marshal(calculator,"theEndPoint"); // "They also serve who only stand and wait."); (Milton) Console.WriteLine("Press [enter] to exit..."); Console.ReadLine( ); }

212

Marshaling v Remoting

Gvhd: Nguyn Tn Trn Minh Khang

19.3.7 Tm hiu EndPoint


Chuyn g xy ra khi bn ng k endpoint ? R rng l server lin kt endpoint vi i tng bn va to, v khi client kt ni, server s dng ch mc trong mt bng c th tr v i tng proxy tng ng vi i tng yu cu. Bn c th khng cung cp endpoint, thay vo bn ghi cc thng tin v i tng Calculator ri gi v client. Client phc ch li i tng proxy c th dng lin lc vi Calculator trn server. c th hiu lm cch no bn c th gi mt i tng m khng bit endpoint, hy thay i hm Main() mt ln na, thay v gi Marshal() vi mt endpoint, hy trao mt i tng:
ObjRef objRef = RemotingServices.Marshal(calculator)

Hm Marshal() tr v mt i tng ObjRef. i tng ObjRef cha tt c thng tin cn thit kch hot v lin lc vi i tng xa. Khi bn cung cp mt endpoint, server to mt bng v lin kt endpoint vi mt ObjRef khi client c yu cu, server c th to mt proxy cung cp cho client. ObjRef cha tt c thng tin cn thit cho client client c th to mt proxy. ObjRef c kh nng Serializable. M mt stream tp tin, to mt SOAP formatter, bn c th serialize i tng ObjRef thnh mt tp tin bng cch gi hm Serialize() ca formatter, sau a cho formatter tham chiu n stream tp tin v tham chiu ca ObjRef, vy l bn c tt c thng tin cn thit to mt proxy di dng mt tp tin
V d 19-2 Marshaling an object without a well-known endpoint
public static void Main( ) { // create a channel and register it HttpChannel chan = new HttpChannel(65100); ChannelServices.RegisterChannel(chan); // make your own instance and call Marshal directly Calculator calculator = new Calculator( ); ObjRef objRef = RemotingServices.Marshal(calculator); FileStream fileStream = new FileStream("calculatorSoap.txt",FileMode.Create); SoapFormatter soapFormatter = new SoapFormatter( ); soapFormatter.Serialize(fileStream,objRef); fileStream.Close( ); // "They also serve who only stand and wait."); (Milton) Console.WriteLine( "Exported to CalculatorSoap.txt. Press ENTER to exit..."); Console.ReadLine( ); }

Bn hy trao tp tin cha i tng serialize cho client. client c th ti to li i tng, client cn to mt channel v ng k n.
FileStream fileStream = new FileStream ("calculatorSoap.txt", FileMode.Open);

213

Marshaling v Remoting

Gvhd: Nguyn Tn Trn Minh Khang

Sau to mt th hin ca i tng SoapFormatter ri gi hm DeSerialize() ca formatter nhn li i tng ObjRef


SoapFormatter soapFormatter = new SoapFormatter ( ); try { ObjRef objRef = (ObjRef) soapFormatter.Deserialize (fileStream);

Tin hnh g b marshall, nhn li ICalc


ICalc calc = (ICalc) RemotingServices.Unmarshal(objRef);

By gi client c th triu gi phng thc trn server thng qua ICalc.


V d 19-3 Replacement of Main( ) from Example 19-4 (the client)
public static void Main( ) { int[] myIntArray = new int[3]; Console.WriteLine("Watson, come here I need you..."); // create an Http channel and register it // uses port 0 to indicate you won't be listening HttpChannel chan = new HttpChannel(0); ChannelServices.RegisterChannel(chan); FileStream fileStream = new FileStream ("calculatorSoap.txt", FileMode.Open); SoapFormatter soapFormatter = new SoapFormatter ( ); try { ObjRef objRef = (ObjRef) soapFormatter.Deserialize (fileStream); ICalc calc = (ICalc) RemotingServices.Unmarshal(objRef); // use the interface to call methods double sum = calc.Add(3.0,4.0); double difference = calc.Sub(3,4); double product = calc.Mult(3,4); double quotient = calc.Div(3,4); // print the results Console.WriteLine("3+4 = {0}", sum); Console.WriteLine("3-4 = {0}", difference); Console.WriteLine("3*4 = {0}", product); Console.WriteLine("3/4 = {0}", quotient); } catch( System.Exception ex ) { Console.WriteLine("Exception caught: "); Console.WriteLine(ex.Message); } }

214

Thread v S ng B

Gvhd: Nguyn Tn Trn Minh Khang

Chng 20 Thread v S ng B
Thread l mt process nh cn cung cp kh nng multitasking trong mt ng dng. Vng tn System.Threading cung cp nhiu lp v giao din h tr lp trnh nhiu thread.

20.1 Thread
Thread thng c to ra khi bn mun lm ng thi 2 vic trong cng mt thi im. Gi s ng dng ca bn ang tin hnh c vo b nh mt tp tin c kch thc khong 500MB, trong lc ang c th d nhin ng dng khng th p ng yu cu x l giao din. Gi s ngi dng mun ngng gia chng, khng cho ng dng c tip tp tin ln na, do cn mt thread khc x l giao din, lc ny khi ngi dng n nt Stop th ng dng p ng c yu cu trong khi thread ban u vn ang c tp tin.

20.1.1 To Thread
Cch n gin nht l to mt th hin ca lp Thread. Contructor ca lp Thread nhn mt tham s kiu delegate. CLR cung cp lp delegate ThreadStart nhm mc ch ch n phng thc m bn mun thread mi thc thi. Khai bo delegate ThreadStart nh sau:
public delegate void ThreadStart( );

Phng thc m bn mun gn vo delegate phi khng cha tham s v phi tr v kiu void. Sau y l v d:
Thread myThread = new Thread( new ThreadStart(myFunc) );

myFunc phi l phng thc khng tham s v tr v kiu void. Xin lu l i tng Thread mi to s khng t thc thi (execute), i tng thc thi, bn cn gi phng thc Start() ca n.
Thread t1 Thread t2 t1.Start( t2.Start( = new Thread( new ThreadStart(Incrementer) ); = new Thread( new ThreadStart(Decrementer) ); ); );

Thread s chm dt khi hm m n thc thi tr v (return).

20.1.2 Gia nhp Thread


Hin tng thread A ngng chy v ch cho thread B chy xong c gi l thread A gia nhp thread B. thread 1 gia nhp thread 2:

215

Thread v S ng B

Gvhd: Nguyn Tn Trn Minh Khang

t2.Join( );

Nu cu lnh trn c thc hin bi thread 1, thread 1 s dng li v ch cho n khi thread 2 kt thc.

20.1.3 Treo thread li (suspend thread)


Nu bn mun treo thread ang thc thi li mt khong thi gian th bn s dng hm Sleep() ca i tng Thread. V d thread ngng khong 1 giy:
Thread.Sleep(1000);

Cu lnh trn bo cho b iu phi thread (ca h iu hnh) bit bn khng mun b iu phi thread phn phi thi gian CPU cho thread thc thi cu lnh trn trong thi gian 1 giy.

20.1.4 Git mt Thread (Kill thread)


Thng thng thread s chm dt khi hm m n thc thi tr v. Tuy nhin bn c th yu cu mt thread t t bng cch gi hm Interrupt() ca n. iu ny s lm cho exception ThreadInterruptedException c nm ra. Thread b yu cu t t c th bt exception ny tin hnh dn dp ti nguyn.
catch (ThreadInterruptedException) { Console.WriteLine("[{0}] Interrupted! Cleaning up...", Thread.CurrentThread.Name); }

20.2 ng b ha (Synchronization)
Khi bn cn bo v mt ti nguyn, trong mt lc ch cho php mt thread thay i hoc s dng ti nguyn , bn cn ng b ha. ng b ha c cung cp bi mt kha trn i tng , kha s ngn cn thread th 2 truy cp vo i tng nu thread th nht cha tr quyn truy cp i tng. Sau y l v d cn s ng b ha. Gi s 2 thread s tin hnh tng tun t 1 n v mt bin tn l counter.
int counter = 0;

Hm lm thay i gi tr ca Counter:
public void Incrementer( ) { try { while (counter < 1000) { int temp = counter; temp++; // increment // simulate some work in this method Thread.Sleep(1); // assign the Incremented value

216

Thread v S ng B

Gvhd: Nguyn Tn Trn Minh Khang

// to the counter variable // and display the results counter = temp; Console.WriteLine( "Thread {0}. Incrementer: {1}", Thread.CurrentThread.Name, counter); } }

Vn ch thread 1 c gi tr counter vo bin tm ri tng gi tr bin tm, trc khi thread 1 ghi gi tr mi t bin tm tr li counter th thread 2 li c gi tr counter ra bin tm ca thread 2. Sau khi thread 1 ghi gi tr va tng 1 n v tr li counter th thread 2 li ghi tr li counter gi tr mi bng vi gi tr m thread 1 va ghi. Nh vy sau 2 ln truy cp gi tr ca bin counter ch tng 1 n v trong khi yu cu l phi tng 2 n v.

20.2.1 S dng Interlocked


CLR cung cp mt s c ch ng b t c ch n gin Critical Section (gi l Locks trong .NET) n phc tp nh Monitor. Tng v gim gi tr lm mt nhu cu ph bin, do C# cung cp mt lp c bit Interlocked nhm p ng nhu cu trn. Interlocked c 2 phng thc Increment() v Decrement() nhm tng v gim gi tr trong s bo v ca c ch ng b. V d phn trc c th sa li nh sau:
public void Incrementer( ) { try { while (counter < 1000) { Interlocked.Increment(ref counter); // simulate some work in this method Thread.Sleep(1); // assign the decremented value // and display the results Console.WriteLine( "Thread {0}. Incrementer: {1}", Thread.CurrentThread.Name, counter); } } }

Khi catch v finally khng thay i so vi v d trc.

20.2.2 S dng Locks


Lock nh du mt on m gay cn (critical section) trong chng trnh ca bn, cung cp c ch ng b cho khi m m lock c hiu lc.

217

Thread v S ng B

Gvhd: Nguyn Tn Trn Minh Khang

C# cung cp s h tr cho lock bng t cht (keyword) lock. Lock c g b khi ht khi lnh. V d:
public void Incrementer( ) { try { while (counter < 1000) { lock (this) { // lock bt u c hiu lc int temp = counter; temp ++; Thread.Sleep(1); counter = temp; } // lock ht hiu lc -> b g b // assign the decremented value // and display the results Console.WriteLine( "Thread {0}. Incrementer: {1}", Thread.CurrentThread.Name, counter); } }

Khi catch v finally khng thay i so vi v d trc.

20.2.3 S dng Monitor


c th ng b ha phc tp hn cho ti nguyn, bn cn s dng monitor. Mt monitor cho bn kh nng quyt nh khi no th bt u, khi no th kt thc ng b v kh nng ch i mt khi m no ca chng trnh t do. Khi cn bt u ng b ha, trao i tng cn ng b cho hm sau:
Monitor.Enter(i tng X);

Nu monitor khng sn dng (unavailable), i tng bo v bi monitor ang c s dng. Bn c th lm vic khc trong khi ch i monitor sn dng (available) hoc treo thread li cho n khi c monitor (bng cch gi hm Wait()) V d bn ang download v in mt bi bo t Web. hiu qu bn cn tin hnh in sau hu trng (background), tuy nhin bn cn chc chn rng 10 trang c download trc khi bn tin hnh in. Thread in n s ch i cho n khi thread download bo hiu rng s lng trang download . Bn khng mun gia nhp (join) vi thread download v s lng trang c th ln n vi trm. Bn mun ch cho n khi t nht 10 trang c download. gi lp vic ny, bn thit lp 2 hm m dng chung 1 bin counter. Mt hm m tng 1 tng ng vi thread download, mt hm m gim 1 tng ng vi thread in n. Trong hm lm gim bn gi phng thc Enter(), sau kim tra gi tr counter, nu < 5 th gi hm Wait()

218

Thread v S ng B

Gvhd: Nguyn Tn Trn Minh Khang

if (counter < 5) { Monitor.Wait(this); }

Li gi Wait() gii phng monitor nhng bn bo cho CLR bit l bn mun ly li monitor ngay sau khi monitor c t do mt ln na. Thread thc thi phng thc Wait() s b treo li. Cc thread ang treo v ch i monitor s tip tc chy khi thread ang thc thi gi hm Pulse().
Monitor.Pulse(this);

Pulse() bo hiu cho CLR rng c s thay i trong trng thi monitor c th dn n vic gii phng (tip tc chy) mt thread ang trong tnh trng ch i. Khi thread hon tt vic s dng monitor, n gi hm Exit() tr monitor.
Monitor.Exit(this);

Source code v d:
namespace Programming_CSharp { using System; using System.Threading; class Tester { static void Main( ) { // make an instance of this class Tester t = new Tester( ); // run outside static Main t.DoTest( ); } public void DoTest( ) { // create an array of unnamed threads Thread[] myThreads = { new Thread( new ThreadStart(Decrementer) ), new Thread( new ThreadStart(Incrementer) ) }; // start each thread int ctr = 1; foreach (Thread myThread in myThreads) { myThread.IsBackground=true; myThread.Start( ); myThread.Name = "Thread" + ctr.ToString( ); ctr++; Console.WriteLine("Started thread {0}",myThread.Name); Thread.Sleep(50); } // wait for all threads to end before continuing foreach (Thread myThread in myThreads) { myThread.Join( ); } // after all threads end, print a message Console.WriteLine("All my threads are done."); }

219

Thread v S ng B

Gvhd: Nguyn Tn Trn Minh Khang

void Decrementer( ) { try { // synchronize this area of code Monitor.Enter(this); // if counter is not yet 10 // then free the monitor to other waiting // threads, but wait in line for your turn if (counter < 10) { Console.WriteLine( "[{0}] In Decrementer. Counter: {1}. Gotta Wait!", Thread.CurrentThread.Name, counter); Monitor.Wait(this); } while (counter >0) { long temp = counter; temp--; Thread.Sleep(1); counter = temp; Console.WriteLine("[{0}] In Decrementer. Counter: {1}.", Thread.CurrentThread.Name, counter); } } finally { Monitor.Exit(this); } } void Incrementer( ) { try { Monitor.Enter(this); while (counter < 10) { long temp = counter; temp++; Thread.Sleep(1); counter = temp; Console.WriteLine("[{0}] In Incrementer. Counter: {1}", Thread.CurrentThread.Name, counter); } // I'm done incrementing for now, let another // thread have the Monitor Monitor.Pulse(this); } finally { Console.WriteLine("[{0}] Exiting...", Thread.CurrentThread.Name); Monitor.Exit(this); } } private long counter = 0; }

220

Thread v S ng B

Gvhd: Nguyn Tn Trn Minh Khang

} Kt qu: Started thread Thread1 [Thread1] In Decrementer. Started thread Thread2 [Thread2] In Incrementer. [Thread2] In Incrementer. [Thread2] In Incrementer. [Thread2] In Incrementer. [Thread2] In Incrementer. [Thread2] In Incrementer. [Thread2] In Incrementer. [Thread2] In Incrementer. [Thread2] In Incrementer. [Thread2] In Incrementer. [Thread2] Exiting... [Thread1] In Decrementer. [Thread1] In Decrementer. [Thread1] In Decrementer. [Thread1] In Decrementer. [Thread1] In Decrementer. [Thread1] In Decrementer. [Thread1] In Decrementer. [Thread1] In Decrementer. [Thread1] In Decrementer. [Thread1] In Decrementer. All my threads are done.

Counter: 0. Gotta Wait! Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: Counter: 1 2 3 4 5 6 7 8 9 10 9. 8. 7. 6. 5. 4. 3. 2. 1. 0.

20.3 Race condition v DeadLock


ng b ha thread kh rc ri trong nhng chng trnh phc tp. Bn cn phi cn thn kim tra v gii quyt cc vn lin quan n ng b ha thread: race condition v deadlock

20.3.1 Race condition


Mt iu kin tranh ua xy ra khi s ng n ca ng dng ph thuc vo th t hon thnh khng kim sot c ca 2 thread c lp vi nhau. V d: gi s bn c 2 thread. Thread 1 tin hnh m tp tin, thread 2 tin hnh ghi ln cng tp tin . iu quan trng l bn cn phi iu khin thread 2 sao cho n ch tin hnh cng vic sau khi thread 1 tin hnh xong. Nu khng, thread 1 s khng m c tp tin v tp tin b thread 2 m ghi. Kt qu l chng trnh s nm ra exception hoc t hn na l crash. gii quyt vn trong v d trn, bn c th tin hnh join thread 2 vi thread 1 hoc thit lp monitor.

20.3.2 Deadlock
Gi s thread A nm monitor ca ti nguyn X v ang ch monitor ca ti nguyn Y. Trong khi th thread B li nm monitor ca ti nguyn Y v ch

221

Thread v S ng B

Gvhd: Nguyn Tn Trn Minh Khang

monitor ca ti nguyn X. 2 thread c ch i ln nhau m khng thread no c th thot ra khi tnh trng ch i. Tnh trng trn gi l deadlock. Trong mt chng trnh nhiu thread, deadlock rt kh pht hin v g li. Mt hng dn trnh deadlock l gii phng tt c lock ang s hu nu tt c cc lock cn nhn khng th nhn ht c. Mt hng dn khc l gi lock cng t cng tt.

222

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

Chng 21 Lung d liu.


Khi mun c hay ghi d liu vo/ra tp tin hay mun truyn d liu t my ny sang my khc, ta phi t chc d liu theo cu trc tun t cc byte hay cc gi tin . iu ny d lin tng d liu nh l cc lung d liu chy t t ngun n ch. Th vin .NET Framework cung cp cc lp Stream (Stream v cc lp tha k t n) chng trnh c th s dng trong cc thao tc nhp xut d liu nh doc/ghi tp tin, truyn d liu qua mng

21.1 Tp tin v th mc
Cc lp cp trong chng ny thuc v vng tn System.IO. Cc lp ny bao gm lp File m phng cho mt tp tin trn a, v lp Directory m phng cho mt th mc trn a.

21.1.1 Lm vic vi th mc
Lp Directory c nhiu phng thc dnh cho vic to, di chuyn, duyt th mc. Cc phng thc trong lp Directory u l phng thc tnh;v vy khng cn phi to mt th hin lp Directory m c th truy xut trc tip t tn lp. Lp DirectoryInfo l lp tng t nh lp Directory. N cung cc tt c cc phng thc m lp Directory c ng thi b sung nhiu phng thc hu ch hn cho vic duyt cu trc cy th mc. Lp DirectoryInfo tha k t lp FileSystemInfo, v v vy cng tha k lp MarshalByRefObj. Lp DirectoryInfo khng c phng thc tnh, v vy cn to mt th hin lp trc khi s dng cc phng thc. C mt khc bit quan trong gia Directory v DirectoryInfo l cc phng thc ca lp Directory s c kim tra v bo mt mi khi c gi trong khi i tng DirectoryInfo ch kim tra mt ln vo lc khi to, cc phng thc v vy s thc hin nhanh hn. Di y l bng lit k cc phng thc quan trng ca hai lp
Bng 21-1 Cc phng thc lp Directory
Phong thc
CreateDirectory() Delete()

Gii thch To tt c cc th mc v th mc con trong ng dn tham s. Xo th mc v cc ni dung ca n.

223

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

Exists( ) GetCreationTime( ) SetCreationTime( ) GetCurrentDirectory( ) SetCurrentDirectory( ) GetDirectories( ) GetDirectoryRoot( ) GetFiles( ) GetLastAccessTime( ) SetLastAccessTime( ) GetLastWriteTime( ) SetLastWriteTime( ) GetLogicalDrives( ) GetParent() Move()

Tr v kt qu kiu logic, ng nu ng dn n th mc tn ti (c ngha l th mc tn ti). Ly/thit t ngy gi to th mc Ly/thit t th mc hin hnh Ly v mt mng cc th mc con mt th mc Tr v th mc gc ca ng dn Tr v mng chui tn cc tp tin cha trong mt th mc Ly/thit t ngy gi ln truy cp cui cng n th mc Ly/thit t ngy gi ln chnh sa cui cng ln th mc Tr v tn ca tt c cc a logic theo nh dng <_a>:\ Tr v th mc cha ca mt ng dn. Di chuyn th mc (c ni dung) n mt v tr khc.

Bng 21-2 Cc phng thc/property lp DirectoryInfo


Phong thc/property Attributes CreationTime Exists Extension FullName LastAccessTime LastWriteTime Name Parent Root Create( ) CreateSubdirectory() Delete( ) GetDirectories( ) GetFiles( ) GetFileSystemInfos() MoveTo( ) ngha Tha k t FileSystemInfo, ly/thit t thuc tnh ca tp tin hin hnh. Tha k t FileSystemInfo, ly/thit t thi gian to tp tin Tr v ng nu th mc tn ti Tha k t FileSystemInfo, phn m rng tp tin Tha k t FileSystemInfo, ng dn y ca tp tin hay th mc Tha k t FileSystemInfo, ngy gi truy cp cui cng Tha k t FileSystemInfo, ngy gi chnh sa cui cng Tn th mc Ly th mc cha Ly th mc gc ca ng dn. To mt th mc To mt hoc nhiu th mc con Xa mt th mc v ni dung ca n Tr v danh sch cc th mc con ca th hin hin c Ly danh mc cc tp tin ca th mc Nhn v mng cc i tng FileSystemInfo Di chuyn DirectoryInfo v ni dung ca n sang ng dn khc

224

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

Phong thc/property Refresh( )

ngha Lm ti trng thi i tng

21.1.2 To i tng DirectoryInfo


duyt cu trc cy th mc, ta cn to mt th hin ca lp DirectoryInfo. Lp DirectoryInfo khng ch cung cp phng thc ly v tn cc tp tin v th mc con cha trong mt th mc m cn cho php ly v cc i tng FileInfo v DirectoryInfo, cho php ta thc hin vic qun l cc cu trc cy th mc, hay thc hin cc thao tc qui. Khi to mt i tng DirectoryInfo bng tn ca th mc mun tham chiu.
DirectoryInfo dir = new DirectoryInfo(@"C:\winNT");

Ta c th thc hin cc phng thc lit k bng trn. Di y l on m ngun v d. V d 21-1. Duyt cc th mc con
using System; using System.IO; namespace Programming_CSharp { class Tester { public static void Main() { Tester t = new Tester( ); // mt mt th mc string theDirectory = @"c:\WinNT"; // duyt th mc v hin th ngy truy cp gn nht // v tt c cc th mc con DirectoryInfo dir = new DirectoryInfo(theDirectory); t.ExploreDirectory(dir); // hon tt. in ra s lng thng k Console.WriteLine( "\n\n{0} directories found.\n", dirCounter); } // vi mi th mc tm thy, n gi chnh n private void ExploreDirectory(DirectoryInfo dir) { indentLevel++; // cp th mc // nh dng cho vic trnh by for (int i = 0; i < indentLevel; i++) Console.Write(" "); // hai khong trng cho mi cp // in th mc v ngy truy cp gn nht Console.WriteLine("[{0}] {1} [{2}]\n", indentLevel, dir.Name, dir.LastAccessTime); // ly tt c th mc con ca th mc hin ti // quy tng th mc DirectoryInfo[] directories = dir.GetDirectories( ); foreach (DirectoryInfo newDir in directories) {

225

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

dirCounter++; //tng bin m ExploreDirectory(newDir); } indentLevel--; // gim cp th mc } // cc bin thnh vin tnh cho vic thng k v trnh by static int dirCounter = 1; static int indentLevel = -1; // so first push = 0 } } Kt qu (mt phn): [2] logiscan [5/1/2001 3:06:41 PM] [2] miitwain [5/1/2001 3:06:41 PM] [1] Web [5/1/2001 3:06:41 PM] [2] printers [5/1/2001 3:06:41 PM] [3] images [5/1/2001 3:06:41 PM] [2] Wallpaper [5/1/2001 3:06:41 PM] 363 directories found.

Chng trnh to mt i tng DirectoryInfo gn vi th mc WinNT. Sau gi hm ExploreDirectory vi tham s l i tng DirectoryInfo va to. Hm s hin th cc thng tin v th mc ny v sau ly tt c cc th mc con. lit k danh sch cc th mc con, hm gi phng thc GetDirectories. Phng thc ny tr v mng cc i tng DirectoryInfo. Bng cch gi qui chnh n, hm lit k xung cc th mc con v th mc con ca th mc con Kt qu cui cng l cu trc cy th mc c hin th.

21.1.3 Lm vic vi tp tin.


i tng DirectoryInfo cng tr v danh sch cc i tng FileInfo l cc tp tin cha trong th mc. Cc i tng ny m t thng tin v tp tin. Th vin .NET cng cung cp hai lp File v FileInfo tng t nh vi trng hp th mc. Lp File ch c cc phng thc tnh v lp FileInfo th khng c phng thc tnh no c. Hai bng di y lit k cc phng thc ca hai lp ny
Bng 21-3 Cc phng thc lp File
Phng thc AppendText() Copy() Create() CreateText() Delete() Exists() GetAttributes() Gii thch To mt StreamWriter cho php thm vn bn vo tp tin Sao chp mt tp tin t tp tin c To mt tp tin mi To mt StreamWriter cho php vit mi vn bn vo tp tin Xo mt tp tin Tr v ng nu tp tin tn ti Ly/ thit t cc thuc tnh ca mt tp tin

226

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

Phng thc SetAttributes() GetCreationTime() SetCreationTime() GetLastAccessTime() SetLastAccessTime() GetLastWriteTime() SetLastWriteTime() Move() OpenRead() OpenWrite()

Gii thch

Ly / thit t thi gian to tp tin Ly / thit t thi gian truy cp tp tin ln cui Ly / thit t thi gian chnh sa tp tin ln cui Di chuyn tp tin n v tr mi, c th dng i tn tp tin M mt tp tin c (khng ghi) M mt tp tin cho php ghi.

Bng 21-4 Cc phng thc / property lp FileInfo


Phng thc / property Attributes() CreationTime Directory Exists Extension FullName LastAccessTime LastWriteTime Length Name AppendText() CopyTo() Create() Delete() MoveTo() Open() OpenRead() OpenText() OpenWrite() Gii thch Tha k t FileSystemInfo. Ly/thit t thuc tnh tp tin Tha k t FileSystemInfo. Ly/thit t thi gian to tp tin Ly th mc cha Xc nh tp tin c tn ti cha? Tha k t FileSystemInfo. Phn m rng ca tp tin Tha k t FileSystemInfo. ng dn y ca tp tin Tha k t FileSystemInfo. Thi im truy cp gn nht Tha k t FileSystemInfo. Thi im ghi gn nht. Kvh thc tp tin Tn tp tin To i tng StreamWriter ghi thm vo tp tin Sao chp sang mt tp tin mi To mt tp tin mi Xa tp tin Dch chuyn tp tin, cng dng i tn tp tin M mt tp tin vi cc quyn hn To i tng FileStream cho vic c tp tin To i tng StreamReader cho vic c tp tin To i tng FileStream cho vic ghi tp tin

V d 21-2 sa li t v d 12-1, thm on m ly FileInfo ca mi th mc. i tng ny dng hin th tn, kch thc v ngy truy cp cui cng ca tp tin.

227

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

V d 21-2. Duyt tp tin v th mc con


using System; using System.IO; namespace Programming_CSharp { class Tester { public static void Main( ) { Tester t = new Tester( ); string theDirectory = @"c:\WinNT"; DirectoryInfo dir = new DirectoryInfo(theDirectory); t.ExploreDirectory(dir); Console.WriteLine( "\n\n{0} files in {1} directories found.\n", fileCounter,dirCounter ); } private void ExploreDirectory(DirectoryInfo dir) { indentLevel++; for (int i = 0; i < indentLevel; i++) Console.Write(" "); Console.WriteLine("[{0}] {1} [{2}]\n", indentLevel, dir.Name, dir.LastAccessTime); // ly tt c cc tp tin trong th mc v // in tn, ngy truy cp gn nht, kch thc ca chng FileInfo[] filesInDir = dir.GetFiles( ); foreach (FileInfo file in filesInDir) { // li vo mt khong pha di th mc // phc v vic trnh by for (int i = 0; i < indentLevel+1; i++) Console.Write(" "); // hai khong trng cho mi cp Console.WriteLine("{0} [{1}] Size: {2} bytes", file.Name, file.LastWriteTime, file.Length); fileCounter++; } DirectoryInfo[] directories = dir.GetDirectories( ); foreach (DirectoryInfo newDir in directories) { dirCounter++; ExploreDirectory(newDir); } indentLevel--; } // cc static static static } } bin tnh cho vic thng k v trnh by int dirCounter = 1; int indentLevel = -1; int fileCounter = 0;

228

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

Kt qu (mt phn): [0] WinNT [5/1/2001 3:34:01 PM] ActiveSetupLog.txt [4/20/2001 10:42:22 AM] Size: 10620 bytes actsetup.log [4/20/2001 12:05:02 PM] Size: 8717 bytes Blue Lace 16.bmp [12/6/1999 4:00:00 PM] Size: 1272 bytes [2] Wallpaper [5/1/2001 3:14:32 PM] Boiling Point.jpg [4/20/2001 8:30:24 AM] Size: 28871 bytes Chateau.jpg [4/20/2001 8:30:24 AM] Size: 70605 bytes Windows 2000.jpg [4/20/2001 8:30:24 AM] Size: 129831 bytes 8590 files in 363 directories found.

21.1.4 Chnh sa tp tin


i tng FileInfo c th dng to, sao chp, i tn v xo mt tp tin. V d di y to mt th mc con mi, sao chp mt tp tin, i tn vi tp tin, v sau xa ton b th mc ny. V d 21-3. To th mc con v thao tc cc tp tin
using System; using System.IO; namespace Programming_CSharp { class Tester { public static void Main( ) { Tester t = new Tester( ); string theDirectory = @"c:\test\media"; DirectoryInfo dir = new DirectoryInfo(theDirectory); t.ExploreDirectory(dir); } private void ExploreDirectory(DirectoryInfo dir) { // to mi mt th mc con string newDirectory = "newTest"; DirectoryInfo newSubDir = dir.CreateSubdirectory(newDirectory); // ly tt c cc tp tin trong th mc v // sao chp chng sang th mc mi FileInfo[] filesInDir = dir.GetFiles( ); foreach (FileInfo file in filesInDir) { string fullName = newSubDir.FullName + "\\" + file.Name; file.CopyTo(fullName); Console.WriteLine("{0} copied to newTest", file.FullName); } // ly cc tp tin va sao chp filesInDir = newSubDir.GetFiles( ); // hy hoc i tn mt vi tp tin

229

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

int counter = 0; foreach (FileInfo file in filesInDir) { string fullName = file.FullName; if (counter++ %2 == 0) { file.MoveTo(fullName + ".bak"); Console.WriteLine("{0} renamed to {1}", fullName,file.FullName); } else { file.Delete( ); Console.WriteLine("{0} deleted.", fullName); } } newSubDir.Delete(true); // hy th mc con ny } } }

Kt qu (mt phn): c:\test\media\Bach's Brandenburg Concerto No. 3.RMI copied to newTest c:\test\media\Beethoven's 5th Symphony.RMI copied to newTest c:\test\media\Beethoven's Fur Elise.RMI copied to newTest c:\test\media\canyon.mid copied to newTest c:\test\media\newTest\Bach's Brandenburg Concerto No. 3.RMI renamed to c:\test\media\newTest\Bach's Brandenburg Concerto No. 3.RMI.bak c:\test\media\newTest\Beethoven's 5th Symphony.RMI deleted. c:\test\media\newTest\Beethoven's Fur Elise.RMI renamed to c:\test\media\newTest\Beethoven's Fur Elise.RMI.bak c:\test\media\newTest\canyon.mid deleted.

21.2 c v ghi d liu


c v ghi d liu l nhim v chnh ca cc lung, Stream. Stream h tr c hai cch c ghi ng b hay bt ng b. .NET Framework cung cp sn nhiu lp tha k t lp Stream, bao gm FileStream, MemoryStream v NetworkStream. Ngoi ra cn c lp BufferedStream cung cp vng m xut nhp c dng thm vi cc lung khc. Bng di y tm tt ngha s dng ca cc lung
Bng 21-5 ngha cc lung
Lp Stream BinaryReader / BinaryWriter File, FileInfo, Directory, DirectoryInfo Gii thch Lp tru tng cung cp h tr c / ghi theo byte c / ghi cc kiu d liu gc (primitive data type) theo tr nh phn Cung cp cc ci t cho lp FileSystemInfo, bao gm vic to, dch chuyn, i tn, xo tp tin hay th mc

230

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

FileStream TextReader, TextWriter, StringReader, StringWriter

c t / ghi ln tp tin. Mc nh m tp tin ng b, h tr truy cp tp tin bt ng b. TextReader v TextWriter l hai lp tru tng c thit k cho vic xut nhp k t Unicode.StringReader v StringWrite ci t hai lp trn dnh cho vic c ghi vo mt chui Lung dng lm vng m cho cc lung khc nh NetworkStream. Lp FileStream t ci t sn vng m. Lp ny nhm tng cng hiu nng cho lung gn vi n. Lung d liu trc tip t b nh. Thng c dng nh vng m tm. Lung cho kt ni mng.

BufferedStream

MemoryStream NetworkStream

21.2.1 Tp tin nh phn


Phn ny s bt u s dng lp c s Stream c tp tin nh phn. Lp Stream c rt nhiu phng thc nhng quan trng nht l nm phng thc Read(), Write(), BeginRead(), BeginWrite() v Flush(). thao tc tp tin nh phn (hay c tp tin theo kiu nh phn), ta bt u to mt cp i tng Stream, mt c, mt vit.
Stream inputStream = File.OpenRead(@"C:\test\source\test1.cs"); Stream outputStream = File.OpenWrite(@"C:\test\source\test1.bak");

m mt tp tin c v vit, ta s dng hai hm tnh OpenRead() v OpenWrite() ca lp File vi tham s l ng dn tp tin. Tip theo ta c d liu t inputStream cho n khi khng cn d liu na v s ghi d liu c c vo outputStream. Hai hm lp Stream phc v vic c ghi d liu l Read() v Write().
while( (bytesRead = inputStream.Read(buffer,0,SIZE_BUFF)) > 0 ) { outputStream.Write(buffer,0,bytesRead); }

Hai hm c cng mt s lng v kiu tham s truyn vo. u tin l mt mng cc byte (c gi l vng m buffer) dng cha d liu theo dang byte. Tham s th hai cho bit v tr bt u c hay ghi trn vng m, tham s cui cng cho bit s byte cn c hay ghi. i vi hm Read() cn tr v s byte m Stream c c, c th bng hay khc gi tr tham s th ba. V d 21-4. Ci t vic c v ghi tp tin nh phn
using System; using System.IO; namespace Programming_CSharp { class Tester {

231

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

const int SizeBuff = 1024; public static void Main( ) { Tester t = new Tester( ); t.Run( ); } private void Run( ) { // c t tp tin ny Stream inputStream = File.OpenRead( @"C:\test\source\test1.cs"); // ghi vo tp tin ny Stream outputStream = File.OpenWrite( @"C:\test\source\test1.bak"); // to vng m cha d liu byte[] buffer = new Byte[SizeBuff]; int bytesRead; // sau khi c d liu xut chng ra outputStream while ( (bytesRead = inputStream.Read(buffer,0,SizeBuff)) > 0 ) { outputStream.Write(buffer,0,bytesRead); } // ng tp tin trc khi thot inputStream.Close( ); outputStream.Close( ); } } }

Kt qu sau khi chay chng trnh l mt bn sao ca tp tin u vo (test1.cs) c to trong cng th mc vi tn test1.bak

21.2.2 Lung c vng m


Trong v d trc ta thc hin vic ghi ln tp tin theo tng khi buffer, nh vy h iu hnh s thc thi vic ghi tp tin ngay sau lnh Write(). iu ny c th lm gim hiu nng thc thi do phi ch cc thao tc c hc ca a cng vn rt chm. Lung c vng m s khc phc nhc im ny bng cch sau: khi c lnh Write() d liu, lung s khng gi h iu hnh ngay m s gi trn vng m (thc cht l b nh), ch cho n khi d liu ln s ghi mt lt ln tp tin. Lp BufferedStream l ci t cho lung c vng m. to mt lung c vng m trc tin ta vn to lung Stream nh trn
Stream inputStream = File.OpenRead(@"C:\test\source\folder3.cs"); Stream outputStream = File.OpenWrite(@"C:\test\source\folder3.bak");

Sau truyn cc lung ny cho hm dng ca BufferedStream


BufferedStream bufferedInput = new BufferedStream(inputStream); BufferedStream bufferedOutput = new BufferedStream(outputStream);

232

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

T y ta s dng bufferedInput v bufferedOutput thay cho inputStream v outputStream. Cch s dng l nh nhau: cng dng phng thc Read() v Write()
while((bytesRead = bufferedInput.Read(buffer,0,SIZE_BUFF))>0 ) { bufferedOutput.Write(buffer,0,bytesRead); }

C mt khc bit duy nht l phi nh gi hm Flush() chc chn d liu c "tng" t vng buffer ln tp tin.
bufferedOutput.Flush( );

Lnh ny nhm yu cu h iu hnh sao chp d liu t vng nh buffer ln a cng. V d 21-5. Ci t lung c vng m
using System; using System.IO; namespace Programming_CSharp { class Tester { const int SizeBuff = 1024; public static void Main( ) { Tester t = new Tester( ); t.Run( ); } private void Run( ) { // to mt lung nh phn Stream inputStream = File.OpenRead( @"C:\test\source\folder3.cs"); Stream outputStream = File.OpenWrite( @"C:\test\source\folder3.bak"); // to lung vng m kt buc vi lung nh phn BufferedStream bufferedInput = new BufferedStream(inputStream); BufferedStream bufferedOutput = new BufferedStream(outputStream); byte[] buffer = new Byte[SizeBuff]; int bytesRead; while ( (bytesRead = bufferedInput.Read(buffer,0,SizeBuff)) > 0 ) { bufferedOutput.Write(buffer,0,bytesRead); } bufferedOutput.Flush( ); bufferedInput.Close( ); bufferedOutput.Close( ); } } }

233

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

Vi tp tin c dung lng ln, chng trnh ny s chy nhanh hn chng trnh v d trc.

21.2.3 Lm vic vi tp tin vn bn


i vi cc tp tin ch cha vn bn, ta s dng hai lung StreamReader v StreamWriter cho vic c v ghi. Hai lp ny c thit k thao tc vi vn bn d dng hn. V d nh chng cung cp hm ReadLine() v WriteLine() c v ghi mt dng vn bn. to mt th hin StreamReader ta gi phng thc OpenText() ca lp FileInfo.
FileInfotheSourceFile = new FileInfo (@"C:\test\source\test1.cs"); StreamReader stream = theSourceFile.OpenText( );

Ta c tng dng vn bn ca tp tin cho n ht


do { text = stream.ReadLine( ); } while (text != null);

to i tng StreamWriter ta truyn cho hm khi dng ng dn tp tin


StreamWriter writer = new StreamWriter(@"C:\test\source\folder3.bak",false);

tham s th hai thuc kiu bool, nu tp tin tn ti, gi tr true s ghi d liu mi vo cui tp tin, gi tr false s xa d liu c, d liu mi s ghi d liu c. V d 21-6. c v ghi tp tin vn bn
using System; using System.IO; namespace Programming_CSharp { class Tester { public static void Main( ) { Tester t = new Tester( ); t.Run( ); } private void Run( ) { // m mt tp tin FileInfo theSourceFile = new FileInfo( @"C:\test\source\test.cs"); // to lung c vn bn cho tp tin StreamReader reader = theSourceFile.OpenText( ); // to lung ghi vn bn cho tp tin xut StreamWriter writer = new StreamWriter( @"C:\test\source\test.bak",false); // to mt bin chui l gi mt dng vn bn

234

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

string text; // c ton b tp tin theo tng dng // ghi ra mn hnh console v tp tin xut do { text = reader.ReadLine( ); writer.WriteLine(text); Console.WriteLine(text); } while (text != null); // ng tp tin reader.Close( ); writer.Close( );

} } }

Khi thc thi chng trnh ni dung tp tin ngun c ghi ln tp tin mi ng thi xut ra mn hnh console.

21.3 Bt ng b nhp xut


Cc v d c trnh by trn s dng k thut ng b ha trong nhp xut d liu (synchronous I/O), c ngha l chng trnh s tm ngng trong lc h iu hnh thc hin vic c hay ghi d liu. iu ny c th lm chng trnh tn thi gian v ch, c bit khi lm vic vi cc a c tc chm hay dung lng ng truyn mng thp. K thut bt ng b nhp xut (asynchronous I/O) c dng gii quyt vn ny. Ta c th thc hin cc cng vic khc trong khi ch h thng hp xut c/ghi d liu. K thut ny c ci t trong phng thc BeginRead() v BeginWrite() ca lp Stream. Mu cht ca phng thc Begin*() l khi c gi mt tiu trnh mi s c to v lm cng vic nhp xut, tiu trnh c s thc hin cng vic khc. Sau khi hon tt vic c/ghi, thng bo c gi n hm callback thng qua mt deleagte. Ta c th thao tc vi cc d liu va c c/ghi, thc hin mt cng vic c/ghi khc v li quay i lm cng vic khc. Phng thc BeginRead() yu cu nm tham s, ba tham s tng t hm Read, hai tham s (ty chn) cn li l: delegate AsyncCallback gi hm callback v tham s cn li l object dng phn bit gia cc thao tc nhp xut bt ng b khc nhau. Trong v d d ny ta s to mt mng byte lm vng m, v mt i tng
Stream
public class AsynchIOTester { private Stream inputStream; private byte[] buffer; const int BufferSize = 256;

235

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

mt bin thnh vin kiu delegate m phng thc BeginRead() yu cu


private AsyncCallback myCallBack; // delegated method

Delegate AsyncCallback khai bo trong vng tn System nh sau


public delegate void AsyncCallback (IAsyncResult ar);

To mt hm callback ng gi trong delegate


void OnCompletedRead(IAsyncResult asyncResult)

Di y l cch hot ng ca v d. Trong hm Main() ta khi to v cho thc thi lp kim th AsyncIOTester
public static void Main( ) { AsynchIOTester theApp = new AsynchIOTester( ); theApp.Run( ); }

Hm dng khi to cc bin thnh vin


AsynchIOTester( ) { inputStream = File.OpenRead(@"C:\test\source\AskTim.txt"); buffer = new byte[BufferSize]; myCallBack = new AsyncCallback(this.OnCompletedRead); }

Phng thc Run() s gi BeginRead()


inputStream.BeginRead( buffer, // cha kt qu 0, // v tr bt u buffer.Length, // kch thc vng m myCallBack, // callback delegate null); // i tng trng thi

Sau thc hin cng vic khc, trng hp ny l vng lp for thc hin 500.000 ln.
for (long i = 0; i < 500000; i++) { if (i%1000 == 0) { Console.WriteLine("i: {0}", i); } }

Sau khi vic c hon tt hm callback c gi


void OnCompletedRead(IAsyncResult asyncResult) {

iu u tin l phi bit s lng byte tht s c c bng cch gi hm


EndRead()
int bytesRead = inputStream.EndRead(asyncResult);

Sau thao tc trn d liu c c (in ra console), v li gi tip mt BeginRead() thc hin nhp xut bt ng b mt ln na,
if (bytesRead > 0)

236

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

string s = Encoding.ASCII.GetString (buffer, 0, bytesRead); Console.WriteLine(s); inputStream.BeginRead(buffer, 0, buffer.Length, myCallBack, null);

Hiu qu ca chng trnh l ta c th thc hin cc cng vic khng cn kt qu ca vic c d liu khc. V d hon chnh lit k di y V d 21-7. ci t nhp xut bt ng b
using using using using System; System.IO; System.Threading; System.Text;

namespace Programming_CSharp { public class AsynchIOTester { private Stream inputStream; // delegated private AsyncCallback myCallBack; // vng nh buffer lu gi liu c c private byte[] buffer; // kch thc buffer const int BufferSize = 256; AsynchIOTester( ) { // m mt lung nhp inputStream = File.OpenRead( @"C:\test\source\AskTim.txt"); // cp pht vng buffer buffer = new byte[BufferSize]; // gn mt hm callback myCallBack = new AsyncCallback(this.OnCompletedRead); } public static void Main( ) { AsynchIOTester theApp = new AsynchIOTester(); theApp.Run( ); } void Run() { inputStream.BeginRead( buffer, // cha kt qu 0, // v tr bt u trn buffer buffer.Length, // kch thc buffer myCallBack, // callback delegate null); // i tng trng thi cc b // lm chuyn g trong lc c d liu for (long i = 0; i < 500000; i++) { if (i%1000 == 0) {

237

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

} }

Console.WriteLine("i: {0}", i);

} }

// hm callback void OnCompletedRead(IAsyncResult asyncResult) { int bytesRead = inputStream.EndRead(asyncResult); // nu c c d liu if (bytesRead > 0) { // chuyn n thnh chui String s = Encoding.ASCII.GetString(buffer, 0, bytesRead); Console.WriteLine(s); inputStream.BeginRead( buffer, 0, buffer.Length, myCallBack, null); } }

Kt qu (mt phn) i: 47000 i: 48000 i: 49000 Date: January 2001 From: Dave Heisler To: Ask Tim Subject: Questions About O'Reilly Dear Tim, I've been a programmer for about ten years. I had heard of O'Reilly books,then... Dave, You might be amazed at how many requests for help with school projects I get; i: 50000 i: 51000 i: 52000

Trong cc ng dng thc t, ta s tng tc vi ngi dng hoc thc hin cc tnh ton trong khi cng vic nhp xut tp tin hay c s d liu c thc hin mt cch bt ng b mt tiu trnh khc.

21.4 Serialization
Serialize c ngha l sp theo th t. Khi ta mun lu mt i tng xung tp tin trn a t lu tr, ta phi nh ra trnh t lu tr ca d liu trong i tng. Khi cn ti to li i tng t thng tin trn tp tin lu tr, ta s "np" ng theo trnh t nh trc . y gi l qu trnh Serialize. Ni chnh xc hn, serialize l tin trnh bin i trng thi ca i tng theo mt nh dng c th c lu tr hay dch chuyn (transfer).

238

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

.NET Framework cung cp 2 k thut serialize: Binary serialize (serialize nh phn): cch ny gi nguyn kiu d liu, thch hp cho vic gi nguyn cu trc i tng. C th dng k thut ny chia s i tng gia cc ng dng bng cch serialize vo vng nh clipboard; hoc serialize vo cc lung, a t, b nh, trn mng ; hoc truyn cho my tnh xa nh mt tham tr ("by-value object") XML v SOAP Serialize: ch serialize cc thuc tnh public, v khng gi nguyn kiu d liu. Tuy nhin XML v SOAP l cc chun m nn k thut khng b cc hn ch v giao tip gia cc ng dng. Cc i tng c s u c kh nng serialize. i tng ca ta c th serialize, trc tin cn thm khai bo attribute [Serialize] cho lp i tng . Nu i tng c cha cc i tng khc th cc i tng phi c kh nng serialize.

21.4.1 Lm vic vi Serialize


Trc tin, ta to mt i tng Sumof lm v d cho vic Serialize. i tng c cc bin thnh vin sau:
private int startNumber = 1; private int endNumber; private int[] theSums;

mng theSums uc m t: phn t theSum[i] cha gi tr l tng t startNumber cho n startNumber + i.

21.4.1.1 serialize i tng


Trc tin thm attribute [Serialize] vo trc khai bo i tng
[Serializable] class SumOf

Ta cn mt tp tin l tr i tng ny, to mt FileStream


FileStream fileStream = new FileStream("DoSum.out",FileMode.Create);

Sau khi to mt Formatter, gi phng thc Serialize ca n.


binaryFormatter.Serialize(fileStream,this);

i tng Sumof c Serialize.

21.4.1.2 Deserialize i tng


Deserialize l tin trnh ngc vi serialize, tin trnh ny c d liu c serialize ti to li i tng.

Khai bo phng thc tnh DeSerialize cho tin trnh ny


public static SumOf DeSerialize( ) { FileStream fileStream = new FileStream("DoSum.out",FileMode.Open); BinaryFormatter binaryFormatter = new BinaryFormatter( );

239

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

return (SumOf) binaryFormatter.Deserialize(fileStream); fileStream.Close( );

V d 21-1 Serialize v Deserialize i tng


using using using using System; System.IO; System.Runtime.Serialization; System.Runtime.Serialization.Formatters.Binary;

namespace Programming_CSharp { [Serializable] class SumOf { public static void Main( ) { Console.WriteLine("Creating first one with new..."); SumOf app = new SumOf(1,10); Console.WriteLine("Creating second one with deserialize..."); SumOf newInstance = SumOf.DeSerialize( ); newInstance.DisplaySums( ); } public SumOf(int start, int end) { startNumber = start; endNumber = end; ComputeSums( ); DisplaySums( ); Serialize( ); } private void ComputeSums( ) { int count = endNumber - startNumber + 1; theSums = new int[count]; theSums[0] = startNumber; for (int i=1,j=startNumber + 1;i<count;i++,j++) { theSums[i] = j + theSums[i-1]; } } private void DisplaySums( ) { foreach(int i in theSums) { Console.WriteLine("{0}, ",i); } } private void Serialize( ) { Console.Write("Serializing..."); // to mt file stream hay ghi

240

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

FileStream fileStream = new FileStream("DoSum.out",FileMode.Create); //s dung binary formatter BinaryFormatter binaryFormatter = new BinaryFormatter( ); // serialize binaryFormatter.Serialize(fileStream,this); Console.WriteLine("...completed"); fileStream.Close( ); } public static SumOf DeSerialize( ) { FileStream fileStream = new FileStream("DoSum.out",FileMode.Open); BinaryFormatter binaryFormatter = new BinaryFormatter( ); return (SumOf) binaryFormatter.Deserialize(fileStream); fileStream.Close( ); } private int startNumber = 1; private int endNumber; private int[] theSums; } }

Kt qu: Creating first one with new... 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, Serializing......completed Creating second one with deserialize... 1, 3, 6, 10, 15, 21, 28, 36, 45, 55,

21.4.2 Handling Transient Data


Theo cch nhn no th serialize kiu V d 21-1 rt lng ph. Gi tr cc phn t trong mng c th tnh bng thut ton v vy khng nht thit phi serialize mng ny (v lm gim ng k dung lng tp tin lu tr).

241

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

CLR bit ta khng mun Serialize bin thnh vin ny, ta t attribute [NonSerialize] trc khai bo:
[NonSerialized] private int[] theSums;

Theo logic, khi deserialize, ta khng th c ngay mng v v vy cn thc hin li cng vic tnh ton mt ln na. Ta c th thc hin trong hm Deserialize, nhng CLR cung cp giao din IDeserializationCallback, ta s ci t giao din ny
[Serializable] class SumOf : IDeserializationCallback

Giao din ny c mt phng thc duy nht l OnDeserialization() m ta phi ci t:


public virtual void OnDeserialization (Object sender) { ComputeSums( ); }

Khi tin trnh Deserialize, phng thc ny s c gi v mng theSums c tnh ton v khi gn. Ci gi m ta phi tr chnh l thi gian dnh cho vic tnh ton ny.
V d 21-2 Lm vic vi di tng nonserialize
using using using using System; System.IO; System.Runtime.Serialization; System.Runtime.Serialization.Formatters.Binary;

namespace Programming_CSharp { [Serializable] class SumOf : IDeserializationCallback { public static void Main( ) { Console.WriteLine("Creating first one with new..."); SumOf app = new SumOf(1,5); Console.WriteLine("Creating second one with deserialize..."); SumOf newInstance = SumOf.DeSerialize( ); newInstance.DisplaySums( ); } public SumOf(int start, int end) { startNumber = start; endNumber = end; ComputeSums( ); DisplaySums( ); Serialize( ); } private void ComputeSums( ) {

242

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

int count = endNumber - startNumber + 1; theSums = new int[count]; theSums[0] = startNumber; for (int i=1,j=startNumber + 1;i<count;i++,j++) { theSums[i] = j + theSums[i-1]; } } private void DisplaySums( ) { foreach(int i in theSums) { Console.WriteLine("{0}, ",i); } } private void Serialize( ) { Console.Write("Serializing..."); FileStream fileStream = new FileStream("DoSum.out",FileMode.Create); BinaryFormatter binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(fileStream,this); Console.WriteLine("...completed"); fileStream.Close( ); } public static SumOf DeSerialize( ) { FileStream fileStream = new FileStream("DoSum.out",FileMode.Open); BinaryFormatter binaryFormatter = new BinaryFormatter( ); return (SumOf) binaryFormatter.Deserialize(fileStream); fileStream.Close( ); } public virtual void OnDeserialization( Object sender ) { ComputeSums( ); } private int startNumber = 1; private int endNumber; [NonSerialized] private int[] theSums; } } Kt qu: Creating first one with new... 1, 3, 6, 10, 15, Serializing......completed Creating second one with deserialize...

243

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

1, 3, 6, 10, 15,

21.5 Isolate Storage


Outlook Express (OE) l trnh nhn/chuyn th in t ca Microsoft. Khi chy trn mi trng a ngi dng nh Windows 2000, n cung cp cho mi ngi dng mt hp th ring. Cc hp th ny lu tr trn a cng thnh nhiu tp tin khc nhau cc th mc thuc quyn ca ngi dng tng ng. Ngoi ra OE cn lu gi cc cc thit t (nh cc ca s hin th, ti khan kt ni ) ca tng ngi dng. .NET Framework cung cp cc lp thc hin cc cng vic ny. N tng t nh cc tp tin .ini ca Windows c, hay gn y hn l kha HKEY_CURRENT_USER trong Registry. Lp thc hin vic ny l lung IsolatedStorageFileStream. Cch s dng tng t nh cc lung khc. Ta khi to bng cch truyn cho hm dng tn tp tin, cc cng vic khc hon ton do lung thc hin.
V d 21-3 Isolated Storage
using System; using System.IO; using System.IO.IsolatedStorage; namespace Programming_CSharp { public class Tester { public static void Main( ) { Tester app = new Tester( ); app.Run( ); } private void Run( ) { // to mt lung cho tp tin cu hnh IsolatedStorageFileStream configFile = new IsolatedStorageFileStream("Tester.cfg",FileMode.Create); // to mt writer ghi ln lung StreamWriter writer = new StreamWriter(configFile); // ghi d liu lr6n tp tin config String output; System.DateTime currentTime = System.DateTime.Now; output = "Last access: " + currentTime.ToString( ); writer.WriteLine(output); output = "Last position = 27,35"; writer.WriteLine(output); // tng sch d liu writer.Flush( ); writer.Close( );

244

Lung d liu.

Gvhd: Nguyn Tn Trn Minh Khang

} }

configFile.Close( );

Sau khi chy on m ny ta, thc hin vic tm kim tp tin test.cfg, ta s thy n trong ng dn sau:
c:\Documents and Settings\Administrator\ApplicationData\ Microsoft\COMPlus\IsolatedStorage\0.4\ Url.wj4zpd5ni41dynqxx1uz0x0aoaraftc\ Url.wj4zpd5ni41dynqxx1uz0ix0aoaraftc\files

M tp tin ny bng Notepad, ni dung tp tin nh sau


Last access: 5/2/2001 10:00:57 AM Last position = 27,35

Ta cng c th c tp tin ny bng chnh lung IsolatedStorageFileStream

245

Lp trnh .NET v COM

Gvhd: Nguyn Tn Trn Minh Khang

Chng 22 Lp trnh .NET v COM


Chng ny ni v nhng iu cn li ca C# (v .NET Framework). Khi xy dng v cng b chun OLE 2.0, sau l COM v ActiveX, Microsoft qung co mt cch rm r v "kh nng" lp trnh cc thnh phn, sau gn chng li c cc ng dng. Bn cnh l kh nng vit mt ln dng cho tt c ngn ng ca COM. Tuy nhin COM vn vng mc mt s hn ch nh vn phin bn v kh "kh nut". .NET Framework mi ra i li mang mt kin trc khc, khng hn ch v ngn ng, gii quyt "xong" vn phin bn. Tuy nhin trong cc cng ty hin nay vn cn "v s COM", v .NET Framework buc phi tip tc h tr COM. Di y l cc vn m .NET Framework gii quyt c: Hiu v cho php s dng cc ActiveX control trong mi trng Vs.NET Hiu v cho php s dng cc i tng COM Cho php chuyn mt lp .NET thnh mt COM Ngoi ra, nh gii thiu C# h tr kiu con tr ca C++ vi mc ch c c s mm do ca C/C++. Kiu con tr c khuyn khng nn s dng v on m dng con tr c xem l khng an ton. N ch thch hp cho cc thao tc vi cc COM, cc th vin hm DLL, hay gi trc tip n cc Win API.

22.1 P/Invoke
Khi u Platform invoke facility (P/Invoke - d dng gi cc giao din lp trnh ca h iu hnh/sn din) c d nh cung cp mt cch thc truy cp n cc hm Windows API, nhng ta c th dng n gi cc hm th vin DLL. V d sp trnh by s dng hm Win API MoveFile ca th vin kernal32.dll. Ta khai bo phng thc static extern bng attribute DllImport nh sau:
[DllImport("kernel32.dll", EntryPoint="MoveFile", ExactSpelling=false, CharSet=CharSet.Unicode, SetLastError=true)] static extern bool MoveFile( string sourceFile, string destinationFile);

Lp DllImport (cng l lp DllImportAttribute) ch ra mt phng thc khng c qun l (unmanaged) c gi thng qua P/Invoke. Cc tham s c gii thch nh sau:
EntryPoint: Tn hm c gi ExactSpelling: t gi tr false khng phn bit hoa thng CharSet: tp k t thao tc trn cc tham s kiu chui

246

Lp trnh .NET v COM

Gvhd: Nguyn Tn Trn Minh Khang

SetLastError: t gi tr true c php gi hm GetLastError (Win API) kim tra li

V d 22-1 S dng P/Invoke gi WinAPI


using System; using System.IO; using System.Runtime.InteropServices; namespace Programming_CSharp { class Tester { // khai bo hm WinAPI mun gi P/Invoke [DllImport("kernel32.dll", EntryPoint="MoveFile", ExactSpelling=false, CharSet=CharSet.Unicode, SetLastError=true)] static extern bool MoveFile( string sourceFile, string destinationFile); public static void Main( ) { Tester t = new Tester( ); string theDirectory = @"c:\test\media"; DirectoryInfo dir = new DirectoryInfo(theDirectory); t.ExploreDirectory(dir); } private void ExploreDirectory(DirectoryInfo dir) { string newDirectory = "newTest"; DirectoryInfo newSubDir = dir.CreateSubdirectory(newDirectory); FileInfo[] filesInDir = dir.GetFiles( ); foreach (FileInfo file in filesInDir) { string fullName = newSubDir.FullName + "\\" + file.Name; file.CopyTo(fullName); Console.WriteLine("{0} copied to newTest", file.FullName); } filesInDir = newSubDir.GetFiles( ); // xa mt vi tp tin v // i tn mt vi tp tin int counter = 0; foreach (FileInfo file in filesInDir) { string fullName = file.FullName; if (counter++ %2 == 0) { // P/Invoke Win API Tester.MoveFile(fullName, fullName + ".bak"); Console.WriteLine("{0} renamed to {1}", fullName,file.FullName); } else

247

Lp trnh .NET v COM

Gvhd: Nguyn Tn Trn Minh Khang

{ } }

file.Delete( ); Console.WriteLine("{0} deleted.", fullName);

newSubDir.Delete(true); } } Kt qu (mt phn): c:\test\media\newTest\recycle.wav renamed to c:\test\media\newTest\recycle.wav c:\test\media\newTest\ringin.wav renamed to c:\test\media\newTest\ringin.wav }

Mt ln na, ch nn gi P/Invoke trong trng bt kh khng. S dng cc lp .NET Framework c on m c qun l.

22.2 Con tr
Nh cp trn, ch nn s dng con tr khi lm vic vi cc COM, WinAPI, hm DLL. Cc ton t s dng vi con tr tng t nh C/C++
&: ton t ly a ch *: ton t ly ni dung con tr ->: ton t n cc thnh vin ca con tr

V d di y s dng con tr lm tham s cho hai hm WinAPI CreatFile v ReadFile.


V d 22-2 S dng con tr trong C#
using System; using System.Runtime.InteropServices; using System.Text; class APIFileReader { // import hai phng thc, phi c t kha unsafe [DllImport("kernel32", SetLastError=true)] static extern unsafe int CreateFile( string filename, uint desiredAccess, uint shareMode, uint attributes, uint creationDisposition, uint flagsAndAttributes, uint templateFile); // API phi dng con tr [DllImport("kernel32", SetLastError=true)] static extern unsafe bool ReadFile( int hFile, void* lpBuffer,

248

Lp trnh .NET v COM

Gvhd: Nguyn Tn Trn Minh Khang

int nBytesToRead, int* nBytesRead, int overlapped); // hm dng: m mt tp tin tn ti public APIFileReader(string filename) { fileHandle = CreateFile( filename, // tp tin GenericRead, // cch truy xut - desiredAccess UseDefault, // shareMode UseDefault, // attributes OpenExisting, // creationDisposition UseDefault, // flagsAndAttributes UseDefault); // templateFile } // unsafe: cho php to con tr v // ng cnh unsafe (unsafe context) public unsafe int Read(byte[] buffer, int index, int count) { int bytesRead = 0; // fixed: cm CLR dn dp rc fixed (byte* bytePointer = buffer) { ReadFile( fileHandle, // hfile bytePointer + index, // lpBuffer count, // nBytesToRead &bytesRead, // nBytesRead 0); // overlapped } return bytesRead; } const uint GenericRead = 0x80000000; const uint OpenExisting = 3; const uint UseDefault = 0; int fileHandle; } class Test { public static void Main( ) { APIFileReader fileReader = new APIFileReader("myTestFile.txt"); // to buffer v ASCII coder const int BuffSize = 128; byte[] buffer = new byte[BuffSize]; ASCIIEncoding asciiEncoder = new ASCIIEncoding( ); // c tp tin vo buffer v hin th ra mn hnh console while (fileReader.Read(buffer, 0, BuffSize) != 0) { Console.Write("{0}", asciiEncoder.GetString(buffer)); }

} }

249

Lp trnh .NET v COM

Gvhd: Nguyn Tn Trn Minh Khang

Phn 2 Xy dng mt ng dng minh ha

250

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Chng 23 Website dy hc ngn ng C#


23.1 Hin trng v yu cu
Trc tin chng ta s tm hiu s qua v nhng g ang din ra trong thc t, v ng dng ca ta lin quan n kha cnh no. Sau ta phi xc nh r cc yu cu m ng dng cn phi thc hin. Vic xc nh tht r v ng cc yu cu m ng dng cn phi thc hin l bc rt quan trng, n s nh hng cho ton b ng dng ca chng ta.

23.1.1 Hin trng thc t


23.1.1.1 Hin trng
Hin nay, lnh vc cng ngh thng tin trn ton th gii ang pht trin ht sc nhanh chng c v hng cng ngh phn mm v ln hng cng ngh phn cng. Ch cn mt vi thng l s c rt nhiu thay i, v th ta cn phi c mt phng php tt tip cn chng. Mc d c rt nhiu cng c, ngn ng gip cc nh pht trin phn mm to ra hng lot cc ng dng mnh m, nhng ging nh cha . H vn lun mun tm ti nhng ci mi, cng c tt hn c th tng hiu sut pht trin phn mm tht nhanh v tht hiu qu. Mt s t chc cung cp cc b pht trin phn mm ni ting nh : 1. Microsoft vi h iu hnh Windows, b Visual Studio 6.0 vi cc ngn ng lp trnh nh : Visual Basic, Visual C++ 2. T chc Sun vi ngn ng Java tng ni ting mt thi, thng tr trong cc ng dng Web. Nhng nm u ca th k 21, nm 2000 2002. Micrsoft tung ra th trng mt cng ngh mi Microsoft Development Enviroment .NET vi mc ch : 3. nh bi cc i th khc : ngn ng lp trnh Java ca Sun hay h qun tr c s d liu Oracle 4. Tr thnh cng c mnh nht pht trin cc ng dng Web ( ch NET vit tt ca Network ). Nhm minh ha qu trnh tm hiu ngn ng C# (c l Csharp) trong b cng c .NET, chng ti vit nn ng dng Web dy hc C# ny.

251

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

23.1.1.2 Qu trnh tm hiu thc t


ng dng ph hp vi thc t v xc nh r c cc yu cu m ng dng cn thc hin, chng ti cng tm hiu qua mt s Web-Site dy hc trn mng. Sau y l mt s hnh nh minh ha qu trnh tm hiu : Trang ch dy hc ch CSS Trang ny s lit k tt c cc mc thuc ch ny, ng thi trang ny cng cho php cc lin kt ( Link ) ti cc trang con khc : cc tham chiu ti cc a ch khc c lin quan, trc nghim ca ch v minh ha l thuyt qua cc v d nu c.
Hnh 23-1 Trang Ch dy hc ngn ng CSS

Trang hin th l thuyt ca chng thuc ch Trong mt ch s c nhiu chng. Khi chn mt chng no , th s hin th phn l thuyt chnh m t cho chng .

252

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 23-2 Trang gii thiu v chng : Introduction CSS

Lit k cc v d minh ha l thuyt thuc ch Phn ny s lit k tt c cc v d hin c thuc ch theo tng nhm c th.

253

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 23-3 Lit k cc v d minh ha l thuyt thuc ch theo nhm

Minh ha l thuyt qua v d Sau khi tm hiu l thuyt, ngi dng mun tm hiu r hn l thuyt qua phn m ngun ca cc v d thuc ch . Ty tng loi ch m ngi dng c h tr chc nng g m tip vo ca s Text, sau s gi trang m ny ln my ch nhn c kt qu ca phn m va g vo.

254

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 23-4 Minh ha l thuyt qua v d, cho php ngi dng t g m ca h vo

T chc thi trc nghim cho ch Trong mi ch , ngi dng c th tham gia thi trc nghim kin thc ca mnh :

255

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Hnh 23-5 T chc thi trc nghim cho ch

23.1.2 Xc nh yu cu
ng dng phi gip ngi dng c th nm bt c kin thc mt cch nhanh nht, trnh trn lan, di dng v phi h tr chc nng hiu chnh ( Admin ).

23.1.2.1 Yu cu chc nng


ng dng d nh s c 5 chc nng chnh sau : 1. Hin th l thut 2. Minh ha l thuyt qua v d 3. T chc thi trc nghim 4. Cho php qung co, gii thiu sch v Link ti cc Site lin quan khc 5. Cho php chc nng hiu chnh ( thm, xa, sa ) cc thnh phn trn M t chi tit v cc yu cu chc nng trn : Lu tr L thuyt v tng ch , cc chng thuc ch v tng mc chnh, chnh ca chng, cc tp tin nh km. Cc v d minh ha ca mi ch , tp tin nh km nu c.

256

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Danh sch cc bi trc nghim v cc cu hi, khng lu tr bi lm Cc a ch Web-Site tham chiu, cc hnh nh v thng tin v vic qung co sch ng vi mi ch . Mt s thng tin khc : thng tin ngi dng Admin, cc tham s hiu chnh Tra cu Thng tin v mi ch , chng, mc chnh v cc chnh thuc chng. Thng tin v cc bi v d minh ha l thuyt. Thng tin v cc bi thi trc nghim. Mt s thng tin khc lin quan nu cn thit. Tnh ton S cu ng cho cc bi trc nghim v tnh im cho chng. Kt xut Hin th theo cu trc phn cp dng cy v l thuyt theo ch , chng, mc chnh, chnh. V d minh ha l thuyt Cc bi trc nghim v kt qu tng ng Danh sch cc tham chiu n cc Web-Site, cc hnh nh v thng tin v sch cn qung co. Cc thng tin v l thuyt, v d, trc nghim, sch cn hiu chnh. Cc bo co thng k v cc mc trn nu c.

23.1.2.2 Yu cu cht lng


2. ng dng phi hin th thng tin mt cch sch tch, ngn gn, trc quan i vi ngi dng, phi gip ngi dng nm bt thng tin c nhanh nht. 3. Phi cho php hiu chnh (Admin) trc tip trn ng dng. 4. Ni dung phi cht lng, ph hp vi tng ch , d hiu.

257

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

23.2 Phn tch hng i tng


23.2.1 S lp i tng
Hnh 23-6 Lp i tng

23.2.2 ngha cc i tng chnh


23.2.2.1 CH
ng dng c th c nhiu ch , mi ch s lu tr cc thng tin v chnh n nh : cc thnh phn thuc ch , gii thiu v ch , c nhiu chng.

23.2.2.2 CHNG
Chng thuc v mt ch no , mi chng c mt hay nhiu mc chnh, v d, trc nghim.

23.2.2.3 MC CHNH
Mc chnh thuc v mt chng no , mi mc chnh c mt hay nhiu chnh con v mt tp tin m t chi tit cho mc chnh ny nu c.

23.2.2.4 V D
V d thuc v mt chng no , mi v d s c phn m ngun v kt xut tng ng vi m ngun ny, c th s c mt tp tin m t chi tit v v d nu cn thit.

23.2.2.5 CU TRC NGHIM


Trc nghim thuc v mt chng, mt bi trc nghim s c nhiu cu hi, mi cu hi s c mt p n v cc chn la tng ng vi cu hi .

23.2.3 Bng thuc tnh cc i tng chnh


Thuc tnh i tng : CH Stt 1 Tn thuc tnh MACHUDE Loi PK Kiu d liu VARCHAR(50) ngha Mi ch c mt m ch duy nht

258

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

2 3 4 5

TEN NOIDUNG SOCHUONG TENTP

VARCHAR(50) VARCHAR(1000) INT VARCHAR(50)

Tn ch Ni dung ca ch S chng c trong ch Tn thnh phn : L thuyt, V d, Trc nghim, Qun tr Ni dung tng quan ca thnh phn thuc ch

NOIDUNGTP

VARCHAR(500)

Thuc tnh i tng : CHNG Stt 1 2 3 4 Tn thuc tnh MACHUONG TEN NOIDUNG SOMUCCHINH Loi PK Kiu d liu INT VARCHAR(50) VARCHAR(1000) INT ngha Mi chng c mt m duy nht Tn ca chng Ni dung ca chng S mc chnh trong mt chng

Thuc tnh i tng : MC CHNH Stt 1 2 3 4 5 Tn thuc tnh MAMUCCHINH TENMC GIOITHIEUMC TAPTIN NOIDUNGCTMC Loi PK Kiu d liu INT VARCHAR(100) VARCHAR(2000) VARCHAR(50) VARCHAR(1000) ngha M mc chnh Tn mc chnh Gii thiu tng quan tng quan v mc chnh Tn tp tin m t chi tit v mc chnh nu c Ni dung ca mt chnh con thuc mc chnh

Thuc tnh i tng : V D Stt 1 2 3 4 5 Tn thuc tnh MAVD TENVIDU MANGUON KETQUA TAPTIN Loi PK Kiu d liu INT VARCHAR(100) VARCHAR(1000) VARCHAR(1000) VARCHAR(50) ngha M v d Tn ca v d M ngun ca mt v d Kt xut ca m v d Tn tp tin m t chi tit v mt v d

259

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Thuc tnh i tng : CU TRC NGHIM Stt 1 2 3 4 Tn thuc tnh MACAUTRACNGHIEM TEN NOIDUNG TRALOI1, TRALOI2, TRALOI3, TRALOI4 DAPAN Loi PK Kiu d liu INT VARCHAR(500) VARCHAR(1000) VARCHAR(500) ngha M cu trc nghim Tn ca cu trc nghim Ni dung ca cu trc nghim Mt cu hi c 4 cu tr li, ng vi 4 thuc tnh p n ca cu hi, c 4 gi tr : 1, 2, 3, 4

INT

23.2.4 Cc x l trn cc i tng chnh


X l trn i tng : CH Stt 1 2 3 4 5 6 Tn x l Hin th thng tin v ch Thm ch mi Xa ch c sn Sa i thng tin v ch Kim tra hp l vic thay i ch Lp bo co, thng k Loi Qui nh Qui nh Qui nh Qui nh Qui nh Qui nh ngha Hin th thng tin v cc thnh phn trong ch D liu nhp l tn v ni dung Xa ton b thng tin v ch Hiu chnh tn, ni dung ch Kim tra cc rng buc v tnh hp l khi thm, xa, sa ch Tng kt ton b thng tin v s chng, v d, cu trc nghim

X l trn i tng : CHNG Stt 1 2 3 4 5 Tn x l Hin th thng tin v chng Thm chng mi Xa chng c sn Sa i thng tin v chng Kim tra hp l vic thay i chng Loi Qui nh Qui nh Qui nh Qui nh Qui nh ngha Hin th danh sch tn chng theo tng ch v ni dung D liu nhp l tn v ni dung Xa ton b thng tin v chng : cc mc chnh, chnh Hiu chnh tn, ni dung chng Kim tra cc rng buc v tnh hp l khi thm, xa, sa

260

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

X l trn i tng : MC CHNH Stt 1 2 Tn x l Hin th thng tin v mc chnh thuc chng Thm mc chnh mi Loi Qui nh Qui nh ngha Hin th danh sch cc chnh con ca mc chnh D liu nhp l tn, ni dung mc chnh v cc chnh con, v c tn tp tin m t mc chnh nu cn thit Xa ton b thng tin v mc chnh : cc chnh, tn tp tin Hiu chnh tn, ni dung ni dung mc chnh v cc chnh con nu cn thit Kim tra cc rng buc v tnh hp l khi thm, xa, sa

3 4

Xa mc chnh c sn Sa i thng tin v mc chnh

Qui nh Qui nh

Kim tra hp l vic thay i mc chnh

Qui nh

X l trn i tng : V D Stt 1 2 Tn x l Hin th thng tin v v d Thm v d mi Loi Qui nh Qui nh ngha Hin th danh sch cc v d ca chng D liu nhp l tn, gii thiu s v v d, m ngun, kt xut tng ng v c tn tp tin m t v d nu cn thit Xa ton b thng tin v v d : tn, m ngun, kt xut v tn tp tin Hiu chnh tn, gii thiu v d, m ngun, kt xut v tn tp tin nu c. Kim tra cc rng buc v tnh hp l khi thm, xa, sa

3 4

Xa v d c sn Sa i thng tin v v d

Qui nh Qui nh

Kim tra hp l vic thay i v d

Qui nh

X l trn i tng : CU TRC NGHIM Stt 1 Tn x l Hin th thng tin v cu trc nghim thuc chng Thm cu trc nghim mi Loi Qui nh ngha Hin th danh sch cc cu trc nghim, cc cu tr li v p n tng ng ca cu. D liu nhp l tn, cu hi trc

Qui nh

261

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

nghim, cc cu chn la v p n ca cu. 3 Xa cu trc nghim c sn Qui nh Xa ton b thng tin v cu trc nghim : tn, cu hi trc nghim, cc cu chn la v p n ca cu. Hiu chnh tn, cu hi trc nghim, cc cu chn la v p n ca cu. Kim tra cc rng buc v tnh hp l khi thm, xa, sa

4 5

Sa i thng tin v cu trc nghim Kim tra hp l vic thay i cu trc nghim

Qui nh Qui nh

23.3 Thit k hng i tng


23.3.1 Thit k d liu
23.3.1.1 S logic
Hnh 23-7 S logic

23.3.1.2 Bng thuc tnh cc i tng ph


Thuc tnh i tng : THAM S Stt 1 2 3 4 Tn thuc tnh MATHAMSO TEN GIATRI DIENGIAI Loi PK Kiu d liu INT VARCHAR(100) INT VARCHAR(100) ngha M tham s Tn tham s Gi tr tham s ngha ca tham s

Thuc tnh i tng : NGI DNG Stt Tn thuc tnh Loi Kiu d liu ngha

262

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

1 2 3 4 5

TENNGUOIDUNG MATMA EMAIL DIENTHOAI FAX

PK

VARCHAR(100) VARCHAR(100) VARCHAR(100) VARCHAR(100) VARCHAR(100)

Tn ngi dng Mt m a ch mail in thoi S fax

23.3.2 Thit k giao din


23.3.2.1 Tng quan S mn hnh

Tng quan l thut Bo co Thng k Tng quan V d

L thuyt theo chng

V d theo chng

Tng quan Trc nghim MN HNH CHNH

Trc nghim theo chng

ng nhp

Qun tr
Thng bo li

L thuyt

V d

Trc nghim

263

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

23.3.2.2 Mt s giao din ca ng dng


Giao din chnh
Hnh 23-8 Trang ch ng dng dy hc CSharp

264

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Giao din chi tit l thuyt tng chng


Hnh 23-9 Lit k chi tit cc mc chnh, chnh con trong chng s 1

265

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Giao din tng quan v v d


Hnh 23-10 Lit k tt c v d trong mi chng

266

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Giao din m t chi tit v d


Hnh 23-11 Minh ha l thuyt bng m v d v kt xut ca n

267

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Giao din cc cu trc nghim kin thc


Hnh 23-12 Trc nghim kin thc chng s 1

268

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Kt qu bi lm trc nghim
Hnh 23-13 Kt qu chm im bi lm trc nghim

269

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Giao din hiu chnh ch


Hnh 23-14 Cho php thm, xa v s ch

270

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Giao din tng quan hiu chnh ni dung chi tit ca tng ch
Hnh 23-15 Tng quan v hiu chnh l thuyt, v d v trc nghim

271

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Giao din hiu chnh chi tit ni dung l thuyt chng


Hnh 23-16 Cho php thm, xa v sa ni dung l thuyt theo tng chng

272

Website dy hc ngn ng C#

Gvhd: Nguyn Tn Trn Minh Khang

Giao din hiu chnh chi tit Trc nghim


Hnh 23-17 Giao din thm, xa v sa cu trc nghim

273

You might also like