Escolar Documentos
Profissional Documentos
Cultura Documentos
Thinking in C#
Larry OBrien and Bruce Eckel
Prentice Hall Upper Saddle River, !!!)phptr)c*+ e! "er#ey $%&'(
Overview
Overvie! ,hat# -n#ide -ntr*ducti*n 01 Th*#e ,h* Can, C*de 21 -ntr*ducti*n t* O34ect# /1 Hell*, O34ect#
&1 C*ntr*lling Pr*gra+ 5l*!(6 '1 -nitiali7ati*n 8 Cleanup 0'0 .1 C*upling and C*he#i*n20' .a1 Hiding the -+ple+entati*n %1 Reu#ing cla##e# (a1 -nter9ace# 61 C*llecting :*ur O34ect# 001 -<O in C# 2'$ 26% //' /6/ &(' '2/ '60 %0' (1 -nter9ace# and -+ple+entati*n 2/&
0$1 Err*r Handling ,ith E;cepti*n# 021 Re9lecti*n and =ttri3ute#'.0 0/1 Pr*gra++ing ,ind*!# 5*r+# 0&1 >?-@ Overvie! 0'1 BAL 0.1 ,e3 Service# %$6 %'/ %'' 0&1 Aultithreaded Pr*gra++ing
%'%
B1 C# 5*r Ci#ual Ba#ic Pr*gra++er# C1 C# Pr*gra++ing >uideline# ?1 Re#*urce# -nde; %%/ %%&
%'6 %.0
Whats Inside
Overvie! ,hat# -n#ide -ntr*ducti*n & . /
PrereDui#ite#))))))))))))))))))))))))/ Learning C#)))))))))))))))))))))))))/ >*al#))))))))))))))))))))))))))))))))))))& Online d*cu+entati*n)))))))). Chapter#)))))))))))))))))))))))))))))). E;erci#e#))))))))))))))))))))))))))))))6 S*urce c*de))))))))))))))))))))))))0$
C*ding #tandard#))))))))))))))))))))))))))02
C# ver#i*n#))))))))))))))))))))))))02 Se+inar# and +ent*ring)))02 Err*r#)))))))))))))))))))))))))))))))))02 *te *n the c*ver de#ign) ) )0/ =ckn*!ledge+ent#))))))))))))0/
-nternet c*ntri3ut*r#))))))))))))))))))))0/
0' 0'
The pr*gre## *9 a3#tracti*n0. =n *34ect ha# an inter9ace) 06 =n *34ect pr*vide# #ervice#20 The hidden i+ple+entati*n22
E;cepti*n handling1 dealing !ith err*r#)))))))))))))))))))))))))))))))))))))))))))))&/ Aultithreading))))))))))))))))))&& Per#i#tence))))))))))))))))))))))))&' C# and the -nternet)))))))))))&'
,hat i# the ,e3F)))))))))))))))))))))))))&. ClientE#ide pr*gra++ing)))))))))))))&. ServerE#ide pr*gra++ing))))))))))))&. = #eparate arena1 applicati*n#)))))&.
/1 Hell*, O34ect#
'0
Building a C# pr*gra+)))))).6
a+e vi#i3ility))))))))))))))))))))))))))))).6 U#ing *ther c*+p*nent#))))))))))))))%$ The #tatic key!*rd))))))))))))))))))))))))%0
9*reach)))))))))))))))))))))))))))))0/'
Ae+3er initiali7ati*n))))))0('
Speci9ying initiali7ati*n))))))))))))))0(% C*n#truct*r initiali7ati*n)))))))))))0((
=rray initiali7ati*n)))))))))))06'
Aultidi+en#i*nal array#))))))))))))2$$ Side3ar<=ppendi;1 ,hat a di99erence a rectangle +ake#)))))))))))))))))))))))))))))))))))))))))))))))))))))2$/
Su++ary)))))))))))))))))))))))))20/ E;erci#e#))))))))))))))))))))))))))20&
I *t Really O34ectEOrientedJ22& ?e#ign -# =# ?e#ign ?*e#22& 5ir#t, ?* * Har+)))))))))))22' ?e#ign Rule #01 ,rite B*ring C*de)))))))))))))))))))))))))))))))))))))))))))))))))))22. ?e#ign -# =# ?e#ign ?*e#2/&
2/&
%1 Reu#ing cla##e#
2'$
Su++ary)))))))))))))))))))))))))26& E;erci#e#))))))))))))))))))))))))))26'
26%
The t!i#t))))))))))))))))))))))))))/$/
Aeth*dEcall 3inding)))))))))))))))))))/$& Pr*ducing the right 3ehavi*r)))))/$' E;ten#i3ility)))))))))))))))))))))))))))))))/$6
Overriding v#) *verl*ading/0/ Operat*r Overl*ading))))))/0& =3#tract cla##e# and +eth*d#))))))))))))))))))))/0& C*n#truct*r# and p*ly+*rphi#+)))))))))))))))))))))))))))))))))))))))))))))))))))))))/2$
Order *9 c*n#truct*r call#))))))))))/2$ Behavi*r *9 p*ly+*rphic +eth*d# in#ide c*n#truct*r#)))))))))))))))))))))/2/
Su++ary)))))))))))))))))))))))))//& E;erci#e#))))))))))))))))))))))))))//&
(a1 -nter9ace#
E;tending an inter9ace
//'
-nter9ace#)))))))))))))))))))))))))//.
IAultiple inheritanceJ in "ava)))/&$ !ith inheritance)))))))))))))))))))))))))/&& ?*e#nt !*rk in C#) Au#t have #ecti*n *n enu+# and #truct# earlier))))))))))))))))))))))))))))))))))/&. -nitiali7ing 9ield# in inter9ace#))))/&( e#ting inter9ace#))))))))))))))))))))))/&6
-nner cla##e#))))))))))))))))))))/'2
-nner cla##e# and upca#ting))))))))/'' -nner cla##e# in +eth*d# and #c*pe#)))))))))))))))/'% =n*ny+*u# inner cla##e#)))))))))))/.$
The link t* the *uter cla##))))))))))/./ #tatic inner cla##e#)))))))))))))))))))))/.. Re9erring t* the *uter cla## *34ect/.( Reaching *ut!ard 9r*+ a +ultiplyEne#ted cla##)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))/%$ -nheriting 9r*+ inner cla##e#))))))/%0 Can inner cla##e# 3e *verriddenF/%2 -nner cla## identi9ier#)))))))))))))))))/%& ,hy inner cla##e#F)))))))))))))))))))))/%' -nner cla##e# 8 c*ntr*l 9ra+e!*rk#/(0
Su++ary)))))))))))))))))))))))))/(6 E;erci#e#)))))))))))))))))))))))))/6$
/6/
=rray#))))))))))))))))))))))))))))))/6&
=rray# are 9ir#tEcla## *34ect#))))))/6. The =rray cla##))))))))))))))))))))))))))&$$ =rray# Static Aeth*d#)))))))))))))))&$0 =rray ele+ent c*+pari#*n#)))))))&$& ,hatF * 3u33le#F))))))))))))))))))))&$. Un#a9e =rray#))))))))))))))))))))))))))))&$( >et thing# rightL))))))))))))))))))))))))&02 L Then >et The+ 5a#t)))))))))))))))&0. =rray #u++ary))))))))))))))))))))))))))&2/
String #peciali#t#1 StringC*llecti*n and String?icti*nary ))))))))))))))))&/6 C*ntainer di#advantage1 unkn*!n type)))))))))))))))))&&$
-Enu+erat*r#))))))))))))))))))&&' Cu#t*+ -nde;er#)))))))))))))&&% Cu#t*+ Enu+erat*r# 8 ?ata Structure#)))))))))))))))))))))))))))))))))))))))))))&'0 S*rting and #earching Li#t#&'% 5r*+ C*llecti*n# t* =rray#&'6 Per#i#tent ?ata ,ith =?O) ET))))))))))))))))))))))))))))))))))))))))))))))))))))))))&..
>etting a handle *n data !ith ?ataSet)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))&.% C*nnecting t* a data3a#e))))))))))))&%0 5a#t Reading ,ith an -?ataReader&%' CRU? ,ith =?O) ET))))))))))))))))&%% Update and ?elete )))))))))))))))))))))&%% The O34ectERelati*nal -+pedance Ai#+atch)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))&(2
Su++ary)))))))))))))))))))))))))&(/ E;erci#e#)))))))))))))))))))))))))&(&
&('
Catching an e;cepti*n)))))&62
The try 3l*ck))))))))))))))))))))))))))))))&62 E;cepti*n handler#))))))))))))))))))))&6/ E;cepti*n# have a helplink)))))))))&6&
Su++ary))))))))))))))))))))))))))'20
Ot*d* P
E;erci#e#))))))))))))))))))))))))))'22
001 -<O in C#
'2/
Su++ary)))))))))))))))))))))))))''6 E;erci#e#)))))))))))))))))))))))))'.$
Su++ary)))))))))))))))))))))))))'(( E;erci#e#))))))))))))))))))))))))))'(6
'60
Event#)))))))))))))))))))))))))))))).$0
Recur#ive Trap#))))))))))))))))))))))))).$&
The >ene#i# *9 ,ind*!# 5*r+#)))))))))))))))))))))))))))))))))))))))))))))))))))))))).$. Creating a 5*r+)))))))))))))).$% >U- =rchitecture#))))))))))).$6 U#ing the Ci#ual ?e#igner.$6 5*r+EEventEC*ntr*l)))))))).0. Pre#entati*nE=3#tracti*nEC*ntr*l))))))))))))))))))))))))))))))))))))))))))))))))))))).2$ A*delECie!EC*ntr*ller))).2& Lay*ut))))))))))))))))))))))))))))).26 *nEC*de Re#*urce#))))))).//
Creating Satellite =##e+3lie#)))))./6
C*n#tant Re#*urce#)))))))).&$ ,hat =3*ut the BP L**kF.&2 5ancy Butt*n#))))))))))))))))).&& T**ltip#))))))))))))))))))))))))))).&( ?i#playing 8 Editing Te;t.&6 Linking Te;t)))))))))))))))))))).'/ Check3*;e# and Radi*Butt*n#)))))))))))))))))))))))))))))))))))))))))))))))))))))))))).'' Li#t, C*+3*, and CheckedLi#tB*;e#))))))))))))))))))))))))))))))))))))))))))))))))).'( Aultiplane di#play# !ith the Splitter c*ntr*l))))))))))))))))))))))))))))))))))))..& TreeCie! 8 Li#tCie!)))))))... Li#tCie!))))))))))))))))))))))))))..(
-c*n Cie!#))))))))))))))))))))))))))))))))))..( ?etail# Cie!)))))))))))))))))))))))))))))))..(
?ataE3*und C*ntr*l#)))))).(' Editing ?ata 9r*+ B*und C*ntr*l#))))))))))))))))))))))))))))))))))))))))))))))))))).6$ Aenu#)))))))))))))))))))))))))))))).6( Standard ?ial*g#)))))))))))))%$2 U#ageECentered ?e#ign)))%$' Su++ary)))))))))))))))))))))))))%$. E;erci#e#)))))))))))))))))))))))))%$(
%$6
?ra!ing pi;el#)))))))))))))))))%$6
?ra!ing #hape#)))))))))))))))%$6 5illing and #tr*king)))))))))%$6 Printing)))))))))))))))))))))))))))%$6 =cce##ing ?irectB))))))))))))%02 Creating a #creen#vaer)))))%02 Creating a #y#te+ #ervice)%02 U#ageECentered ?e#ign) ) )%02 Creating an applicati*n G,ind*!# 8 Aenu#H))))))))))))))))))))))))))))))))))))%02
=+3ient Pr*pertie#)))))))))))))))))))))%02 =pplicati*n))))))))))))))))))))))))))))))))))%02 =pplicati*nC*nte;t)))))))))))))))))))))%02 =;H*#t))))))))))))))))))))))))))))))))))))))))%02 Err*rPr*vider)))))))))))))))))))))))))))))%02 5eatureSupp*rt)))))))))))))))))))))))))))%02 Help))))))))))))))))))))))))))))))))))))))))))))%02 Ae##age))))))))))))))))))))))))))))))))))))))%02 Ae##ageB*; )))))))))))))))))))))))))))))))%02 *ti9y-c*n)))))))))))))))))))))))))))))))))))%02 Pr*gre## Bar))))))))))))))))))))))))))))))))%0/ Pr*perty>rid)))))))))))))))))))))))))))))))%0/ Selecti*nRange)))))))))))))))))))))))))))%0/ Ta3C*ntr*l< Ta33ed Page#)))))))))%0/ Ti+er))))))))))))))))))))))))))))))))))))))))))%0/ T**lBar)))))))))))))))))))))))))))))))))))))))%0/ TrackBar)))))))))))))))))))))))))))))))))))))%0/ U#erC*ntr*l))))))))))))))))))))))))))))))))%0/
%0'
Threading Pr*3le+#)))))))))%0% The Cardinal Rule# *9 Threading))))))))))))))))))))))))))))))))))))))))))))))))))))))))%0% Thread Li9ecycle)))))))))))))))%0% Starting Thread#))))))))))))))%0% St*pping Thread#)))))))))))))%0% Pau#ing and Re#tarting))))%0% Bl*cking and ,aiting)))))))%0% E;cepti*n Handling in Thread#))))))))))))))))))))))))))))))))))))))))))))))))))))))))))%0% Thread# and -nter*pera3ility%0% Thread# and >ar3age C*llecti*n))))))))))))))))))))))))))))))))))))))))))))))))))))))))%0( Thread# and Scala3ility) ) )%0( Re#p*n#ive u#er inter9ace#%0(
Creating Thread#))))))))))))))))))))))))%20 Threading 9*r a re#p*n#ive inter9ace%2&
?1 Re#*urce#
%%/
S*9t!are)))))))))))))))))))))))))))%%/ B**k#)))))))))))))))))))))))))))))))%%&
C#)))))))))))))))))))))))))))))))))))))))))))))))%%& =naly#i# 8 de#ign))))))))))))))))))))))))%%& Aanage+ent 8 Pr*ce##))))))))))))))%%&
-nde;
%%&
Bruce Eckel# Hand#EOn "ava Se+inar Aulti+edia C? -t# like c*+ing t* the #e+inarK =vaila3le at !!!)BruceEckel)c*+)))))))))))))))))))))))))))))))))))))))))))))))))))))%%%
Introduction
Prerequisites
Thi# 3**k a##u+e# that y*u have #*+e pr*gra++ing 9a+iliarity1 y*u under#tand that a pr*gra+ i# a c*llecti*n *9 #tate+ent#, the idea *9 a #u3r*utine<9uncti*n<+acr*, c*ntr*l #tate+ent# #uch a# Ii9J and l**ping c*n#truct# #uch a# I!hile,J etc) H*!ever, y*u +ight have learned thi# in +any place#, #uch a# pr*gra++ing !ith a +acr* language *r !*rking !ith a t**l like Perl) =# l*ng a# y*uve pr*gra++ed t* the p*int !here y*u 9eel c*+9*rta3le !ith the 3a#ic idea# *9 pr*gra++ing, y*ull 3e a3le t* !*rk thr*ugh thi# 3**k) O9 c*ur#e, the 3**k !ill 3e easier 9*r the C pr*gra++er# and +*re #* 9*r the C@@ pr*gra++er#, 3ut d*nt c*unt y*ur#el9 *ut i9 y*ure n*t e;perienced !ith th*#e language# G3ut c*+e !illing t* !*rk hardQ al#*, the +ulti+edia C? that acc*+panie# thi# 3**k !ill 3ring y*u up t* #peed *n the 3a#ic C #ynta; nece##ary t* learn C#H) -ll 3e intr*ducing the c*ncept# *9 *34ectE*riented pr*gra++ing GOOPH and C##3a#ic c*ntr*l +echani#+#, #* y*ull 3e e;p*#ed t* th*#e, and the 9ir#t e;erci#e# !ill inv*lve the 3a#ic c*ntr*lE9l*! #tate+ent#) =lth*ugh re9erence# !ill *9ten 3e +ade t* C and C@@ language 9eature#, the#e are n*t intended t* 3e in#ider c*++ent#, 3ut in#tead t* help all pr*gra++er# put C# in per#pective !ith th*#e language#, 9r*+ !hich, a9ter all, C# i# de#cended) - !ill atte+pt t* +ake the#e re9erence# #i+ple and t* e;plain anything that - think a n*nE C<C@@ pr*gra++er !*uld n*t 3e 9a+iliar !ith)
Learning C#
Tk) =t a3*ut the #a+e ti+e that +y 9ir#t 3**k Using C++ GO#3*rne<Ac>ra!EHill, 06(6H ca+e *ut, - 3egan teaching that language) Teaching pr*gra++ing language# ha# 3ec*+e +y pr*9e##i*nQ -ve #een n*dding head#, 3lank 9ace#, and pu77led e;pre##i*n# in audience# all *ver the !*rld #ince 06(6) =# - 3egan giving inEh*u#e training !ith #+aller gr*up# *9 pe*ple, - di#c*vered #*+ething during the e;erci#e#) Even th*#e
pe*ple !h* !ere #+iling and n*dding !ere c*n9u#ed a3*ut +any i##ue#) 9*und *ut, 3y chairing the C@@ track at the S*9t!are ?evel*p+ent C*n9erence 9*r a nu+3er *9 year# Gand later the "ava trackH, that - and *ther #peaker# tended t* give the typical audience t** +any t*pic# t** 9a#t) S* eventually, thr*ugh 3*th variety in the audience level and the !ay that - pre#ented the +aterial, - !*uld end up l*#ing #*+e p*rti*n *9 the audience) Aay3e it# a#king t** +uch, 3ut 3ecau#e - a+ *ne *9 th*#e pe*ple re#i#tant t* traditi*nal lecturing Gand 9*r +*#t pe*ple, - 3elieve, #uch re#i#tance re#ult# 9r*+ 3*red*+H, - !anted t* try t* keep every*ne up t* #peed) 5*r a ti+e, - !a# creating a nu+3er *9 di99erent pre#entati*n# in 9airly #h*rt *rder) Thu#, - ended up learning 3y e;peri+ent and iterati*n Ga techniDue that al#* !*rk# !ell in C# pr*gra+ de#ignH) Eventually devel*ped a c*ur#e u#ing everything - had learned 9r*+ +y teaching e;perienceR*ne that - !*uld 3e happy giving 9*r a l*ng ti+e) -t tackle# the learning pr*3le+ in di#crete, ea#yEt*Edige#t #tep#, and in a hand#E*n #e+inar Gthe ideal learning #ituati*nH there are e;erci#e# 9*ll*!ing each *9 the #h*rt le##*n#) - n*! give thi# c*ur#e in pu3lic C# #e+inar#, !hich y*u can 9ind *ut a3*ut at www.BruceEckel.com) GThe intr*duct*ry #e+inar i# al#* availa3le a# a C? ROA) -n9*r+ati*n i# availa3le at the #a+e ,e3 #ite)H The 9eed3ack that - get 9r*+ each #e+inar help# +e change and re9*cu# the +aterial until - think it !*rk# !ell a# a teaching +ediu+) But thi# 3**k i#nt 4u#t #e+inar n*te#R- tried t* pack a# +uch in9*r+ati*n a# c*uld !ithin the#e page#, and #tructured it t* dra! y*u thr*ugh *nt* the ne;t #u34ect) A*re than anything, the 3**k i# de#igned t* #erve the #*litary reader !h* i# #truggling !ith a ne! pr*gra++ing language)
Goals
Tk) Like +y previ*u# 3**k Thinking in C++, thi# 3**k ha# c*+e t* 3e #tructured ar*und the pr*ce## *9 teaching the language) -n particular, +y +*tivati*n i# t* create #*+ething that pr*vide# +e !ith a !ay t* teach the language in +y *!n #e+inar#) ,hen - think *9 a chapter in the 3**k, think in ter+# *9 !hat +ake# a g**d le##*n during a #e+inar) Ay g*al i# t* get 3iteE#i7ed piece# that can 3e taught in a rea#*na3le a+*unt *9 ti+e,
9*ll*!ed 3y e;erci#e# that are 9ea#i3le t* acc*+pli#h in a cla##r**+ #ituati*n) Ay g*al# in thi# 3**k are t*1 1. 2. Pre#ent the +aterial *ne #i+ple #tep at a ti+e #* that y*u can ea#ily dige#t each c*ncept 3e9*re +*ving *n) U#e e;a+ple# that are a# #i+ple and #h*rt a# p*##i3le) Thi# #*+eti+e# prevent# +e 9r*+ tackling Ireal !*rldJ pr*3le+#, 3ut -ve 9*und that 3eginner# are u#ually happier !hen they can under#tand every detail *9 an e;a+ple rather than 3eing i+pre##ed 3y the #c*pe *9 the pr*3le+ it #*lve#) =l#*, there# a #evere li+it t* the a+*unt *9 c*de that can 3e a3#*r3ed in a cla##r**+ #ituati*n) 5*r thi# - !ill n* d*u3t receive critici#+ 9*r u#ing It*y e;a+ple#,J 3ut -+ !illing t* accept that in 9av*r *9 pr*ducing #*+ething pedag*gically u#e9ul) Care9ully #eDuence the pre#entati*n *9 9eature# #* that y*u arent #eeing #*+ething that y*u havent 3een e;p*#ed t*) O9 c*ur#e, thi# i#nt al!ay# p*##i3leQ in th*#e #ituati*n#, a 3rie9 intr*duct*ry de#cripti*n i# given) >ive y*u !hat - think i# i+p*rtant 9*r y*u t* under#tand a3*ut the language, rather than everything - kn*!) - 3elieve there i# an in9*r+ati*n i+p*rtance hierarchy, and that there are #*+e 9act# that 6' percent *9 pr*gra++er# !ill never need t* kn*! and that 4u#t c*n9u#e pe*ple and add# t* their percepti*n *9 the c*+ple;ity *9 the language) T* take an e;a+ple 9r*+ C, i9 y*u +e+*ri7e the *perat*r precedence ta3le G- never didH, y*u can !rite clever c*de) But i9 y*u need t* think a3*ut it, it !ill al#* c*n9u#e the reader<+aintainer *9 that c*de) S* 9*rget a3*ut precedence, and u#e parenthe#e# !hen thing# arent clear) Neep each #ecti*n 9*cu#ed en*ugh #* that the lecture ti+eRand the ti+e 3et!een e;erci#e peri*d#Ri# #+all) *t *nly d*e# thi# keep the audience# +ind# +*re active and inv*lved during a hand#E*n #e+inar, 3ut it give# the reader a greater #en#e *9 acc*+pli#h+ent)
3.
!.
Introduction
".
Pr*vide y*u !ith a #*lid 9*undati*n #* that y*u can under#tand the i##ue# !ell en*ugh t* +*ve *n t* +*re di99icult c*ur#e!*rk and 3**k#)
Online docu#entation
tk
Cha$ters
Thi# 3**k !a# de#igned !ith *ne thing in +ind1 the !ay pe*ple learn the C# language) Se+inar audience 9eed3ack helped +e under#tand the di99icult part# that needed illu+inati*n) -n the area# !here - g*t a+3iti*u# and included t** +any 9eature# all at *nce, - ca+e t* kn*!Rthr*ugh the pr*ce## *9 pre#enting the +aterialRthat i9 y*u include a l*t *9 ne! 9eature#, y*u need t* e;plain the+ all, and thi# ea#ily c*+p*und# the #tudent# c*n9u#i*n) =# a re#ult, -ve taken a great deal *9 tr*u3le t* intr*duce the 9eature# a# 9e! at a ti+e a# p*##i3le) The g*al, then, i# 9*r each chapter t* teach a #ingle 9eature, *r a #+all gr*up *9 a##*ciated 9eature#, !ith*ut relying *n additi*nal 9eature#) That !ay y*u can dige#t each piece in the c*nte;t *9 y*ur current kn*!ledge 3e9*re +*ving *n) Here i# a 3rie9 de#cripti*n *9 the chapter# c*ntained in the 3**k, !hich c*rre#p*nd t* lecture# and e;erci#e peri*d# in +y hand#E*n #e+inar#)
Chapter 01 Chapter 21
tk
Introduction to Objects
tk
Thinking in C
www.ThinkingIn.!et
c*n#truct*r lead# int* the c*ncept *9 9uncti*n *verl*ading G#ince y*u +ight !ant #everal c*n#truct*r#H) Thi# i# 9*ll*!ed 3y a di#cu##i*n *9 the pr*ce## *9 cleanup, !hich i# n*t al!ay# a# #i+ple a# it #ee+#) *r+ally, y*u 4u#t dr*p an *34ect !hen y*ure d*ne !ith it and the gar3age c*llect*r eventually c*+e# al*ng and relea#e# the +e+*ry) Thi# p*rti*n e;pl*re# the gar3age c*llect*r and #*+e *9 it# idi*#yncra#ie#) The chapter c*nclude# !ith a cl*#er l**k at h*! thing# are initiali7ed1 aut*+atic +e+3er initiali7ati*n, #peci9ying +e+3er initiali7ati*n, the *rder *9 initiali7ati*n, static initiali7ati*n and array initiali7ati*n)
eusing Classes
The c*ncept *9 inheritance i# #tandard in virtually all OOP language#) -t# a !ay t* take an e;i#ting cla## and add t* it# 9uncti*nality Ga# !ell a# change it, the #u34ect *9 Chapter %H) -nheritance i# *9ten a !ay t* reu#e c*de 3y leaving the I3a#e cla##J the #a+e, and 4u#t patching thing# here and there t* pr*duce !hat y*u !ant) H*!ever, inheritance i#nt the *nly !ay t* +ake ne! cla##e# 9r*+ e;i#ting *ne#) :*u can al#* e+3ed an *34ect in#ide y*ur ne! cla## !ith com"osition) -n thi# chapter y*ull learn a3*ut the#e t!* !ay# t* reu#e c*de in "ava, and h*! t* apply the+)
Chapter %1
Polymorphism
On y*ur *!n, y*u +ight take nine +*nth# t* di#c*ver and under#tand p*ly+*rphi#+, a c*rner#t*ne *9 OOP) Thr*ugh #+all, #i+ple e;a+ple# y*ull #ee h*! t* create a 9a+ily *9 type# !ith inheritance and +anipulate *34ect# in that 9a+ily thr*ugh their c*++*n 3a#e cla##) C## p*ly+*rphi#+ all*!# y*u t* treat all *34ect# in thi# 9a+ily generically, !hich +ean# the 3ulk *9 y*ur c*de d*e#nt rely *n #peci9ic type in9*r+ati*n) Thi# +ake# y*ur pr*gra+# e;ten#i3le, #* 3uilding pr*gra+# and c*de +aintenance i# ea#ier and cheaper)
Introduction
Chapter (1
Inter!aces
C# pr*vide# a third !ay t* #et up a reu#e relati*n#hip, thr*ugh the inter$ace, !hich i# a pure a3#tracti*n *9 the inter9ace *9 an *34ect) The interface i# +*re than 4u#t an a3#tract cla## taken t* the e;tre+e, #ince it all*!# y*u t* per9*r+ a variati*n *n C@@# I+ultiple inheritance,J 3y creating a cla## that can 3e upca#t t* +*re than *ne 3a#e type)
Chapter 61
Chapter 0$1
&
Thinking in C
www.ThinkingIn.!et
Chapter 001
+ultiple #hreads
C# pr*vide# a 3uiltEin 9acility t* #upp*rt +ultiple c*ncurrent #u3ta#k#, called threads, running !ithin a #ingle pr*gra+) GUnle## y*u have +ultiple pr*ce##*r# *n y*ur +achine, thi# i# *nly the a""earance *9 +ultiple #u3ta#k#)H Thi# chapter l**k# at the #ynta; and #e+antic# *9 +ultithreading in C#)
Chapter 0'1
,+Tk
=ppendi; B1
tk
%&ercises
-ve di#c*vered that #i+ple e;erci#e# are e;cepti*nally u#e9ul t* c*+plete a #tudent# under#tanding during a #e+inar, #* y*ull 9ind a #et at the end *9 each chapter) A*#t e;erci#e# are de#igned t* 3e ea#y en*ugh that they can 3e 9ini#hed in a rea#*na3le a+*unt *9 ti+e in a cla##r**+ #ituati*n !hile the in#truct*r *3#erve#, +aking #ure that all the #tudent# are a3#*r3ing the +aterial)
Introduction
'
S*+e e;erci#e# are +*re advanced t* prevent 3*red*+ 9*r e;perienced #tudent#) The +a4*rity are de#igned t* 3e #*lved in a #h*rt ti+e and te#t and p*li#h y*ur kn*!ledge) S*+e are +*re challenging, 3ut n*ne pre#ent +a4*r challenge#) GPre#u+a3ly, y*ull 9ind th*#e *n y*ur *!nR*r +*re likely theyll 9ind y*uH)
'ource code
=ll the #*urce c*de 9*r thi# 3**k i# availa3le a# c*pyrighted 9ree!are, di#tri3uted a# a #ingle package, 3y vi#iting the ,e3 #ite www.thinkingin.net) T* +ake #ure that y*u get the +*#t current ver#i*n, thi# i# the *99icial #ite 9*r di#tri3uti*n *9 the c*de and the electr*nic ver#i*n *9 the 3**k) :*u can 9ind +irr*red ver#i*n# *9 the electr*nic 3**k and the c*de *n *ther #ite# G#*+e *9 the#e #ite# are 9*und at www.thinkingin.netH, 3ut y*u #h*uld check the *99icial #ite t* en#ure that the +irr*red ver#i*n i# actually the +*#t recent editi*n) :*u +ay di#tri3ute the c*de in cla##r**+ and *ther educati*nal #ituati*n#) The pri+ary g*al *9 the c*pyright i# t* en#ure that the #*urce *9 the c*de i# pr*perly cited, and t* prevent y*u 9r*+ repu3li#hing the c*de in print +edia !ith*ut per+i##i*n) G=# l*ng a# the #*urce i# cited, u#ing e;a+ple# 9r*+ the 3**k in +*#t +edia i# generally n*t a pr*3le+)H -n each #*urce c*de 9ile y*u !ill 9ind a re9erence t* the 9*ll*!ing c*pyright n*tice1 //:! :CopyRight.txt Copyright 2002 Larry O'Brien Source code fi e fro! the "#t edition of the $oo% &'hin%ing in C(.& ) right# re#er*ed +,C+-' a# a o.ed $y the fo o.ing #tate!ent#: /ou can free y u#e thi# fi e for your o.n .or% 0per#ona or co!!ercia 12 inc uding !odification# and di#tri$ution in executa$ e for! on y. -er!i##ion i# granted to u#e thi# fi e in c a##roo! #ituation#2 inc uding it# u#e in pre#entation !ateria #2 a# ong a# the $oo% &'hin%ing in C(& i# cited a# the #ource. +xcept in c a##roo! #ituation#2 you cannot copy and di#tri$ute thi# code3 in#tead2 the #o e
1(
Thinking in C
www.ThinkingIn.!et
di#tri$ution point i# http://....thin%ingin.net 0and officia !irror #ite#1 .here it i# free y a*ai a$ e. /ou cannot re!o*e thi# copyright and notice. /ou cannot di#tri$ute !odified *er#ion# of the #ource code in thi# pac%age. /ou cannot u#e thi# fi e in printed !edia .ithout the expre## per!i##ion of the author. Larry O4Brien !a%e# no repre#entation a$out the #uita$i ity of thi# #oft.are for any purpo#e. 5t i# pro*ided &a# i#& .ithout expre## or i!p ied .arranty of any %ind2 inc uding any i!p ied .arranty of !erchanta$i ity2 fitne## for a particu ar purpo#e or non6infringe!ent. 'he entire ri#% a# to the 7ua ity and perfor!ance of the #oft.are i# .ith you. Larry O4Brien2 Bruce +c%e 2 and the pu$ i#her #ha not $e ia$ e for any da!age# #uffered $y you or any third party a# a re#u t of u#ing or di#tri$uting #oft.are. 5n no e*ent .i Larry O4Brien2 Bruce +c%e or the pu$ i#her $e ia$ e for any o#t re*enue2 profit2 or data2 or for direct2 indirect2 #pecia 2 con#e7uentia 2 incidenta 2 or puniti*e da!age#2 ho.e*er cau#ed and regard e## of the theory of ia$i ity2 ari#ing out of the u#e of or ina$i ity to u#e #oft.are2 e*en if Larry O4Brien2 Bruce +c%e and the pu$ i#her ha*e $een ad*i#ed of the po##i$i ity of #uch da!age#. Shou d the #oft.are pro*e defecti*e2 you a##u!e the co#t of a nece##ary #er*icing2 repair2 or correction. 5f you thin% you'*e found an error2 p ea#e #u$!it the correction u#ing the for! you .i find at ....thin%ingin.net. 0- ea#e u#e the #a!e for! for non6code error# found in the $oo%.1 ///:8 :*u +ay u#e the c*de in y*ur pr*4ect# and in the cla##r**+ Gincluding y*ur pre#entati*n +aterial#H a# l*ng a# the c*pyright n*tice that appear# in each #*urce 9ile i# retained)
Introduction
11
Coding standards
-n the te;t *9 thi# 3**k, identi9ier# G9uncti*n, varia3le, and cla## na+e#H are #et in bold) A*#t key!*rd# are al#* #et in 3*ld, e;cept 9*r th*#e key!*rd# that are u#ed #* +uch that the 3*lding can 3ec*+e tedi*u#, #uch a# Icla##)J tk The pr*gra+# in thi# 3**k are 9ile# that are included 3y the !*rd pr*ce##*r in the te;t, directly 9r*+ c*+piled 9ile#) Thu#, the c*de 9ile# printed in the 3**k #h*uld all !*rk !ith*ut c*+piler err*r#) The err*r# that should cau#e c*+pileEti+e err*r +e##age# are c*++ented *ut !ith the c*++ent //! #* they can 3e ea#ily di#c*vered and te#ted u#ing aut*+atic +ean#) Err*r# di#c*vered and rep*rted t* the auth*r !ill appear 9ir#t in the di#tri3uted #*urce c*de and later in update# *9 the 3**k G!hich !ill al#* appear *n the ,e3 #ite www.thinkingin.netH)
C# versions
tk
%rrors
* +atter h*! +any trick# a !riter u#e# t* detect err*r#, #*+e al!ay# creep in and the#e *9ten leap *99 the page 9*r a 9re#h reader) There i# an err*r #u3+i##i*n 9*r+ linked 9r*+ the 3eginning *9 each chapter in the HTAL ver#i*n *9 thi# 3**k Gand *n the C? ROA 3*und int* the 3ack *9 thi# 3**k, and d*!nl*ada3le 9r*+ www.thinkingin.netH and al#* *n the ,e3 #ite it#el9, *n the page 9*r thi# 3**k) -9 y*u di#c*ver anything y*u 3elieve t* 3e an err*r, plea#e u#e thi# 9*r+ t* #u3+it the err*r al*ng !ith y*ur #ugge#ted c*rrecti*n) -9 nece##ary, include the
1)
Thinking in C
www.ThinkingIn.!et
*riginal #*urce 9ile and n*te any #ugge#ted +*di9icati*n#) :*ur help i# appreciated)
)c*nowledge#ents
tk
Internet contri+utors
tk
Introduction
13
15
are intr*duced here t* give y*u a #*lid *vervie! *9 OOP) H*!ever, +any *ther pe*ple d*nt get the 3ig picture c*ncept# until theyve #een #*+e *9 the +echanic# 9ir#tQ the#e pe*ple +ay 3ec*+e 3*gged d*!n and l*#t !ith*ut #*+e c*de t* get their hand# *n) -9 y*ure part *9 thi# latter gr*up and are eager t* get t* the #peci9ic# *9 the language, 9eel 9ree t* 4u+p pa#t thi# chapterR#kipping it at thi# p*int !ill n*t prevent y*u 9r*+ !riting pr*gra+# *r learning the language) H*!ever, y*u !ill !ant t* c*+e 3ack here eventually t* 9ill in y*ur kn*!ledge #* y*u can under#tand !hy *34ect# are i+p*rtant and h*! t* de#ign !ith the+)
16
pr*gra++ing and 9*r pr*gra++ing e;clu#ively 3y +anipulating graphical #y+3*l#) GThe latter pr*ved t* 3e t** re#trictive)H Each *9 the#e appr*ache# i# a g**d #*luti*n t* the particular cla## *9 pr*3le+ theyre de#igned t* #*lve, 3ut !hen y*u #tep *ut#ide *9 that d*+ain they 3ec*+e a!k!ard) The *34ectE*riented appr*ach g*e# a #tep 9urther 3y pr*viding t**l# 9*r the pr*gra++er t* repre#ent ele+ent# in the pr*3le+ #pace) Thi# repre#entati*n i# general en*ugh that the pr*gra++er i# n*t c*n#trained t* any particular type *9 pr*3le+) ,e re9er t* the ele+ent# in the pr*3le+ #pace and their repre#entati*n# in the #*luti*n #pace a# I*34ect#)J GO9 c*ur#e, y*u !ill al#* need *ther *34ect# that d*nt have pr*3le+E#pace anal*g#)H The idea i# that the pr*gra+ i# all*!ed t* adapt it#el9 t* the ling* *9 the pr*3le+ 3y adding ne! type# *9 *34ect#, #* !hen y*u read the c*de de#cri3ing the #*luti*n, y*ure reading !*rd# that al#* e;pre## the pr*3le+) Thi# i# a +*re 9le;i3le and p*!er9ul language a3#tracti*n than !hat !eve had 3e9*re) Thu#, OOP all*!# y*u t* de#cri3e the pr*3le+ in ter+# *9 the pr*3le+, rather than in ter+# *9 the c*+puter !here the #*luti*n !ill run) There# #till a c*nnecti*n 3ack t* the c*+puter, th*ugh) Each *34ect l**k# Duite a 3it like a little c*+puterQ it ha# a #tate, and it ha# *perati*n# that y*u can a#k it t* per9*r+) H*!ever, thi# d*e#nt #ee+ like #uch a 3ad anal*gy t* *34ect# in the real !*rldRthey all have characteri#tic# and 3ehavi*r#) S*+e language de#igner# have decided that *34ectE*riented pr*gra++ing 3y it#el9 i# n*t adeDuate t* ea#ily #*lve all pr*gra++ing pr*3le+#, and adv*cate the c*+3inati*n *9 vari*u# appr*ache# int* multi"aradigm pr*gra++ing language#)0 =lan Nay #u++ari7ed 9ive 3a#ic characteri#tic# *9 S+alltalk, the 9ir#t #ucce##9ul *34ectE*riented language and *ne *9 the language# up*n !hich C# i# 3a#ed) The#e characteri#tic# repre#ent a pure appr*ach t* *34ectE *riented pr*gra++ing1 1. Everything is an object. Think *9 an *34ect a# a 9ancy varia3leQ it #t*re# data, 3ut y*u can I+ake reDue#t#J t* that *34ect, a#king it t* per9*r+ *perati*n# *n it#el9) -n the*ry, y*u can take any c*nceptual c*+p*nent in the pr*3le+ y*ure trying t* #*lve
1#
Gd*g#, 3uilding#, #ervice#, etc)H and repre#ent it a# an *34ect in y*ur pr*gra+) 2. A program is a bunch of objects telling each other what to do by sending messages) T* +ake a reDue#t *9 an *34ect, y*u I#end a +e##ageJ t* that *34ect) A*re c*ncretely, y*u can think *9 a +e##age a# a reDue#t t* call a 9uncti*n that 3el*ng# t* a particular *34ect) Each object has its own memory made up of other objects) Put an*ther !ay, y*u create a ne! kind *9 *34ect 3y +aking a package c*ntaining e;i#ting *34ect#) Thu#, y*u can 3uild c*+ple;ity in a pr*gra+ !hile hiding it 3ehind the #i+plicity *9 *34ect#) Every object has a type) U#ing the parlance, each *34ect i# an instance *9 a class, in !hich Icla##J i# #yn*ny+*u# !ith Itype)J The +*#t i+p*rtant di#tingui#hing characteri#tic *9 a cla## i# I,hat +e##age# can y*u #end t* itFJ All objects of a particular type can receive the same messages) Thi# i# actually a l*aded #tate+ent, a# y*u !ill #ee later) Becau#e an *34ect *9 type IcircleJ i# al#* an *34ect *9 type I#hape,J a circle i# guaranteed t* accept #hape +e##age#) Thi# +ean# y*u can !rite c*de that talk# t* #hape# and aut*+atically handle anything that 9it# the de#cripti*n *9 a #hape) Thi# su2stituta2ilit4 i# *ne *9 the +*#t p*!er9ul c*ncept# in OOP)
3.
!.
B**ch *99er# an even +*re #uccinct de#cripti*n *9 an *34ect1 5n o23ect has state6 2eha-ior and identit4 Thi# +ean# that an *34ect can have internal data G!hich give# it #tateH, +eth*d# Gt* pr*duce 3ehavi*rH, and each *34ect can 3e uniDuely di#tingui#hed 9r*+ every *ther *34ect P t* put thi# in a c*ncrete #en#e, each *34ect ha# a uniDue addre## in +e+*ry2
2 Thi# i# actually a 3it re#trictive, #ince *34ect# can c*nc eiva3ly e;i#t in di99erent +achine#
and addre## #pace#, and they can al#* 3e #t*red *n di#k) -n the#e ca#e#, the identity *9 the *34ect +u#t 3e deter+ined 3y #*+ething *ther than +e+*ry addre##)
1&
Thinking in C
www.ThinkingIn.!et
1'
characteri#tic# and 3ehavi*r#) The di99erence i# that a pr*gra++er de9ine# a cla## t* 9it a pr*3le+ rather than 3eing 9*rced t* u#e an e;i#ting data type that !a# de#igned t* repre#ent a unit *9 #t*rage in a +achine) :*u e;tend the pr*gra++ing language 3y adding ne! data type# #peci9ic t* y*ur need#) The pr*gra++ing #y#te+ !elc*+e# the ne! cla##e# and give# the+ all the care and typeEchecking that it give# t* 3uiltEin type#) The *34ectE*riented appr*ach i# n*t li+ited t* 3uilding #i+ulati*n#) ,hether *r n*t y*u agree that any pr*gra+ i# a #i+ulati*n *9 the #y#te+ y*ure de#igning, the u#e *9 OOP techniDue# can ea#ily reduce a large #et *9 pr*3le+# t* a #i+ple #*luti*n) Once a cla## i# e#ta3li#hed, y*u can +ake a# +any *34ect# *9 that cla## a# y*u like, and then +anipulate th*#e *34ect# a# i9 they are the ele+ent# that e;i#t in the pr*3le+ y*u are trying t* #*lve) -ndeed, *ne *9 the challenge# *9 *34ectE*riented pr*gra++ing i# t* create a *neEt*E*ne +apping 3et!een the ele+ent# in the pr*3le+ #pace and *34ect# in the #*luti*n #pace) But h*! d* y*u get an *34ect t* d* u#e9ul !*rk 9*r y*uF There +u#t 3e a !ay t* +ake a reDue#t *9 the *34ect #* that it !ill d* #*+ething, #uch a# c*+plete a tran#acti*n, dra! #*+ething *n the #creen, *r turn *n a #!itch) =nd each *34ect can #ati#9y *nly certain reDue#t#) The reDue#t# y*u can +ake *9 an *34ect are de9ined 3y it# inter$ace6 and the type i# !hat deter+ine# the inter9ace) = #i+ple e;a+ple +ight 3e a repre#entati*n *9 a light 3ul31
)(
Thinking in C
www.ThinkingIn.!et
The inter9ace e#ta3li#he# what reDue#t# y*u can +ake 9*r a particular *34ect) H*!ever, there +u#t 3e c*de #*+e!here t* #ati#9y that reDue#t) Thi#, al*ng !ith the hidden data, c*+pri#e# the im"lementation) 5r*+ a pr*cedural pr*gra++ing #tandp*int, it# n*t that c*+plicated) = type ha# a 9uncti*n a##*ciated !ith each p*##i3le reDue#t, and !hen y*u +ake a particular reDue#t t* an *34ect, that 9uncti*n i# called) Thi# pr*ce## i# u#ually #u++ari7ed 3y #aying that y*u I#end a +e##ageJ G+ake a reDue#tH t* an *34ect, and the *34ect 9igure# *ut !hat t* d* !ith that +e##age Git e;ecute# c*deH) Here, the na+e *9 the type<cla## i# Light, the na+e *9 thi# particular Light *34ect i# lt, and the reDue#t# that y*u can +ake *9 a Light *34ect are t* turn it *n, turn it *99, +ake it 3righter, *r +ake it di++er) :*u create a Light *34ect 3y de9ining a Ire9erenceJ GltH 9*r that *34ect and calling new t* reDue#t a ne! *34ect *9 that type) T* #end a +e##age t* the *34ect, y*u #tate the na+e *9 the *34ect and c*nnect it t* the +e##age reDue#t !ith a peri*d Gd*tH) 5r*+ the #tandp*int *9 the u#er *9 a prede9ined cla##, that# pretty +uch all there i# t* pr*gra++ing !ith *34ect#) The diagra+ #h*!n a3*ve 9*ll*!# the 9*r+at *9 the Uni$ied .odeling 0anguage GUALH) Each cla## i# repre#ented 3y a 3*;, !ith the type na+e in the t*p p*rti*n *9 the 3*;, any data +e+3er# that y*u care t* de#cri3e in the +iddle p*rti*n *9 the 3*;, and the mem2er $unctions Gthe 9uncti*n# that 3el*ng t* thi# *34ect, !hich receive any +e##age# y*u #end t* that *34ectH in the 3*tt*+ p*rti*n *9 the 3*;) O9ten, *nly the na+e *9 the cla## and the pu3lic +e+3er 9uncti*n# are #h*!n in UAL de#ign diagra+#, and #* the +iddle p*rti*n i# n*t #h*!n) -9 y*ure intere#ted *nly in the cla## na+e, then the 3*tt*+ p*rti*n d*e#nt need t* 3e #h*!n, either)
)1
))
Thinking in C
www.ThinkingIn.!et
The #ec*nd rea#*n 9*r acce## c*ntr*l i# t* all*! the li3rary de#igner t* change the internal !*rking# *9 the cla## !ith*ut !*rrying a3*ut h*! it !ill a99ect the client pr*gra++er) 5*r e;a+ple, y*u +ight i+ple+ent a particular cla## in a #i+ple 9a#hi*n t* ea#e devel*p+ent, and then later di#c*ver that y*u need t* re!rite it in *rder t* +ake it run 9a#ter) -9 the inter9ace and i+ple+entati*n are clearly #eparated and pr*tected, y*u can acc*+pli#h thi# ea#ily) "ava u#e# 9ive e;plicit key!*rd# t* #et the 3*undarie# in a cla##1 public, private, protected, internal, and protected internal) Their u#e and +eaning are Duite #traight9*r!ard) The#e access s"eci$iers deter+ine !h* can u#e the de9initi*n# that 9*ll*!) public +ean# the 9*ll*!ing de9initi*n# are availa3le t* every*ne) The private key!*rd, *n the *ther hand, +ean# that n* *ne can acce## th*#e de9initi*n# e;cept y*u, the creat*r *9 the type, in#ide +e+3er 9uncti*n# *9 that type) private i# a 3rick !all 3et!een y*u and the client pr*gra++er) -9 #*+e*ne trie# t* acce## a private +e+3er, theyll get a c*+pileEti+e err*r) protected act# like private, !ith the e;cepti*n that an inheriting cla## ha# acce## t* protected +e+3er#, 3ut n*t private +e+3er#) -nheritance !ill 3e intr*duced #h*rtly) internal i# *9ten called I9riendlyJPthe de9initi*n can 3e acce##ed 3y *ther cla##e# in the #a+e na+e#pace a# i9 it !ere public, 3ut i# n*t acce##i3le t* cla##e# in di99erent na+e#pace#) a+e#pace# !ill 3e di#cu##ed in depth in chapter #re9#) protected internal all*!# acce## 3y cla##e# !ithin the #a+e na+e#pace Ga# !ith internalH or 3y inheriting cla##e# Ga# !ith protectedH even i9 the inheriting cla##e# are n*t !ithin the #a+e na+e#pace) C## de9ault acce##, !hich c*+e# int* play i9 y*u d*nt u#e *ne *9 the a9*re+enti*ned #peci9ier#, i# internal)
)3
reu#e i# *ne *9 the greate#t advantage# that *34ectE*riented pr*gra++ing language# pr*vide) The #i+ple#t !ay t* reu#e a cla## i# t* 4u#t u#e an *34ect *9 that cla## directly, 3ut y*u can al#* place an *34ect *9 that cla## in#ide a ne! cla##) ,e call thi# Icreating a +e+3er *34ect)J :*ur ne! cla## can 3e +ade up *9 any nu+3er and type *9 *ther *34ect#, in any c*+3inati*n that y*u need t* achieve the 9uncti*nality de#ired in y*ur ne! cla##) Becau#e y*u are c*+p*#ing a ne! cla## 9r*+ e;i#ting cla##e#, thi# c*ncept i# called com"osition G*r +*re generally, aggregationH) C*+p*#iti*n i# *9ten re9erred t* a# a Iha#EaJ relati*n#hip, a# in Ia car ha# an engine)J
Car % n g in e
GThe a3*ve UAL diagra+ indicate# c*+p*#iti*n !ith the 9illed dia+*nd, !hich #tate# there i# *ne car) - !ill typically u#e a #i+pler 9*r+1 4u#t a line, !ith*ut the dia+*nd, t* indicate an a##*ciati*n)&H C*+p*#iti*n c*+e# !ith a great deal *9 9le;i3ility) The +e+3er *34ect# *9 y*ur ne! cla## are u#ually private, +aking the+ inacce##i3le t* the client pr*gra++er# !h* are u#ing the cla##) Thi# all*!# y*u t* change th*#e +e+3er# !ith*ut di#tur3ing e;i#ting client c*de) :*u can al#* change the +e+3er *34ect# at runEti+e, t* dyna+ically change the 3ehavi*r *9 y*ur pr*gra+) -nheritance, !hich i# de#cri3ed ne;t, d*e# n*t have thi# 9le;i3ility #ince the c*+piler +u#t place c*+pileEti+e re#tricti*n# *n cla##e# created !ith inheritance) Becau#e inheritance i# #* i+p*rtant in *34ectE*riented pr*gra++ing it i# *9ten highly e+pha#i7ed, and the ne! pr*gra++er can get the idea that inheritance #h*uld 3e u#ed every!here) Thi# can re#ult in a!k!ard and *verly c*+plicated de#ign#) -n#tead, y*u #h*uld 9ir#t l**k t* c*+p*#iti*n !hen creating ne! cla##e#, #ince it i# #i+pler and +*re 9le;i3le) -9 y*u take thi# appr*ach, y*ur de#ign# !ill 3e cleaner) Once y*uve had #*+e e;perience, it !ill 3e rea#*na3ly *3vi*u# !hen y*u need inheritance)
& Thi# i# u#ually en*ugh detail 9*r +*#t diagra+#, and y*u d*nt need t* get #peci9ic a3*ut
)4
Thinking in C
www.ThinkingIn.!et
4 e riv e d
GThe arr*! in the a3*ve UAL diagra+ p*int# 9r*+ the derived cla## t* the 3a#e cla##) =# y*u !ill #ee, there can 3e +*re than *ne derived cla##)H = type d*e# +*re than de#cri3e the c*n#traint# *n a #et *9 *34ect#Q it al#* ha# a relati*n#hip !ith *ther type#) T!* type# can have characteri#tic# and 3ehavi*r# in c*++*n, 3ut *ne type +ay c*ntain +*re characteri#tic# than an*ther and +ay al#* handle +*re +e##age# G*r handle the+ di99erentlyH) -nheritance e;pre##e# thi# #i+ilarity 3et!een type# u#ing the c*ncept *9 3a#e type# and derived type#) = 3a#e type c*ntain# all *9 the characteri#tic# and 3ehavi*r# that are #hared a+*ng the type# derived 9r*+ it) :*u create a 3a#e type t* repre#ent the c*re *9 y*ur idea# a3*ut
)5
#*+e *34ect# in y*ur #y#te+) 5r*+ the 3a#e type, y*u derive *ther type# t* e;pre## the di99erent !ay# that thi# c*re can 3e reali7ed) 5*r e;a+ple, a tra#hErecycling +achine #*rt# piece# *9 tra#h) The 3a#e type i# Itra#h,J and each piece *9 tra#h ha# a !eight, a value, and #* *n, and can 3e #hredded, +elted, *r dec*+p*#ed) 5r*+ thi#, +*re #peci9ic type# *9 tra#h are derived that +ay have additi*nal characteri#tic# Ga 3*ttle ha# a c*l*rH *r 3ehavi*r# Gan alu+inu+ can +ay 3e cru#hed, a #teel can i# +agneticH) -n additi*n, #*+e 3ehavi*r# +ay 3e di99erent Gthe value *9 paper depend# *n it# type and c*nditi*nH) U#ing inheritance, y*u can 3uild a type hierarchy that e;pre##e# the pr*3le+ y*ure trying t* #*lve in ter+# *9 it# type#) = #ec*nd e;a+ple i# the cla##ic I#hapeJ e;a+ple, perhap# u#ed in a c*+puterEaided de#ign #y#te+ *r ga+e #i+ulati*n) The 3a#e type i# I#hape,J and each #hape ha# a #i7e, a c*l*r, a p*#iti*n, and #* *n) Each #hape can 3e dra!n, era#ed, +*ved, c*l*red, etc) 5r*+ thi#, #peci9ic type# *9 #hape# are derived GinheritedH1 circle, #Duare, triangle, and #* *n, each *9 !hich +ay have additi*nal characteri#tic# and 3ehavi*r#) Certain #hape# can 3e 9lipped, 9*r e;a+ple) S*+e 3ehavi*r# +ay 3e di99erent, #uch a# !hen y*u !ant t* calculate the area *9 a #hape) The type hierarchy e+3*die# 3*th the #i+ilaritie# and di99erence# 3et!een the #hape#)
Shape d ra w 12 e ra se 12 # ove12 g e tC o lo r 1 2 s e t C o lo r 1 2
C ir c le
S q u a re
T r ia n g le
)6
Thinking in C
www.ThinkingIn.!et
Ca#ting the #*luti*n in the #a+e ter+# a# the pr*3le+ i# tre+end*u#ly 3ene9icial 3ecau#e y*u d*nt need a l*t *9 inter+ediate +*del# t* get 9r*+ a de#cripti*n *9 the pr*3le+ t* a de#cripti*n *9 the #*luti*n) ,ith *34ect#, the type hierarchy i# the pri+ary +*del, #* y*u g* directly 9r*+ the de#cripti*n *9 the #y#te+ in the real !*rld t* the de#cripti*n *9 the #y#te+ in c*de) -ndeed, *ne *9 the di99icultie# pe*ple have !ith *34ectE*riented de#ign i# that it# t** #i+ple t* get 9r*+ the 3eginning t* the end) = +ind trained t* l**k 9*r c*+ple; #*luti*n# i# *9ten #tu+ped 3y thi# #i+plicity at 9ir#t) ,hen y*u inherit 9r*+ an e;i#ting type, y*u create a ne! type) Thi# ne! type c*ntain# n*t *nly all the +e+3er# *9 the e;i#ting type Galth*ugh the private *ne# are hidden a!ay and inacce##i3leH, 3ut +*re i+p*rtant, it duplicate# the inter9ace *9 the 3a#e cla##) That i#, all the +e##age# y*u can #end t* *34ect# *9 the 3a#e cla## y*u can al#* #end t* *34ect# *9 the derived cla##) Since !e kn*! the type *9 a cla## 3y the +e##age# !e can #end t* it, thi# +ean# that the derived cla## is the same t4"e as the 2ase class) -n the previ*u# e;a+ple, Ia circle i# a #hape)J Thi# type eDuivalence via inheritance i# *ne *9 the 9unda+ental gate!ay# in under#tanding the +eaning *9 *34ectE*riented pr*gra++ing) Since 3*th the 3a#e cla## and derived cla## have the #a+e inter9ace, there +u#t 3e #*+e i+ple+entati*n t* g* al*ng !ith that inter9ace) That i#, there +u#t 3e #*+e c*de t* e;ecute !hen an *34ect receive# a particular +e##age) -9 y*u #i+ply inherit a cla## and d*nt d* anything el#e, the +eth*d# 9r*+ the 3a#eEcla## inter9ace c*+e right al*ng int* the derived cla##) That +ean# *34ect# *9 the derived cla## have n*t *nly the #a+e type, they al#* have the #a+e 3ehavi*r, !hich i#nt particularly intere#ting) :*u have t!* !ay# t* di99erentiate y*ur ne! derived cla## 9r*+ the *riginal 3a#e cla##) The 9ir#t i# Duite #traight9*r!ard1 :*u #i+ply add 3rand ne! 9uncti*n# t* the derived cla##) The#e ne! 9uncti*n# are n*t part *9 the 3a#e cla## inter9ace) Thi# +ean# that the 3a#e cla## #i+ply didnt d* a# +uch a# y*u !anted it t*, #* y*u added +*re 9uncti*n#) Thi# #i+ple and pri+itive u#e 9*r inheritance i#, at ti+e#, the per9ect #*luti*n t* y*ur pr*3le+) H*!ever, y*u #h*uld l**k cl*#ely 9*r the p*##i3ility that y*ur 3a#e cla## +ight al#* need the#e additi*nal 9uncti*n#) Thi# pr*ce## *9 di#c*very and iterati*n *9 y*ur de#ign happen# regularly in *34ectE *riented pr*gra++ing)
)#
Shape d ra w 12 e ra s e 12 # ove12 g e t C o lo r1 2 s e t C o lo r 1 2
C ir c le
S q u a re
T r ia n g le 7 li$ 8 e r t ic a l1 2 7 li$ 9 o r i: o n t a l1 2
=lth*ugh inheritance +ay #*+eti+e# i+ply Ge#pecially in "ava, !here the key!*rd that indicate# inheritance i# extendsH that y*u are g*ing t* add ne! 9uncti*n# t* the inter9ace, that# n*t nece##arily true) The #ec*nd and +*re i+p*rtant !ay t* di99erentiate y*ur ne! cla## i# t* change the 3ehavi*r *9 an e;i#ting 3a#eEcla## 9uncti*n) Thi# i# re9erred t* a# o-erriding that 9uncti*n)
)&
Thinking in C
www.ThinkingIn.!et
Shape d ra w 12 e ra se 12 # ove12 g e tC o lo r 1 2 s e tC o lo r 1 2
C ir c le d ra w 12 e ra se 12
S q u a re d ra w 12 e ra se 12
T r ia n g le d ra w 12 e ra se 12
T* *verride a 9uncti*n, y*u #i+ply create a ne! de9initi*n 9*r the 9uncti*n in the derived cla##) :*ure #aying, I-+ u#ing the #a+e inter9ace 9uncti*n here, 3ut - !ant it t* d* #*+ething di99erent 9*r +y ne! type)J
)'
3ecau#e y*ur ne! 9uncti*n# are n*t acce##i3le 9r*+ the 3a#e type) Thi# can 3e de#cri3ed a# an is9like9a' relati*n#hipQ the ne! type ha# the inter9ace *9 the *ld type 3ut it al#* c*ntain# *ther 9uncti*n#, #* y*u cant really #ay it# e;actly the #a+e) 5*r e;a+ple, c*n#ider an air c*nditi*ner) Supp*#e y*ur h*u#e i# !ired !ith all the c*ntr*l# 9*r c**lingQ that i#, it ha# an inter9ace that all*!# y*u t* c*ntr*l c**ling) -+agine that the air c*nditi*ner 3reak# d*!n and y*u replace it !ith a heat pu+p, !hich can 3*th heat and c**l) The heat pu+p is9like9an air c*nditi*ner, 3ut it can d* +*re) Becau#e the c*ntr*l #y#te+ *9 y*ur h*u#e i# de#igned *nly t* c*ntr*l c**ling, it i# re#tricted t* c*++unicati*n !ith the c**ling part *9 the ne! *34ect) The inter9ace *9 the ne! *34ect ha# 3een e;tended, and the e;i#ting #y#te+ d*e#nt kn*! a3*ut anything e;cept the *riginal inter9ace)
T h e rm o s ta t lo w e r - e # $ e r a t u r e 1 2
C o n t r o ls
C o o lin g S y s t e m c o o l1 2
A ir C o n d it io n e r c o o l1 2
O9 c*ur#e, *nce y*u #ee thi# de#ign it 3ec*+e# clear that the 3a#e cla## Ic**ling #y#te+J i# n*t general en*ugh, and #h*uld 3e rena+ed t* Ite+perature c*ntr*l #y#te+J #* that it can al#* include heatingRat !hich p*int the #u3#tituti*n principle !ill !*rk) H*!ever, the diagra+ a3*ve i# an e;a+ple *9 !hat can happen in de#ign and in the real !*rld) ,hen y*u #ee the #u3#tituti*n principle it# ea#y t* 9eel like thi# appr*ach Gpure #u3#tituti*nH i# the *nly !ay t* d* thing#, and in 9act it is nice i9 y*ur de#ign !*rk# *ut that !ay) But y*ull 9ind that there are ti+e# !hen it# eDually clear that y*u +u#t add ne! 9uncti*n# t* the inter9ace *9 a derived cla##) ,ith in#pecti*n 3*th ca#e# #h*uld 3e rea#*na3ly *3vi*u#)
' Ay ter+)
3(
Thinking in C
www.ThinkingIn.!et
31
!ith, *r that Bird# 3ehavi*r) S* h*! d*e# it happen that, !hen move( ) i# called !hile ign*ring the #peci9ic type *9 Bird, the right 3ehavi*r !ill *ccur Ga oose run#, 9lie#, *r #!i+#, and a !enguin run# *r #!i+#HF
" ir d C o n t r o lle r re L o ca te 12 W hat ha$$ens w h e n # o v e 1 2 is c a lle d < " ir d # o v e 12
# oose # ove12
! e n g u in # ove12
The an#!er i# the pri+ary t!i#t in *34ectE*riented pr*gra++ing1 the c*+piler cann*t +ake a 9uncti*n call in the traditi*nal #en#e) The 9uncti*n call generated 3y a n*nEOOP c*+piler cau#e# !hat i# called earl4 2inding, a ter+ y*u +ay n*t have heard 3e9*re 3ecau#e y*uve never th*ught a3*ut it any *ther !ay) -t +ean# the c*+piler generate# a call t* a #peci9ic 9uncti*n na+e, and the linker re#*lve# thi# call t* the a3#*lute addre## *9 the c*de t* 3e e;ecuted) -n OOP, the pr*gra+ cann*t deter+ine the addre## *9 the c*de until runEti+e, #* #*+e *ther #che+e i# nece##ary !hen a +e##age i# #ent t* a generic *34ect) T* #*lve the pr*3le+, *34ectE*riented language# u#e the c*ncept *9 late 2inding) ,hen y*u #end a +e##age t* an *34ect, the c*de 3eing called i#nt deter+ined until runEti+e) The c*+piler d*e# en#ure that the 9uncti*n e;i#t# and per9*r+# type checking *n the argu+ent# and return value Ga language in !hich thi# i#nt true i# called weakl4 t4"edH, 3ut it d*e#nt kn*! the e;act c*de t* e;ecute) T* per9*r+ late 3inding, C# u#e# a #pecial 3it *9 c*de in lieu *9 the a3#*lute call) Thi# c*de calculate# the addre## *9 the 9uncti*n 3*dy, u#ing in9*r+ati*n #t*red in the *34ect Gthi# pr*ce## i# c*vered in great detail in Chapter %H) Thu#, each *34ect can 3ehave di99erently acc*rding t* the c*ntent# *9 that #pecial 3it *9 c*de) ,hen y*u #end a +e##age t* an *34ect, the *34ect actually d*e# 9igure *ut !hat t* d* !ith that +e##age)
3)
Thinking in C
www.ThinkingIn.!et
-n C#, y*u can ch**#e !hether a language i# earlyE *r lateE3*und) By de9ault, they are earlyE3*und) T* take advantage *9 p*ly+*rphi#+, +eth*d# +u#t 3e de9ined in the 3a#e cla## u#ing the virtual key!*rd and i+ple+ented in inheriting cla##e# !ith the override key!*rd) C*n#ider the #hape e;a+ple) The 9a+ily *9 cla##e# Gall 3a#ed *n the #a+e uni9*r+ inter9aceH !a# diagra++ed earlier in thi# chapter) T* de+*n#trate p*ly+*rphi#+, !e !ant t* !rite a #ingle piece *9 c*de that ign*re# the #peci9ic detail# *9 type and talk# *nly t* the 3a#e cla##) That c*de i# decou"led 9r*+ typeE#peci9ic in9*r+ati*n, and thu# i# #i+pler t* !rite and ea#ier t* under#tand) =nd, i9 a ne! typeRa "exagon, 9*r e;a+pleRi# added thr*ugh inheritance, the c*de y*u !rite !ill !*rk 4u#t a# !ell 9*r the ne! type *9 #hape a# it did *n the e;i#ting type#) Thu#, the pr*gra+ i# e%tensi2le) -9 y*u !rite a +eth*d in C# Ga# y*u !ill #**n learn h*! t* d*H1 *oid :oStuff0Shape #1 ; #.+ra#e013 // ... #.:ra.013 < Thi# 9uncti*n #peak# t* any #hape, #* it i# independent *9 the #peci9ic type *9 *34ect that it# dra!ing and era#ing) -9 in #*+e *ther part *9 the pr*gra+ !e u#e the $o#tuff( ) 9uncti*n1 Circ e c 9 ne. Circ e013 'riang e t 9 ne. 'riang e013 Line 9 ne. Line013 :oStuff0c13 :oStuff0t13 :oStuff0 13 The call# t* $o#tuff( ) aut*+atically !*rk c*rrectly, regardle## *9 the e;act type *9 the *34ect) Thi# i# actually a pretty a+a7ing trick) C*n#ider the line1 :oStuff0c13
33
,hat# happening here i# that a Circle i# 3eing pa##ed int* a 9uncti*n that# e;pecting a #hape) Since a Circle is a #hape it can 3e treated a# *ne 3y $o#tuff( )) That i#, any +e##age that $o#tuff( ) can #end t* a #hape, a Circle can accept) S* it i# a c*+pletely #a9e and l*gical thing t* d*) ,e call thi# pr*ce## *9 treating a derived type a# th*ugh it !ere it# 3a#e type u"casting) The na+e cast i# u#ed in the #en#e *9 ca#ting int* a +*ld and the u" c*+e# 9r*+ the !ay the inheritance diagra+ i# typically arranged, !ith the 3a#e type at the t*p and the derived cla##e# 9anning *ut d*!n!ard) Thu#, ca#ting t* a 3a#e type i# +*ving up the inheritance diagra+1 Iupca#ting)J
Shape
= > $ c a s t in g =
C ir c le
S q u a re
T r ia n g le
=n *34ectE*riented pr*gra+ c*ntain# #*+e upca#ting #*+e!here, 3ecau#e that# h*! y*u dec*uple y*ur#el9 9r*+ kn*!ing a3*ut the e;act type y*ure !*rking !ith) L**k at the c*de in $o#tuff( )1 #.+ra#e013 // ... #.:ra.013 *tice that it d*e#nt #ay I-9 y*ure a Circle, d* thi#, i9 y*ure a #%uare, d* that, etc)J -9 y*u !rite that kind *9 c*de, !hich check# 9*r all the p*##i3le type# that a #hape can actually 3e, it# +e##y and y*u need t* change it every ti+e y*u add a ne! kind *9 #hape) Here, y*u 4u#t #ay I:*ure a #hape, - kn*! y*u can &rase( ) and $raw( ) y*ur#el9, d* it, and take care *9 the detail# c*rrectly)J ,hat# i+pre##ive a3*ut the c*de in $o#tuff( ) i# that, #*+eh*!, the right thing happen#) Calling $raw( ) 9*r Circle cau#e# di99erent c*de t*
34
Thinking in C
www.ThinkingIn.!et
3e e;ecuted than !hen calling $raw( ) 9*r a #%uare *r a Line, 3ut !hen the $raw( ) +e##age i# #ent t* an an*ny+*u# #hape, the c*rrect 3ehavi*r *ccur# 3a#ed *n the actual type *9 the #hape) Thi# i# a+a7ing 3ecau#e, a# +enti*ned earlier, !hen the C# c*+piler i# c*+piling the c*de 9*r $o#tuff( ), it cann*t kn*! e;actly !hat type# it i# dealing !ith) S* *rdinarily, y*ud e;pect it t* end up calling the ver#i*n *9 &rase( ) and $raw( ) 9*r the 3a#e cla## #hape, and n*t 9*r the #peci9ic Circle, #%uare, *r Line) =nd yet the right thing happen# 3ecau#e *9 p*ly+*rphi#+) The c*+piler and runEti+e #y#te+ handle the detail#Q all y*u need t* kn*! i# that it happen#, and +*re i+p*rtant h*! t* de#ign !ith it) ,hen y*u #end a +e##age t* an *34ect, the *34ect !ill d* the right thing, even !hen upca#ting i# inv*lved)
35
inter9ace# t*gether, i9 y*u !i#h, !herea# inheriting 9r*+ +ultiple regular cla##e# *r a3#tract cla##e# i# n*t p*##i3le)
36
Thinking in C
www.ThinkingIn.!et
#t*rage !ill n*t have an i+p*rtant i+pact *n the creati*n *9 an *34ect) -n additi*n, the greater 9le;i3ility i# e##ential t* #*lve the general pr*gra++ing pr*3le+) C# u#e# the #ec*nd appr*ach e;clu#ively, e;cept 9*r -alue t4"es !hich !ill 3e di#cu##ed #h*rtly) Every ti+e y*u !ant t* create an *34ect, y*u u#e the new key!*rd t* 3uild a dyna+ic in#tance *9 that *34ect) ,ith language# that all*! *34ect# t* 3e created *n the #tack, the c*+piler deter+ine# h*! l*ng the *34ect la#t# and can aut*+atically de#tr*y it) H*!ever, i9 y*u create it *n the heap the c*+piler ha# n* kn*!ledge *9 it# li9eti+e) -n a language like C@@, y*u +u#t deter+ine pr*gra++atically !hen t* de#tr*y the *34ect, !hich can lead t* +e+*ry leak# i9 y*u d*nt d* it c*rrectly Gand thi# i# a c*++*n pr*3le+ in C@@ pr*gra+#H) The ) ET runti+e pr*vide# a 9eature called a gar3age c*llect*r that aut*+atically di#c*ver# !hen an *34ect i# n* l*nger in u#e and de#tr*y# it) = gar3age c*llect*r i# +uch +*re c*nvenient 3ecau#e it reduce# the nu+3er *9 i##ue# that y*u +u#t track and the c*de y*u +u#t !rite) A*re i+p*rtant, the gar3age c*llect*r pr*vide# a +uch higher level *9 in#urance again#t the in#idi*u# pr*3le+ *9 +e+*ry leak# G!hich ha# 3r*ught +any a C@@ pr*4ect t* it# knee#H) The re#t *9 thi# #ecti*n l**k# at additi*nal 9act*r# c*ncerning *34ect li9eti+e# and land#cape#)
3#
*34ect# y*ure g*ing t* h*ld in a c*ntainer) "u#t create a c*ntainer *34ect and let it take care *9 the detail#) 5*rtunately, a g**d OOP language c*+e# !ith a #et *9 c*ntainer# a# part *9 the package) -n C@@, it# part *9 the Standard C@@ Li3rary and i# #*+eti+e# called the Standard Te+plate Li3rary GSTLH) O34ect Pa#cal ha# c*ntainer# in it# Ci#ual C*+p*nent Li3rary GCCLH) S+alltalk ha# a very c*+plete #et *9 c*ntainer#) C# al#* ha# c*ntainer# in it# #tandard li3rary) -n #*+e li3rarie#, a generic c*ntainer i# c*n#idered g**d en*ugh 9*r all need#, and in *ther# GC#, 9*r e;a+pleH the li3rary ha# di99erent type# *9 c*ntainer# 9*r di99erent need#1 a vect*r Gcalled an 'rrayList in C#H 9*r c*n#i#tent acce## t* all ele+ent#, Dueue#, ha#hta3le#, tree#, #tack#, etc) =ll c*ntainer# have #*+e !ay t* put thing# in and get thing# *utQ there are u#ually 9uncti*n# t* add ele+ent# t* a c*ntainer, and *ther# t* 9etch th*#e ele+ent# 3ack *ut) But 9etching ele+ent# can 3e +*re pr*3le+atic, 3ecau#e a #ingleE#electi*n 9uncti*n i# re#trictive) ,hat i9 y*u !ant t* +anipulate *r c*+pare a #et *9 ele+ent# in the c*ntainer in#tead *9 4u#t *neF The #*luti*n i# an iterat*r, !hich i# an *34ect !h*#e 4*3 i# t* #elect the ele+ent# !ithin a c*ntainer and pre#ent the+ t* the u#er *9 the iterat*r) =# a cla##, it al#* pr*vide# a level *9 a3#tracti*n) Thi# a3#tracti*n can 3e u#ed t* #eparate the detail# *9 the c*ntainer 9r*+ the c*de that# acce##ing that c*ntainer) The c*ntainer, via the iterat*r, i# a3#tracted t* 3e #i+ply a #eDuence) The iterat*r all*!# y*u t* traver#e that #eDuence !ith*ut !*rrying a3*ut the underlying #tructureRthat i#, !hether it# an 'rrayList, a "ashtable, a #tac(, *r #*+ething el#e) Thi# give# y*u the 9le;i3ility t* ea#ily change the underlying data #tructure !ith*ut di#tur3ing the c*de in y*ur pr*gra+) 5r*+ a de#ign #tandp*int, all y*u really !ant i# a #eDuence that can 3e +anipulated t* #*lve y*ur pr*3le+) -9 a #ingle type *9 #eDuence #ati#9ied all *9 y*ur need#, thered 3e n* rea#*n t* have di99erent kind#) There are t!* rea#*n# that y*u need a ch*ice *9 c*ntainer#) 5ir#t, c*ntainer# pr*vide di99erent type# *9 inter9ace# and e;ternal 3ehavi*r) = #tack ha# a di99erent inter9ace and 3ehavi*r than that *9 a Dueue, !hich i# di99erent 9r*+ that *9 a dicti*nary *r a li#t) One *9 the#e +ight pr*vide a +*re 9le;i3le #*luti*n t* y*ur pr*3le+ than the *ther) Sec*nd, di99erent c*ntainer# have
3&
Thinking in C
www.ThinkingIn.!et
di99erent e99iciencie# 9*r certain *perati*n#) But in the end, re+e+3er that a c*ntainer i# *nly a #t*rage ca3inet t* put *34ect# in) -9 that ca3inet #*lve# all *9 y*ur need#, it d*e#nt really +atter h*! it i# i+ple+ented Ga 3a#ic c*ncept !ith +*#t type# *9 *34ect#H)
3'
r**ted hierarchy and a #y#te+ t* +anipulate an *34ect via a re9erence, it i# di99icult t* i+ple+ent a gar3age c*llect*r) Since runEti+e type in9*r+ati*n i# guaranteed t* 3e in all *34ect#, y*ull never end up !ith an *34ect !h*#e type y*u cann*t deter+ine) Thi# i# e#pecially i+p*rtant !ith #y#te+ level *perati*n#, #uch a# e;cepti*n handling, and t* all*! greater 9le;i3ility in pr*gra++ing)
4(
Thinking in C
www.ThinkingIn.!et
-t# n*t c*+pletely danger*u#, h*!ever, 3ecau#e i9 y*u d*!nca#t t* the !r*ng thing y*ull get a runEti+e err*r called an e%ce"tion6 !hich !ill 3e de#cri3ed #h*rtly) ,hen y*u 9etch *34ect re9erence# 9r*+ a c*ntainer, th*ugh, y*u +u#t have #*+e !ay t* re+e+3er e;actly !hat they are #* y*u can per9*r+ a pr*per d*!nca#t) ?*!nca#ting and the runEti+e check# reDuire e;tra ti+e 9*r the running pr*gra+, and e;tra e99*rt 9r*+ the pr*gra++er) ,*uldnt it +ake #en#e t* #*+eh*! create the c*ntainer #* that it kn*!# the type# that it h*ld#, eli+inating the need 9*r the d*!nca#t and a p*##i3le +i#takeF The #*luti*n i# para+eteri7ed type#, !hich are cla##e# that the c*+piler can aut*+atically cu#t*+i7e t* !*rk !ith particular type#) 5*r e;a+ple, !ith a para+eteri7ed c*ntainer, the c*+piler c*uld cu#t*+i7e that c*ntainer #* that it !*uld accept *nly Shape# and 9etch *nly Shape#) Para+eteri7ed type# are an i+p*rtant part *9 C@@, partly 3ecau#e C@@ ha# n* #ingly r**ted hierarchy) -n C@@, the key!*rd that i+ple+ent# para+eteri7ed type# i# Ite+plate)J ) ET currently ha# n* para+eteri7ed type# #ince it i# p*##i3le 9*r it t* get 3yRh*!ever a!k!ardlyRu#ing the #ingly r**ted hierarchy) H*!ever, there i# n* d*u3t that para+eteri7ed type# !ill 3e i+ple+ented in a 9uture ver#i*n *9 the ) ET 5ra+e!*rk)
41
airEtra99icEc*ntr*l 7*ne) 5*r cleanup, #i+ply delete the appr*priate airplane *34ect !hen a plane leave# the 7*ne) But perhap# y*u have #*+e *ther #y#te+ t* rec*rd data a3*ut the plane#Q perhap# data that d*e#nt reDuire #uch i++ediate attenti*n a# the +ain c*ntr*ller 9uncti*n) Aay3e it# a rec*rd *9 the 9light plan# *9 all the #+all plane# that leave the airp*rt) S* y*u have a #ec*nd c*ntainer *9 #+all plane#, and !henever y*u create a plane *34ect y*u al#* put it in thi# #ec*nd c*ntainer i9 it# a #+all plane) Then #*+e 3ackgr*und pr*ce## per9*r+# *perati*n# *n the *34ect# in thi# c*ntainer during idle +*+ent#) *! the pr*3le+ i# +*re di99icult1 h*! can y*u p*##i3ly kn*! !hen t* de#tr*y the *34ect#F ,hen y*ure d*ne !ith the *34ect, #*+e *ther part *9 the #y#te+ +ight n*t 3e) Thi# #a+e pr*3le+ can ari#e in a nu+3er *9 *ther #ituati*n#, and in pr*gra++ing #y#te+# G#uch a# C@@H in !hich y*u +u#t e;plicitly delete an *34ect !hen y*ure d*ne !ith it thi# can 3ec*+e Duite c*+ple;) ,ith C#, the gar3age c*llect*r i# de#igned t* take care *9 the pr*3le+ *9 relea#ing the +e+*ry Galth*ugh thi# d*e#nt include *ther a#pect# *9 cleaning up an *34ectH) The gar3age c*llect*r Ikn*!#J !hen an *34ect i# n* l*nger in u#e, and it then aut*+atically relea#e# the +e+*ry 9*r that *34ect) Thi# Gc*+3ined !ith the 9act that all *34ect# are inherited 9r*+ the #ingle r**t cla## ob)ect and that y*u can create *34ect# *nly *ne !ay, *n the heapH +ake# the pr*ce## *9 pr*gra++ing in C# +uch #i+pler than pr*gra++ing in C@@) :*u have 9ar 9e!er deci#i*n# t* +ake and hurdle# t* *verc*+e)
4)
Thinking in C
www.ThinkingIn.!et
Creating *34ect# *n the heap can 3e +uch +*re e;pen#ive) =l!ay# inheriting 9r*+ a 3a#e cla## and +aking all 9uncti*n call# p*ly+*rphic al#* e;act# a #+all t*ll) But the gar3age c*llect*r i# a particular pr*3le+ 3ecau#e y*u never Duite kn*! !hen it# g*ing t* #tart up *r h*! l*ng it !ill take) Thi# +ean# that there# an inc*n#i#tency in the rate *9 e;ecuti*n *9 a C# pr*gra+, #* y*u cant u#e it in certain #ituati*n#, #uch a# !hen the rate *9 e;ecuti*n *9 a pr*gra+ i# uni9*r+ly critical) GThe#e are generally called real ti+e pr*gra+#, alth*ugh n*t all real ti+e pr*gra++ing pr*3le+# are thi# #tringent)H The de#igner# *9 the C@@ language, trying t* !** C pr*gra++er# Gand +*#t #ucce##9ully, at thatH, did n*t !ant t* add any 9eature# t* the language that !*uld i+pact the #peed *r the u#e *9 C@@ in any #ituati*n !here pr*gra++er# +ight *ther!i#e ch**#e C) Thi# g*al !a# reali7ed, 3ut at the price *9 greater c*+ple;ity !hen pr*gra++ing in C@@) C# i# #i+pler than C@@, 3ut the tradeE*99 i# in e99iciency and #*+eti+e# applica3ility) 5*r a #igni9icant p*rti*n *9 pr*gra++ing pr*3le+#, h*!ever, C# i# the #uperi*r ch*ice)
43
err*r) -t# a# i9 e;cepti*n handling i# a di99erent, parallel path *9 e;ecuti*n that can 3e taken !hen thing# g* !r*ng) =nd 3ecau#e it u#e# a #eparate e;ecuti*n path, it d*e#nt need t* inter9ere !ith y*ur n*r+ally e;ecuting c*de) Thi# +ake# that c*de #i+pler t* !rite #ince y*u arent c*n#tantly 9*rced t* check 9*r err*r#) -n additi*n, a thr*!n e;cepti*n i# unlike an err*r value that# returned 9r*+ a 9uncti*n *r a 9lag that# #et 3y a 9uncti*n in *rder t* indicate an err*r c*nditi*nRthe#e can 3e ign*red) =n e;cepti*n cann*t 3e ign*red, #* it# guaranteed t* 3e dealt !ith at #*+e p*int) 5inally, e;cepti*n# pr*vide a !ay t* relia3ly rec*ver 9r*+ a 3ad #ituati*n) -n#tead *9 4u#t e;iting y*u are *9ten a3le t* #et thing# right and re#t*re the e;ecuti*n *9 a pr*gra+, !hich pr*duce# +uch +*re r*3u#t pr*gra+#) -t# !*rth n*ting that e;cepti*n handling i#nt an *34ectE*riented 9eature, alth*ugh in *34ectE*riented language# the e;cepti*n i# n*r+ally repre#ented !ith an *34ect) E;cepti*n handling e;i#ted 3e9*re *34ectE *riented language#)
@ultithreading
= 9unda+ental c*ncept in c*+puter pr*gra++ing i# the idea *9 handling +*re than *ne ta#k at a ti+e) Aany pr*gra++ing pr*3le+# reDuire that the pr*gra+ 3e a3le t* #t*p !hat it# d*ing, deal !ith #*+e *ther pr*3le+, and then return t* the +ain pr*ce##) The #*luti*n ha# 3een appr*ached in +any !ay#) -nitially, pr*gra++er# !ith l*!Elevel kn*!ledge *9 the +achine !r*te interrupt #ervice r*utine# and the #u#pen#i*n *9 the +ain pr*ce## !a# initiated thr*ugh a hard!are interrupt) =lth*ugh thi# !*rked !ell, it !a# di99icult and n*np*rta3le, #* it +ade +*ving a pr*gra+ t* a ne! type *9 +achine #l*! and e;pen#ive) S*+eti+e# interrupt# are nece##ary 9*r handling ti+eEcritical ta#k#, 3ut there# a large cla## *9 pr*3le+# in !hich y*ure #i+ply trying t* partiti*n the pr*3le+ int* #eparately running piece# #* that the !h*le pr*gra+ can 3e +*re re#p*n#ive) ,ithin a pr*gra+, the#e #eparately running piece# are called thread#, and the general c*ncept i# called multithreading. = c*++*n e;a+ple *9 +ultithreading i# the u#er inter9ace) By u#ing
44
Thinking in C
www.ThinkingIn.!et
thread#, a u#er can pre## a 3utt*n and get a Duick re#p*n#e rather than 3eing 9*rced t* !ait until the pr*gra+ 9ini#he# it# current ta#k) Ordinarily, thread# are 4u#t a !ay t* all*cate the ti+e *9 a #ingle pr*ce##*r) But i9 the *perating #y#te+ #upp*rt# +ultiple pr*ce##*r#, each thread can 3e a##igned t* a di99erent pr*ce##*r and they can truly run in parallel) One *9 the c*nvenient 9eature# *9 +ultithreading at the language level i# that the pr*gra++er d*e#nt need t* !*rry a3*ut !hether there are +any pr*ce##*r# *r 4u#t *ne) The pr*gra+ i# l*gically divided int* thread# and i9 the +achine ha# +*re than *ne pr*ce##*r then the pr*gra+ run# 9a#ter, !ith*ut any #pecial ad4u#t+ent#) =ll thi# +ake# threading #*und pretty #i+ple) There i# a catch1 #hared re#*urce#) -9 y*u have +*re than *ne thread running that# e;pecting t* acce## the #a+e re#*urce y*u have a pr*3le+) 5*r e;a+ple, t!* pr*ce##e# cant #i+ultane*u#ly #end in9*r+ati*n t* a printer) T* #*lve the pr*3le+, re#*urce# that can 3e #hared, #uch a# the printer, +u#t 3e l*cked !hile they are 3eing u#ed) S* a thread l*ck# a re#*urce, c*+plete# it# ta#k, and then relea#e# the l*ck #* that #*+e*ne el#e can u#e the re#*urce) C## threading i# 3uilt int* the language, !hich +ake# a c*+plicated #u34ect +uch #i+pler) The threading i# #upp*rted *n an *34ect level, #* *ne thread *9 e;ecuti*n i# repre#ented 3y *ne *34ect) C# al#* pr*vide# li+ited re#*urce l*cking) -t can l*ck the +e+*ry *9 any *34ect G!hich i#, a9ter all, *ne kind *9 #hared re#*urceH #* that *nly *ne thread can u#e it at a ti+e) Thi# i# acc*+pli#hed !ith the loc( key!*rd) Other type# *9 re#*urce# +u#t 3e l*cked e;plicitly 3y the pr*gra++er, typically 3y creating an *34ect t* repre#ent the l*ck that all thread# +u#t check 3e9*re acce##ing that re#*urce)
Persistence
tk
45
Client?'erver co#$uting
tk
Client;side $rogra##ing
tk
Plug;ins
tk
'cri$ting languages
tk
6ich clients in C#
tk
'ecurit5
tk
'erver;side $rogra##ing
tk
46
Thinking in C
www.ThinkingIn.!et
%&tre#e $rogra##ing
tk
4#
C# i# de#igned t* aid "rogramming in the largeRthat i#, t* era#e th*#e creepingEc*+ple;ity 3*undarie# 3et!een a #+all pr*gra+ and a large *ne) :*u certainly d*nt need t* u#e OOP !hen y*ure !riting a Ihell* !*rldJ #tyle utility pr*gra+, 3ut the 9eature# are there !hen y*u need the+) =nd the c*+piler i# aggre##ive a3*ut 9erreting *ut 3ugEpr*ducing err*r# 9*r #+all and large pr*gra+# alike)
Guidelines
Here are #*+e guideline# t* c*n#ider !hen +aking the tran#iti*n t* ) ET and C#1
1. -raining
The 9ir#t #tep i# #*+e 9*r+ *9 educati*n) Re+e+3er the c*+pany# inve#t+ent in c*de, and try n*t t* thr*! everything int* di#array 9*r #i; t* nine +*nth# !hile every*ne pu77le# *ver h*! inter9ace# !*rk) Pick a #+all gr*up 9*r ind*ctrinati*n, pre9era3ly *ne c*+p*#ed *9 pe*ple !h* are curi*u#, !*rk !ell t*gether, and can 9uncti*n a# their *!n #upp*rt net!*rk !hile theyre learning C# and ) ET) =n alternative appr*ach that i# #*+eti+e# #ugge#ted i# the educati*n *9 all c*+pany level# at *nce, including *vervie! c*ur#e# 9*r #trategic +anager# a# !ell a# de#ign and pr*gra++ing c*ur#e# 9*r pr*4ect 3uilder#) Thi# i# e#pecially g**d 9*r #+aller c*+panie# +aking 9unda+ental #hi9t# in the !ay they d* thing#, *r at the divi#i*n level *9 larger c*+panie#) Becau#e the c*#t i# higher, h*!ever, #*+e +ay ch**#e t* #tart !ith pr*4ectElevel training, d* a pil*t pr*4ect Gp*##i3ly !ith an *ut#ide +ent*rH, and let the pr*4ect tea+ 3ec*+e the teacher# 9*r the re#t *9 the c*+pany)
2. Low;ris* $ro/ect
Try a l*!Eri#k pr*4ect 9ir#t and all*! 9*r +i#take#) Once y*uve gained #*+e e;perience, y*u can either #eed *ther pr*4ect# 9r*+ +e+3er# *9 thi# 9ir#t tea+ *r u#e the tea+ +e+3er# a# a ) ET technical #upp*rt #ta99) Thi#
4&
Thinking in C
www.ThinkingIn.!et
9ir#t pr*4ect +ay n*t !*rk right the 9ir#t ti+e, #* it #h*uld n*t 3e +i##i*nE critical 9*r the c*+pany) -t #h*uld 3e #i+ple, #el9Ec*ntained, and in#tructiveQ thi# +ean# that it #h*uld inv*lve creating cla##e# that !ill 3e +eaning9ul t* the *ther pr*gra++er# in the c*+pany !hen they get their turn t* learn C# and ) ET)
4'
@anage#ent o+stacles
-9 y*ure a +anager, y*ur 4*3 i# t* acDuire re#*urce# 9*r y*ur tea+, t* *verc*+e 3arrier# t* y*ur tea+# #ucce##, and in general t* try t* pr*vide the +*#t pr*ductive and en4*ya3le envir*n+ent #* y*ur tea+ i# +*#t likely t* per9*r+ th*#e +iracle# that are al!ay# 3eing a#ked *9 y*u) A*ving t* ) ET 9all# in all three *9 the#e categ*rie#, and it !*uld 3e !*nder9ul i9 it didnt c*#t y*u anything a# !ell) =lth*ugh +*ving t* ) ET +ay 3e cheaperRdepending *n y*ur c*n#traint#Rthan the alternative# 9*r a tea+ *9 Ci#ual Ba#ic pr*gra++er# Gand pr*3a3ly 9*r pr*gra++er# in *ther pr*cedural language#H, it i#nt 9ree, and there are *3#tacle# y*u #h*uld 3e a!are *9 3e9*re trying t* #ell the +*ve t* C# !ithin y*ur c*+pany and e+3arking *n the +*ve it#el9)
'tartu$ costs
tk
Per0or#ance issues
tk
C# vs. Aava<
tk
'u##ar5
tk
5(
Thinking in C
www.ThinkingIn.!et
3, 9ello. O+/ects
=lth*ugh it i# 3a#ed *n C@@, C# i# +*re *9 a IpureJ *34ectE*riented language)
B*th C@@ and C# are hy3rid language#, 3ut in C# the de#igner# 9elt that the hy3ridi7ati*n !a# n*t a# i+p*rtant a# it !a# in C@@) = hy3rid language all*!# +ultiple pr*gra++ing #tyle#Q the rea#*n C@@ i# hy3rid i# t* #upp*rt 3ack!ard c*+pati3ility !ith the C language) Becau#e C@@ i# a #uper#et *9 the C language, it include# +any *9 that language# unde#ira3le 9eature#, !hich can +ake #*+e a#pect# *9 C@@ *verly c*+plicated) The C# language a##u+e# that y*u !ant t* d* *nly *34ectE*riented pr*gra++ing) Thi# +ean# that 3e9*re y*u can 3egin y*u +u#t #hi9t y*ur +ind#et int* an *34ectE*riented !*rld Gunle## it# already thereH. The 3ene9it *9 thi# initial e99*rt i# the a3ility t* pr*gra+ in a language that i# #i+pler t* learn and t* u#e than +any *ther OOP language#) -n thi# chapter !ell #ee the 3a#ic c*+p*nent# *9 a C# pr*gra+ and !ell learn that everything in C# i# an *34ect, even a C# pr*gra+)
51
Ire9erenceJ t* an *34ect) :*u +ight i+agine thi# #cene a# a televi#i*n Gthe *34ectH !ith y*ur re+*te c*ntr*l Gthe re9erenceH) =# l*ng a# y*ure h*lding thi# re9erence, y*u have a c*nnecti*n t* the televi#i*n, 3ut !hen #*+e*ne #ay# Ichange the channelJ *r Il*!er the v*lu+e,J !hat y*ure +anipulating i# the re9erence, !hich in turn +*di9ie# the *34ect) -9 y*u !ant t* +*ve ar*und the r**+ and #till c*ntr*l the televi#i*n, y*u take the re+*te<re9erence !ith y*u, n*t the televi#i*n) =l#*, the re+*te c*ntr*l can #tand *n it# *!n, !ith n* televi#i*n) That i#, 4u#t 3ecau#e y*u have a re9erence d*e#nt +ean there# nece##arily an *34ect c*nnected t* it) S* i9 y*u !ant t* h*ld a !*rd *r #entence, y*u create a string re9erence1 #tring #3 But here y*uve created onl4 the re9erence, n*t an *34ect) -9 y*u decided t* #end a +e##age t* s at thi# p*int, y*ull get an err*r Gat runEti+eH 3ecau#e s i#nt actually attached t* anything Gthere# n* televi#i*nH) = #a9er practice, then, i# al!ay# t* initiali7e a re9erence !hen y*u create it1 #tring # 9 &a#df&3 H*!ever, thi# u#e# a #pecial 9eature1 #tring# can 3e initiali7ed !ith Du*ted te;t) *r+ally, y*u +u#t u#e a +*re general type *9 initiali7ati*n 9*r *34ect#)
5)
O9 c*ur#e, string i# n*t the *nly type that e;i#t#) C# c*+e# !ith a pleth*ra *9 readyE+ade type#) ,hat# +*re i+p*rtant i# that y*u can create y*ur *!n type#) -n 9act, that# the 9unda+ental activity in C# pr*gra++ing, and it# !hat y*ull 3e learning a3*ut in the re#t *9 thi# 3**k)
2.
3.
53
and the #t*rage i# all*cated *n the heap !hen that c*de i# e;ecuted) O9 c*ur#e there# a price y*u pay 9*r thi# 9le;i3ility1 it take# +*re ti+e t* all*cate heap #t*rage than it d*e# t* all*cate #tack #t*rage Gthat i#, i9 y*u even could create *34ect# *n the #tack in C#, a# y*u can in C@@H) . #tatic storage) IStaticJ i# u#ed here in the #en#e *9 Iin a 9i;ed l*cati*nJ Galth*ugh it# al#* in R=AH) Static #t*rage c*ntain# data that i# availa3le 9*r the entire ti+e a pr*gra+ i# running) :*u can u#e the static key!*rd t* #peci9y that a particular ele+ent *9 an *34ect i# #tatic, 3ut C# *34ect# the+#elve# are never placed in #tatic #t*rage) Constant storage) C*n#tant value# are *9ten placed directly in the pr*gra+ c*de, !hich i# #a9e #ince they can never change) S*+eti+e# c*n#tant# are c*rd*ned *99 3y the+#elve# #* that they can 3e *pti*nally placed in readE*nly +e+*ry GROAH) ,on-*'. storage) -9 data live# c*+pletely *ut#ide a pr*gra+ it can e;i#t !hile the pr*gra+ i# n*t running, *ut#ide the c*ntr*l *9 the pr*gra+) The t!* pri+ary e;a+ple# *9 thi# are streamed o23ects6 in !hich *34ect# are turned int* #trea+# *9 3yte#, generally t* 3e #ent t* an*ther +achine, and "ersistent o23ects6 in !hich the *34ect# are placed *n di#k #* they !ill h*ld their #tate even !hen the pr*gra+ i# ter+inated) The trick !ith the#e type# *9 #t*rage i# turning the *34ect# int* #*+ething that can e;i#t *n the *ther +ediu+, and yet can 3e re#urrected int* a regular R=AE3a#ed *34ect !hen nece##ary) C# pr*vide# #upp*rt 9*r lightweight "ersistence, and 9uture ver#i*n# *9 ) ET +ight pr*vide +*re c*+plete #*luti*n# 9*r per#i#tence)
!.
".
)rra5s in Aava
Cirtually all pr*gra++ing language# #upp*rt array#) U#ing array# in C and C@@ i# peril*u# 3ecau#e th*#e array# are *nly 3l*ck# *9 +e+*ry) -9 a pr*gra+ acce##e# the array *ut#ide *9 it# +e+*ry 3l*ck *r u#e# the +e+*ry 3e9*re initiali7ati*n Gc*++*n pr*gra++ing err*r#H there !ill 3e unpredicta3le re#ult#)
54
Thinking in C
www.ThinkingIn.!et
One *9 the pri+ary g*al# *9 C# i# #a9ety, #* +any *9 the pr*3le+# that plague pr*gra++er# in C and C@@ are n*t repeated in C#) = C# array i# guaranteed t* 3e initiali7ed and cann*t 3e acce##ed *ut#ide *9 it# range) The range checking c*+e# at the price *9 having a #+all a+*unt *9 +e+*ry *verhead *n each array a# !ell a# veri9ying the inde; at runEti+e, 3ut the a##u+pti*n i# that the #a9ety and increa#ed pr*ductivity i# !*rth the e;pen#e) ,hen y*u create an array *9 *34ect#, y*u are really creating an array *9 re9erence#, and each *9 th*#e re9erence# i# aut*+atically initiali7ed t* a #pecial value !ith it# *!n key!*rd1 null) ,hen C# #ee# null, it rec*gni7e# that the re9erence in Due#ti*n i#nt p*inting t* an *34ect) :*u +u#t a##ign an *34ect t* each re9erence 3e9*re y*u u#e it, and i9 y*u try t* u#e a re9erence that# #till null, the pr*3le+ !ill 3e rep*rted at runEti+e) Thu#, typical array err*r# are prevented in C#) :*u can al#* create an array *9 value type#) =gain, the c*+piler guarantee# initiali7ati*n 3ecau#e it 7er*e# the +e+*ry 9*r that array) =rray# !ill 3e c*vered in detail in later chapter#)
55
and #* 9*rth and +any pe*ple have 9*und that thi# ha# 3een #u99icient t* +ake "ava appr*priate 9*r al+*#t all per9*r+anceE*riented ta#k#) C# g*e# a #tep 3ey*ndQ n*t *nly are value# Grather than cla##e#H u#ed 9*r 3a#ic nu+eric type#, devel*per# can create ne! value type# in the 9*r+ *9 enu+erati*n# Genum#H and #tructure# Gstruct#H) Calue type# can 3e tran#parently c*nverted t* *34ect re9erence# via a pr*ce## kn*!n a# I3*;ing)J Thi# i# a nice advantage *9 C# *ver "ava, !here turning a pri+itive type int* an *34ect re9erence reDuire# an e;plicit +eth*d call)
'co$ing
A*#t pr*cedural language# have the c*ncept *9 sco"e) Thi# deter+ine# 3*th the vi#i3ility and li9eti+e *9 the na+e# de9ined !ithin that #c*pe) -n C, C@@, and C#, #c*pe i# deter+ined 3y the place+ent *9 curly 3race# /0) S* 9*r e;a+ple1 ; int x 9 "23 /= on y x a*ai a$ e =/ ; int 7 9 >?3 /= $oth x @ 7 a*ai a$ e =/ < /= on y x a*ai a$ e =/ /= 7 Aout of #copeB =/ <
56
Thinking in C
www.ThinkingIn.!et
= varia3le de9ined !ithin a #c*pe i# availa3le *nly t* the end *9 that #c*pe) -ndentati*n +ake# C# c*de ea#ier t* read) Since C# i# a 9reeE9*r+ language, the e;tra #pace#, ta3#, and carriage return# d* n*t a99ect the re#ulting pr*gra+) *te that y*u cannot d* the 9*ll*!ing, even th*ugh it i# legal in C and C@ @1 ; int x 9 "23 ; int x 9 >?3 /= i < < The c*+piler !ill ann*unce that the varia3le x ha# already 3een de9ined) Thu# the C and C@@ a3ility t* IhideJ a varia3le in a larger #c*pe i# n*t all*!ed 3ecau#e the C# de#igner# th*ught that it led t* c*n9u#ing pr*gra+#) ega =/
'co$e o0 o+/ects
C# *34ect# d* n*t have the #a+e li9eti+e# a# value type#) ,hen y*u create a C# *34ect u#ing new, it hang# ar*und pa#t the end *9 the #c*pe) Thu# i9 y*u u#e1 ; #tring # 9 ne. #tring0&a #tring&13 < /= end of #cope =/ the re9erence s vani#he# at the end *9 the #c*pe) H*!ever, the string *34ect that s !a# p*inting t* i# #till *ccupying +e+*ry) -n thi# 3it *9 c*de, there i# n* !ay t* acce## the *34ect 3ecau#e the *nly re9erence t* it i# *ut *9 #c*pe) -n later chapter# y*ull #ee h*! the re9erence t* the *34ect can 3e pa##ed ar*und and duplicated during the c*ur#e *9 a pr*gra+) -t turn# *ut that 3ecau#e *34ect# created !ith new #tay ar*und 9*r a# l*ng a# y*u !ant the+, a !h*le #le! *9 C@@ pr*gra++ing pr*3le+# #i+ply vani#h in C#) The harde#t pr*3le+# #ee+ t* *ccur in C@@ 3ecau#e y*u d*nt get any help 9r*+ the language in +aking #ure that the *34ect# are
5#
availa3le !hen theyre needed) =nd +*re i+p*rtant, in C@@ y*u +u#t +ake #ure that y*u de#tr*y the *34ect# !hen y*ure d*ne !ith the+) That 3ring# up an intere#ting Due#ti*n) -9 C# leave# the *34ect# lying ar*und, !hat keep# the+ 9r*+ 9illing up +e+*ry and halting y*ur pr*gra+F Thi# i# e;actly the kind *9 pr*3le+ that !*uld *ccur in C@@) Thi# i# !here a 3it *9 +agic happen#) The ) ET runti+e ha# a gar2age collector, !hich l**k# at all the *34ect# that !ere created !ith new and 9igure# *ut !hich *ne# are n*t 3eing re9erenced any+*re) Then it relea#e# the +e+*ry 9*r th*#e *34ect#, #* the +e+*ry can 3e u#ed 9*r ne! *34ect#) Thi# +ean# that y*u never need t* !*rry a3*ut reclai+ing +e+*ry y*ur#el9) :*u #i+ply create *34ect#, and !hen y*u n* l*nger need the+ they !ill g* a!ay 3y the+#elve#) Thi# eli+inate# a certain cla## *9 pr*gra++ing pr*3le+1 the #*Ecalled I+e+*ry leak,J in !hich a pr*gra++er 9*rget# t* relea#e +e+*ry)
5&
Thinking in C
www.ThinkingIn.!et
t* d* +uch *9 anything Gthat i#, y*u cann*t #end it any intere#ting +e##age#H until y*u de9ine #*+e +eth*d# 9*r it)
5'
-t i# al#* p*##i3le that y*ur *34ect +ight c*ntain *ther *34ect# that c*ntain data y*ud like t* +*di9y) 5*r thi#, y*u 4u#t keep Ic*nnecting the d*t#)J 5*r e;a+ple1 !y- ane. eft'an%.capacity 9 "003 The $ata1nly cla## cann*t d* +uch *9 anything e;cept h*ld data, 3ecau#e it ha# n* +e+3er 9uncti*n# G+eth*d#H) T* under#tand h*! th*#e !*rk, y*u +u#t 9ir#t under#tand arguments and return -alues, !hich !ill 3e de#cri3ed #h*rtly)
*te care9ully that the de9ault value# are !hat C# guarantee# !hen the varia3le i# u#ed as a mem2er o$ a class) Thi# en#ure# that +e+3er varia3le# *9 pri+itive type# !ill al!ay# 3e initiali7ed G#*+ething C@@ d*e#nt d*H, reducing a #*urce *9 3ug#) H*!ever, thi# initial value +ay n*t 3e c*rrect *r even legal 9*r the pr*gra+ y*u are !riting) -t# 3e#t t* al!ay# e;plicitly initiali7e y*ur varia3le#) Thi# guarantee d*e#nt apply t* Il*calJ varia3le#Rth*#e that are n*t 9ield# *9 a cla##) Thu#, i9 !ithin a 9uncti*n de9initi*n y*u have1 int x3
6(
Thinking in C
www.ThinkingIn.!et
Then x !ill get #*+e ar3itrary value Ga# in C and C@@HQ it !ill n*t aut*+atically 3e initiali7ed t* 7er*) :*u are re#p*n#i3le 9*r a##igning an appr*priate value 3e9*re y*u u#e x) -9 y*u 9*rget, C# de9initely i+pr*ve# *n C@@1 y*u get a c*+pileEti+e err*r telling y*u the varia3le +ight n*t have 3een initiali7ed) GAany C@@ c*+piler# !ill !arn y*u a3*ut uninitiali7ed varia3le#, 3ut in C# the#e are err*r#)H
The return type i# the type *9 the value that p*p# *ut *9 the +eth*d a9ter y*u call it) The argu+ent li#t give# the type# and na+e# 9*r the in9*r+ati*n y*u !ant t* pa## int* the +eth*d) The +eth*d na+e and argu+ent li#t t*gether uniDuely identi9y the +eth*d) Aeth*d# in C# can 3e created *nly a# part *9 a cla##) = +eth*d can 3e called *nly 9*r an *34ect,0 and that *34ect +u#t 3e a3le t* per9*r+ that +eth*d call) -9 y*u try t* call the !r*ng +eth*d 9*r an *34ect, y*ull get an err*r +e##age at c*+pileEti+e) :*u call a +eth*d 9*r an *34ect 3y na+ing the *34ect 9*ll*!ed 3y a peri*d Gd*tH, 9*ll*!ed 3y the na+e *9 the +eth*d
0 static +eth*d#, !hich y*ull learn a3*ut #**n, can 3e called $or the class, !ith*ut an
*34ect)
61
and it# argu+ent li#t, like thi#1 ob)ect,ame6.ethod,ame(arg7, arg8, arg9)) 5*r e;a+ple, #upp*#e y*u have a +eth*d :( ) that take# n* argu+ent# and return# a value *9 type int) Then, i9 y*u have an *34ect called a 9*r !hich :( ) can 3e called, y*u can #ay thi#1 int x 9 a.H013 The type *9 the return value +u#t 3e c*+pati3le !ith the type *9 x) Thi# act *9 calling a +eth*d i# c*++*nly re9erred t* a# sending a message to an o23ect) -n the a3*ve e;a+ple, the +e##age i# :( ) and the *34ect i# a) O34ectE*riented pr*gra++ing i# *9ten #u++ari7ed a# #i+ply I#ending +e##age# t* *34ect#)J
6)
Thinking in C
www.ThinkingIn.!et
pr*perty i# u#ed, !hich i# *ne *9 the pr*pertie# *9 string#Q it return# the nu+3er *9 character# in a #tring) :*u can al#* #ee the u#e *9 the return key!*rd, !hich d*e# t!* thing#) 5ir#t, it +ean# Ileave the +eth*d, -+ d*ne)J Sec*nd, i9 the +eth*d pr*duce# a value, that value i# placed right a9ter the return #tate+ent) -n thi# ca#e, the return value i# pr*duced 3y evaluating the e;pre##i*n s6Length ; 8) :*u can return any type y*u !ant, 3ut i9 y*u d*nt !ant t* return anything at all, y*u d* #* 3y indicating that the +eth*d return# void) Here are #*+e e;a+ple#1 $oo ean H ag01 ; return true3 < f oat Catura LogBa#e01 ; return 2.F"If3 < *oid Cothing01 ; return3 < *oid Cothing201 ;< ,hen the return type i# void, then the return key!*rd i# u#ed *nly t* e;it the +eth*d, and i# there9*re unnece##ary !hen y*u reach the end *9 the +eth*d) :*u can return 9r*+ a +eth*d at any p*int, 3ut i9 y*uve given a n*nEvoid return type then the c*+piler !ill 9*rce y*u G!ith err*r +e##age#H t* return the appr*priate type *9 value regardle## *9 !here y*u return) =t thi# p*int, it can l**k like a pr*gra+ i# 4u#t a 3unch *9 *34ect# !ith +eth*d# that take *ther *34ect# a# argu+ent# and #end +e##age# t* th*#e *ther *34ect#) That i# indeed +uch *9 !hat g*e# *n, 3ut in the 9*ll*!ing chapter y*ull learn h*! t* d* the detailed l*!Elevel !*rk 3y +aking deci#i*n# !ithin a +eth*d) 5*r thi# chapter, #ending +e##age# !ill #u99ice)
63
=ttri3ute# are #peci9ied in C# u#ing #Duare 3racket# 4u#t 3e9*re the c*de ele+ent) =dding an attri3ute t* a c*de ele+ent d*e#nt change the 3ehavi*r *9 the c*de ele+entQ rather, pr*gra+# can 3e !ritten !hich #ay I5*r all the c*de ele+ent# that have thi# attri3ute, d* thi# 3ehavi*r)J The +*#t i++ediately p*!er9ul de+*n#trati*n *9 thi# i# the <=eb.ethod> attri3ute !hich !ithin Ci#ual Studi* ) ET i# all that i# nece##ary t* trigger the e;p*#ure *9 that +eth*d a# a ,e3 Service) =ttri3ute# can 3e u#ed t* #i+ply tag a c*de ele+ent, a# !ith <=eb.ethod> *r they can c*ntain para+eter# that c*ntain additi*nal in9*r+ati*n) 5*r in#tance, thi# e;a+ple #h*!# an ?.L&lement attri3ute that #peci9ie# that, !hen #eriali7ed t* an BAL d*cu+ent, the :light#egment< > array #h*uld 3e created a# a #erie# *9 individual :light#egment ele+ent#1 J,! + e!ent0 + e!entCa!e 9 &H ightSeg!ent&1K pu$ ic H ightSeg!entJK f ight#3
4elegates
-n additi*n t* cla##e# and value type#, C# ha# an *34ectE*riented type that #peci9ie# a +eth*d signature) = +eth*d# #ignature c*n#i#t# *9 it# argu+ent li#t and it# return type) = delegate i# a type that all*!# any +eth*d !h*#e #ignature i# identical t* that #peci9ied in the delegate de9initi*n t* 3e u#ed a# an Iin#tanceJ *9 that delegate) -n thi# !ay, a +eth*d can 3e u#ed a# i9 it !ere a varia3le P in#tantiated, a##igned t*, pa##ed ar*und in re9erence 9*r+, etc) -n thi# e;a+ple, a delegate na+ed 5** i# de9ined1 de egate *oid Hoo0int x13 c a## GyC a##; *oid So!eGethod0int y1; L < int )notherGethod0int M1; L < < c a## GyOtherC a##; *oid /et)nother01; L <
64
Thinking in C
www.ThinkingIn.!et
#tatic *oid So!eOther0int M1; L < < The +eth*d .yClass6#ome.ethod( ) c*uld 3e u#ed t* in#tantiate the :oo delegate, a# c*uld the +eth*d .y1therClass6#ome1ther( )) either .yClass)'nother.ethod( ) n*r .y1therClass6@et'nother( ) can 3e u#ed a# :oo#, a# they have di99erent #ignature#) -n#tantiating a re9erence t* a delegate i# 4u#t like +aking a re9erence t* a cla##1 Hoo f 9 GyOtherC a##.So!eOther3 The le9tEhand #i7e c*ntain# a declarati*n *9 a varia3le f *9 type delegate :oo) The rightEhand #i7e s"eci$ies a +eth*d, it d*e# n*t actually call the +eth*d #ome1ther( )) ?elegate# are a +a4*r ele+ent in pr*gra++ing ,ind*!# 5*r+#, 3ut they repre#ent a +a4*r de#ign 9eature in C# and are u#e9ul in +any #ituati*n#)
Pro$erties
5ield# #h*uld, e##entially, never 3e availa3le directly t* the *ut#ide !*rld) Ai#take# are *9ten +ade !hen a 9ield i# a##igned t*Q the 9ield i# #upp*#ed t* #t*re a di#tance in +etric n*t Engli#h unit#, #tring# are #upp*#ed t* 3e all l*!erca#e, etc) H*!ever, #uch +i#take# are *9ten n*t $ound until the 9ield i# u#ed at a +uch later ti+e Glike, #ay, !hen preparing t* enter Aar# *r3itH) ,hile #uch l*gical +i#take# cann*t 3e di#c*vered 3y any aut*+atic +ean#, di#c*vering the+ can 3e +ade ea#ier 3y *nly all*!ing 9ield# t* 3e acce##ed via +eth*d# G!hich, in turn, can pr*vide additi*nal #anity check# and l*gging trace#H) C# all*!# y*u t* give y*ur cla##e# the appearance *9 having 9ield# directly e;p*#ed 3ut in 9act hiding the+ 3ehind +eth*d inv*cati*n#) The#e !roperty 9ield# c*+e in t!* varietie#1 readE*nly 9ield# that cann*t 3e a##igned t*, and the +*re c*++*n readEandE!rite 9ield#) =dditi*nally, pr*pertie# all*! y*u t* u#e a di99erent type internally t* #t*re the data 9r*+ the type y*u e;p*#e) 5*r in#tance, y*u +ight !i#h t* e;p*#e a 9ield
65
a# an ea#yEt*Eu#e bool, 3ut #t*re it internally !ithin an e99icient Bit'rray cla## Gdi#cu##ed in Chapter 6H) Pr*pertie# are #peci9ied 3y declaring the type and na+e *9 the Pr*perty, 9*ll*!ed 3y a 3racketed c*de 3l*ck that de9ine# a get c*de 3l*ck G9*r retrieving the valueH and a set c*de 3l*ck) ReadE*nly pr*pertie# de9ine *nly a get c*de 3l*ck Git i# legal, 3ut n*t *3vi*u#ly u#e9ul, t* create a !riteE*nly pr*perty 3y de9ining 4u#t #etH) The get c*de 3l*ck act# a# i9 it !ere a +eth*d de9ined a# taking n* argu+ent# and returning the type de9ined in the Pr*perty declarati*nQ the set c*de 3l*ck act# a# i9 it !ere a +eth*d returning v*id that take# an argu+ent na+ed value *9 the #peci9ied type) Here# an e;a+ple *9 a readE!rite pr*perty called !roperty,ame *9 type .y+ype) c a## GyC a## ; Gy'ype !y5nterna Reference3 //Begin property definition Gy'ype -ropertyCa!e; get ; // ogic return !y5nterna Reference3 < #et; // ogic !y5nterna Reference 9 *a ue3 < < //+nd of property definition < T* u#e a Pr*perty, y*u acce## the na+e *9 the pr*perty directly1 !yC a##5n#tance.Gy-roperty 9 #o!eNa ue3 //Ca Gy'ype t 9 !yC a##5n#tance.Gy-roperty3 //Ca # &#et& # &get&
The C# c*+piler in 9cat does create +eth*d# in *rder t* i+ple+ent pr*pertie# Gy*ull never need t* u#e the+, 3ut i9 y*ure intere#ted, the +eth*d# are called getA!roperty,ame( ) and setA!roperty,ame( )H) Thi# i# a the+e *9 C# EE direct language #upp*rt 9*r 9eature# that are i+ple+ented, n*t directly in Aicr*#*9t
66
Thinking in C
www.ThinkingIn.!et
-nter+ediate Language GAS-L P the I+achine c*deJ *9 the ) ET runti+eH, 3ut via c*de generati*n) Such I#yntactical #ugarJ c*uld 3e re+*ved 9r*+ the C# language !ith*ut actually changing the #et *9 pr*3le+# that can 3e #*lved 3y the languageQ they I4u#tJ +ake ta#k# ea#ier) *t every language i# de#igned !ith ea#eE*9Eu#e a# a +a4*r de#ign g*al and #*+e language de#igner# 9eel that #yntactic #ugar end# up c*n9u#ing pr*gra++er#) 5*r a +a4*r language intended t* 3e u#ed 3y the 3r*ade#t p*##i3le audience, C## language de#ign i# appr*priateQ i9 y*u !ant #*+ething 3*iled d*!n t* pure 9uncti*nality, there# talk *9 L-SP 3eing p*rted t* ) ET)
%nu#erations
=n enu+erati*n i# a #et *9 related value#1 UpE?*!n, *rthES*uthEEa#tE ,e#t, PennyE ickelE?i+eEMuarter, etc) =n enu+erati*n i# de9ined u#ing the enum key!*rd and a c*de 3l*ck in !hich the vari*u# value# are de9ined) Here# a #i+ple e;a+ple1 enu! OpOr:o.n; Op2 :o.n < Once de9ined, an enu+erati*n value can 3e u#ed 3y #peci9ying the enu+erati*n type, a d*t, and then the #peci9ic na+e de#ired1 OpOr:o.n coinH ip 9 OpOr:o.n.Op3 The na+e# !ithin an enu+erati*n are actually nu+eric value#) By de9ault, they are integer#, !h*#e value 3egin# at $) :*u can +*di9y 3*th the type *9 #t*rage u#ed 9*r the#e value# and the value# a##*ciated !ith a particular na+e) Here# an e;a+ple, !here a short i# u#ed t* h*ld di99erent c*in value#1 enu! Coin: #hort; -enny 9 "2 Cic%e < 9 P2 :i!e 9 "02 Quarter 9 2P
6#
Then, the na+e# can 3e ca#t t* their i+ple+enting value type1 #hort change 9 0#hort1 0Coin.-enny R Coin.Quarter13 Thi# !ill re#ult in the value *9 change 3eing 2.) -t i# al#* p*##i3le t* d* 3it!i#e *perati*n# *n enu+erati*n# +arked !ith the <:lags> attri3ute1 JH ag#K enu! H a*or; Nani a 9 "2 Choco ate 9 22 Stra.$erry 9 E2 Coffee 9 I< ...etc... H a*or cone-ref 9 H a*or.Nani a S H a*or.Coffee3 =lth*ugh 9*r 3it!i#e *perati*n#, it i# *9 c*ur#e nece##ary 9*r y*u t* de9ine the 9lag# !ith c*+pati3le value#)
'tructs
= struct G#h*rt 9*r I#tructureJH i# very #i+ilar t* a cla## in that it can c*ntain 9ield#, pr*pertie#, and +eth*d#) H*!ever, struct# are value type#, y*u cann*t inherit 9r*+ a struct *r have y*ur struct inherit 9r*+ any cla## e;cept ob)ect Galth*ugh a struct can i+ple+ent an inter9aceH, and struct# have li+ited c*n#truct*r and de#truct*r #e+antic#) Typically, struct# are u#ed t* aggregate a relatively #+all a+*unt *9 l*gically related 9ield#) 5*r in#tance, the 5ra+e!*rk S?N c*ntain# a !oint #tructure that ha# ? and @ pr*pertie#) Structure# are declared in the #a+e !ay a# cla##e#) Thi# e;a+ple #h*!# !hat +ight 3e the #tart *9 a struct 9*r i+aginary nu+3er#1 #truct 5!aginaryCu!$er; dou$ e rea 3 dou$ e Rea ; get ; return rea 3 < #et ; rea 9 *a ue3 < < dou$ e i3 dou$ e 5; get ; return i3 < #et ; i 9 *a ue3 < <
6&
Thinking in C
www.ThinkingIn.!et
<
3uilding a C# $rogra#
There are #everal *ther i##ue# y*u +u#t under#tand 3e9*re #eeing y*ur 9ir#t C# pr*gra+)
(a#e visi+ilit5
= pr*3le+ in any pr*gra++ing language i# the c*ntr*l *9 na+e#) -9 y*u u#e a na+e in *ne +*dule *9 the pr*gra+, and an*ther pr*gra++er u#e# the #a+e na+e in an*ther +*dule, h*! d* y*u di#tingui#h *ne na+e 9r*+ an*ther and prevent the t!* na+e# 9r*+ Icla#hingFJ -n C thi# i# a particular pr*3le+ 3ecau#e a pr*gra+ i# *9ten an un+anagea3le #ea *9 na+e#) C@@ cla##e# G*n !hich C# cla##e# are 3a#edH ne#t 9uncti*n# !ithin cla##e# #* they cann*t cla#h !ith 9uncti*n na+e# ne#ted !ithin *ther cla##e#) H*!ever, C@@ #till all*!ed gl*3al data and gl*3al 9uncti*n#, #* cla#hing !a# #till p*##i3le) T* #*lve thi# pr*3le+, C@@ intr*duced names"aces u#ing additi*nal key!*rd#) -n C#, the namespace key!*rd i# 9*ll*!ed 3y a c*de 3l*ck Gthat i#, a pair *9 curly 3racket# !ith #*+e a+*unt *9 c*de !ithin the+H) Unlike "ava, there i# n* relati*n#hip 3et!een the na+e#pace and cla## na+e# and direct*ry and 9ile #tructure) Organi7ati*nally, it *9ten +ake# #en#e t* gather all the 9ile# a##*ciated !ith a #ingle na+e#pace int* a #ingle direct*ry and t* have a *neEt*E*ne relati*n#hip 3et!een cla## na+e# and 9ile#, 3ut thi# i# #trictly a +atter *9 pre9erence) Thr*ugh*ut thi# 3**k, *ur e;a+ple c*de !ill *9ten c*+3ine +ultiple cla##e# in a #ingle c*+pilati*n unit Gthat i#, a #ingle 9ileH and !e !ill typically n*t u#e na+e#pace#, 3ut in pr*9e##i*nal devel*p+ent, y*u #h*uld av*id #uch #paceE#aving ch*ice#) a+e#pace# can, and #h*uld, 3e ne#ted) By c*nventi*n, the *uter+*#t na+e#pace i# the na+e *9 y*ur *rgani7ati*n, the ne;t the na+e *9 the pr*4ect *r #y#te+ a# a !h*le, and the inner+*#t the na+e *9 the #peci9ic gr*uping *9 intere#t) Here# an e;a+ple1 na!e#pace 'hin%ing5n; na!e#pace CSharp;
6'
na!e#pace ChapT; //c a## and other type dec aration# go here < < < Since na+e#pace# are pu3licly vie!a3le, they #h*uld #tart !ith a capital letter and then u#e Ica+el3ackJ capitali7ati*n G9*r in#tance, +hin(ingBnH) a+e#pace# are navigated u#ing d*t #ynta;1 +hin(ingBn6C#harp6Chap9 and +ay even 3e declared in thi# +anner1 na!e#pace 'hin%ing5n.CSharp.ChapE; L <
#(
Thinking in C
www.ThinkingIn.!et
A*#t *9 the ti+e y*ull 3e u#ing c*+p*nent# 9r*+ the ) ET 5ra+e!*rk S?N) >enerally, i9 *ne cla## in a na+e#pace i# u#e9ul, y*ull !ant t* u#e +*re than *ne cla## 9r*+ that na+e#pace) Thi# i# ea#ily acc*+pli#hed 3y the using key!*rd1 u#ing Sy#te!.Co ection#3
-t i# +*re c*++*n t* i+p*rt a c*llecti*n *9 cla##e# in thi# +anner than t* i+p*rt cla##e# individually)
#1
T* +ake a data +e+3er *r +eth*d static, y*u #i+ply place the key!*rd 3e9*re the de9initi*n) 5*r e;a+ple, the 9*ll*!ing pr*duce# a static data +e+3er and initiali7e# it1 c a## Static'e#t ; #tatic int i 9 EF3 < *! even i9 y*u +ake t!* #tatic+est *34ect#, there !ill #till 3e *nly *ne piece *9 #t*rage 9*r #tatic+est6i6 B*th *34ect# !ill #hare the #a+e i) C*n#ider1 Static'e#t #t" 9 ne. Static'e#t013 Static'e#t #t2 9 ne. Static'e#t013 =t thi# p*int, 3*th st76i and st86i have the #a+e value *9 &% #ince they re9er t* the #a+e piece *9 +e+*ry) There are t!* !ay# t* re9er t* a static varia3le) =# indicated a3*ve, y*u can na+e it via an *34ect, 3y #aying, 9*r e;a+ple, st86i) :*u can al#* re9er t* it directly thr*ugh it# cla## na+e, #*+ething y*u cann*t d* !ith a n*nE #tatic +e+3er) GThi# i# the pre9erred !ay t* re9er t* a static varia3le #ince it e+pha#i7e# that varia3le# static nature)H Static'e#t.iRR3 The CC *perat*r incre+ent# the varia3le) =t thi# p*int, 3*th st76i and st86i !ill have the value &() Si+ilar l*gic applie# t* #tatic +eth*d#) :*u can re9er t* a #tatic +eth*d either thr*ugh an *34ect a# y*u can !ith any +eth*d, *r !ith the #pecial additi*nal #ynta; Class,ame6.ethod( )) :*u de9ine a #tatic +eth*d in a #i+ilar !ay1 c a## StaticHun ; #tatic *oid 5ncr01 ; Static'e#t.iRR3 < < :*u can #ee that the #tatic:un +eth*d Bncr( ) incre+ent# the static data i) :*u can call Bncr( ) in the typical !ay, thr*ugh an *34ect1 StaticHun #f 9 ne. StaticHun013 #f.5ncr013
#)
Thinking in C
www.ThinkingIn.!et
Or, 3ecau#e Bncr( ) i# a #tatic +eth*d, y*u can call it directly thr*ugh it# cla##1 StaticHun.5ncr013 ,hile static, !hen applied t* a data +e+3er, de9initely change# the !ay the data i# created G*ne 9*r each cla## v#) the n*nE static *ne 9*r each *34ectH, !hen applied t* a +eth*d it# n*t #* dra+atic) =n i+p*rtant u#e *9 static 9*r +eth*d# i# t* all*! y*u t* call that +eth*d !ith*ut creating an *34ect) Thi# i# e##ential, a# !e !ill #ee, in de9ining the .ain( ) +eth*d that i# the entry p*int 9*r running an applicati*n) Like any +eth*d, a static +eth*d can create *r u#e na+ed *34ect# *9 it# type, #* a static +eth*d i# *9ten u#ed a# a I#hepherdJ 9*r a 9l*ck *9 in#tance# *9 it# *!n type)
#3
integrated help #y#te+) -9 y*u navigate t* mshelpD//.#6,&+:ramewor(#$E/cpref/html/frlrf#ystem6htm , y*ull #ee the c*ntent# *9 the #ystem na+e#pace) One *9 the+ i# the Console cla##) -9 y*u *pen thi# #u34ect and then click *n Console6.embers, y*ull #ee a li#t *9 pu3lic pr*pertie# and +eth*d#) -n the ca#e *9 the Console cla##, all *9 the+ are +arked !ith an ISJ indicating that they are #tatic) One *9 the #tatic +eth*d# *9 Console i# =riteLine( )) Since it# a #tatic +eth*d, y*u d*nt need t* create an *34ect t* u#e it) Thu#, i9 y*uve #peci9ied using #ystemF y*u can !rite Console6=riteLine(G#omethingG) !heneve y*u !ant t* print #*+ething t* the c*n#*le) =lternately, in an4 C# pr*gra+, y*u can #peci9y the $ull4 8uali$ied na+e #ystem6Console6=riteLine(G#omethingG) even i9 y*u have n*t !ritten using #ystem) Every pr*gra+ +u#t have !hat# called an entr4 "oint, a +eth*d !hich #tart# up thing#) -n C#, the entry p*int i# al!ay# a #tatic +eth*d called .ain( )) .ain( ) can 3e !ritten in #everal di99erent !ay#1 #tatic *oid Gain01; L < #tatic *oid Gain0#tringJK arg#1; L < #tatic int Gain01; L < #tatic int Gain0#tringJK arg#1; L < -9 y*u !i#h t* pa## in para+eter# 9r*+ the c*++andEline t* y*ur pr*gra+, y*u #h*uld u#e *ne *9 the 9*r+# that take an array *9 c*++andE line argu+ent#) args<4> !ill 3e the 9ir#t argu+ent a$ter the na+e *9 the e;ecuta3le) Traditi*nally, pr*gra+# return a $ i9 they ran #ucce##9ully and #*+e *ther integer a# an err*r c*de i9 they 9ailed) C## e;cepti*n# are in9initely #uperi*r 9*r c*++unicating #uch pr*3le+#, 3ut i9 y*u are !riting a pr*gra+ that y*u !i#h t* pr*gra+ !ith 3atch 9ile#, y*u +ay !i#h t* u#e a .ain( ) +eth*d that return# an integer) The line that print# the date illu#trate# the 3ehindEtheE#cene# c*+ple;ity *9 even a #i+ple *34ectE*riented call1 Con#o e.VriteLine0:ate'i!e.Co.13
#4
Thinking in C
www.ThinkingIn.!et
C*n#ider the argu+ent1 i9 y*u 3r*!#e the d*cu+entati*n t* the ?ateTi+e #tructure, y*ull di#c*ver that it ha# a #tatic pr*perty ,ow *9 type $ate+ime) =# thi# pr*perty i# read, the ) ET Runti+e read# the #y#te+ cl*ck, create# a ne! $ate+ime value t* #t*re the ti+e, and return# it) =# #**n a# that pr*perty get 9ini#he#, the $ate+ime #truct i# pa##ed t* the #tatic +eth*d =riteLine( ) *9 the Console cla##) -9 y*u u#e the help9ile t* g* t* that +eth*d# de9initi*n, y*ull #ee +any di99erent o-erloaded ver#i*n# *9 =riteLine( ), *ne !hich take# a bool, *ne !hich take# a char, etc) :*u !*nt 9ind *ne that take# a $ate+ime, th*ugh) Since there i# n* *verl*aded ver#i*n that take# the e;act type *9 the $ate+ime argu+ent, the runti+e l**k# 9*r ancestors *9 the argu+ent type) =ll struct# are de9ined a# de#cending 9r*+ type Halue+ype, !hich in turn de#cend# 9r*+ type ob)ect) There i# n*t a ver#i*n *9 =riteLine( ) that take# a Halue+ype 9*r an argu+ent, 3ut there is *ne that take# an ob)ect) -t i# thi# +eth*d that i# called, pa##ing in the $ate+ime #tructure) Back in the d*cu+entati*n 9*r =riteLine( ), it #ay# it call# the +o#tring( ) +eth*d *9 the ob)ect pa##ed in a# it# argu+ent) -9 y*u 3r*!#e t* 1b)ect6+o#tring( ), th*ugh, y*ull #ee that the de9ault repre#entati*n i# 4u#t the 9ully Duali9ied na+e *9 the *34ect) But !hen run, thi# pr*gra+ d*e#nt print *ut ISy#te+)?ateTi+e,J it print# *ut the ti+e value it#el9) Thi# i# 3ecau#e the i+ple+enter# *9 the $ate+ime cla## o-errode the de9ault i+ple+entati*n *9 +o#tring( ) and the call !ithin =riteLine( ) i# re#*lved "ol4mor"hicall4 3y the $ate+ime i+ple+entati*n, !hich return# a cultureE#peci9ic string repre#entati*n *9 it# value t* 3e printed t* the Console) -9 #*+e *9 that d*e#nt +ake #en#e, d*nt !*rry P al+*#t every a#pect *9 *34ectE*rientati*n i# at !*rk !ithin thi# #ee+ingly trivial e;a+ple)
#5
learning e;perience) Ci#ual Studi* ) ET intr*duce# additi*nal 9ile# t* #tructure and +anage pr*4ect#, 3ut the#e are n*t nece##ary 9*r the #+all #a+ple pr*gra+# u#ed in thi# 3**k) Ci#ual Studi* ) ET ha# #*+e great t**l# that ea#e certain ta#k#, like c*nnecting t* data3a#e# and devel*ping ,ind*!# 5*r+#, 3ut the#e t**l# #h*uld 3e u#ed t* relieve drudgery, n*t a# a #u3#titute 9*r kn*!ledge) = c*++andEline C# c*+piler i# included in Aicr*#*9t# ) ET 5ra+e!*rk S?N, !hich i# availa3le 9*r 9ree d*!nl*ad at +#dn)+icr*#*9t)c*+<d*!nl*ad#< = c*++andEline c*+piler i# al#* included !ithin Aicr*#*9t Ci#ual Studi* ) ET) The c*++andEline c*+piler i# csc6exe) Once y*uve in#talled the S?N, y*u #h*uld 3e a3le t* run csc 9r*+ a c*++andEline pr*+pt) -n additi*n t* the c*++andEline c*+piler, y*u #h*uld have a decent te;t edit*r) S*+e pe*ple #ee+ #ati#9ied !ith ,ind*!# *tepad, 3ut +*#t pr*gra++er# pre9er either the te;t edit*r !ithin Ci#ual Studi*) ET G4u#t u#e 5ile<OpenL and SaveL t* !*rk directly !ith te;t 9ile#H *r a thirdE party pr*gra++er# edit*r) =ll the c*de #a+ple# in thi# 3**k !ere !ritten !ith Ci#ual SlickEdit 9r*+ Aicr*Edge Gan*ther 9av*rite i# C*+puter S*luti*n -nc)# U/' #hare!are UltraEditH) Once the 5ra+e!*rk S?N i# in#talled, d*!nl*ad and unpack the #*urce c*de 9*r thi# 3**k Gy*u can 9ind it at !!!)Thinking-n)netH) Thi# !ill create a #u3direct*ry 9*r each chapter in the 3**k) A*ve t* the #u3direct*ry c49 and type1 c#c Ue o:ate.c# :*u #h*uld #ee a +e##age that #peci9ie# the ver#i*n# *9 the C# c*+piler and ) ET 5ra+e!*rk that are 3eing u#ed Gthe 3**k !a# 9ini#hed !ith C# C*+piler ver#i*n %)$$)6&.. and ) ET 5ra+e!*rk ver#i*n 0)$)/%$'H) There #h*uld 3e n* !arning# *r err*r#Q i9 there are, it# an indicati*n that #*+ething !ent !r*ng !ith the S?N in#tallati*n and y*u need t* inve#tigate th*#e pr*3le+#) On the *ther hand, i9 y*u 4u#t get y*ur c*++and pr*+pt 3ack, y*u can type1 Ue o:ate
#6
Thinking in C
www.ThinkingIn.!et
Thi# i# the pr*ce## y*u can u#e t* c*+pile and run each *9 the pr*gra+# in thi# 3**k) = #*urce 9ile, #*+eti+e# called a com"ilation unit, i# c*+piled 3y csc int* a ) ET assem2l4) By de9ault, the a##e+3ly i# given an e;ten#i*n *9 6exe and, i9 it ha# a .ain( ), the re#ulting a##e+3ly can 3e run 9r*+ the c*++andEline 4u#t a# any *ther pr*gra+)
7ine;tuning Co#$ilation
=n a##e+3ly +ay 3e generated 9r*+ +*re than *ne c*+pilati*n unit) Thi# i# d*ne 3y #i+ply putting the na+e# *9 the additi*nal c*+pilati*n unit# *n the c*++andEline Gcsc :irstClass6cs #econdClass6cs etc)H) :*u can +*di9y the na+e *9 the a##e+3ly !ith the /outD argu+ent) -9 +*re than *ne cla## ha# a .ain( ) de9ined, y*u can #peci9y !hich *ne i# intended t* 3e the entry p*int *9 the a##e+3ly !ith the /mainD argu+ent) *t every a##e+3ly need# t* 3e a #tandEal*ne e;ecuta3le) Such a##e+3lie# #h*uld 3e given the /targetDlibrary argu+ent and !ill 3e c*+piled int* an a##e+3ly !ith a 6$LL e;ten#i*n) By de9ault, a##e+3lie# Ikn*! *9J the #tandard li3rary re9erence mscorlib6dll, !hich c*ntain# the +a4*rity *9 the ) ET 5ra+e!*rk S?N cla##e#) -9 a pr*gra+ u#e# a cla## in a na+e#pace not !ithin the mscorlib6dll a##e+3ly, an a##e+3ly c*ntaining that cla## +u#t 3e either !ithin the current direct*ry, *r the /libD argu+ent #h*uld 3e u#ed t* p*int t* a direct*ry that h*ld# the appr*priate a##e+3ly)
##
Everything in thi# diagra+ e;cept the C*++*n Language Runti+e GCLRH i# #t*red *n the c*+puter in C*++*n -nter+ediate Language GC-L, #*+eti+e# re9erred t* a# Aicr*#*9t -nter+ediate Language, *r AS-L, *r #*+eti+e# 4u#t a# -LH, a very #i+ple I+achine c*deJ 9*r an a3#tract c*+puter) The C# c*+piler, like all ) ET language c*+piler#, tran#9*r+# hu+anE reada3le #*urce c*de int* C-L, n*t the actual *pc*de# *9 any particular CPU) =n a##e+3ly c*n#i#t# *9 C-L, +etadata de#cri3ing the a##e+3ly, and *pti*nal re#*urce#) ,ell di#cu## +etadata in detail in Chapter #re9# !hile re#*urce# !ill 3e di#cu##ed in Chapter 0/) The r*le *9 the C*++*n Language Runti+e can 3e 3*iled d*!n t* I+ediate 3et!een the !*rld *9 C-L and the !*rld *9 the actual plat9*r+)J Thi# reDuire# #everal c*+p*nent#1
?i99erent CPU# and language# have traditi*nally repre#ented #tring# in di99erent !ay# and nu+eric type# u#ing value# *9 di99erent 3itElength#) The
#&
Thinking in C
www.ThinkingIn.!et
value pr*p*#iti*n *9 ) ET i# I=ny language, *ne plat9*r+J Gin c*ntra#t !ith "ava# value pr*p*#iti*n *9 I=ny plat9*r+, *ne language)JH -n *rder t* a##ure that all language# can inter*perate #ea+le##ly ) ET pr*vide# a uni9*r+ de9initi*n *9 #everal 3a#ic type# in the C*++*n Type Sy#te+) Once I3el*!J thi# level, the hu+anEreada3le language in !hich a +*dule !a# *riginal !ritten i# irrelevant) Ta3le # #h*!# the tran#9*r+ati*n *9 a #i+ple +eth*d 9r*+ C# t* C-L t* Pentiu+ +achine c*de) c a## Si!p e; pu$ ic #tatic *oid Gain01; int #u! 9 03 for0int i 9 03 i W P3 iRR1; #u! R9 i3 < Sy#te!.Con#o e.VriteLine0#u!13 < < .!ethod pu$ ic hide$y#ig #tatic *oid !anaged ; .entrypoint // Code #iMe 2P 00x">1 .!ax#tac% 2 . oca # init 0intT2 NX02 intT2 NX"1 5LX0000: dc.iE.0 5LX000": #t oc.0 5LX0002: dc.iE.0 5LX000T: #t oc." 5LX000E: $r.# 5LX000e 5LX000?: d oc.0 5LX000F: d oc." 5LX000I: add 5LX000>: #t oc.0 5LX000a: d oc." 5LX000$: dc.iE." 5LX000c: add 5LX000d: #t oc." 5LX000e: d oc."
Gain01 ci
#'
5LX000f: dc.iE.P 5LX00"0: $ t.# 5LX000? 5LX00"2: d oc.0 5LX00"T: ca *oid J!#cor i$KSy#te!.Con#o e::VriteLine0intT21 5LX00"I: ret < // end of !ethod Si!p e::Gain Security re#tricti*n# are i+ple+ented at thi# level in *rder t* +ake it e;tre+ely di99icult t* 3ypa##) T* #ea+le##ly 3ypa## #ecurity !*uld reDuire replacing the CLR !ith a hacked CLR, n*t i+p*##i3le t* c*nceive, 3ut h*pe9ully 3ey*nd the range *9 #cript kiddie# and reDuiring an ad+ini#trati*nElevel c*+pr*+i#e 9r*+ !hich t* #tart) The #ecurity +*del *9 ) ET c*n#i#t# *9 check# that *ccur at 3*th the +*+ent the cla## i# l*aded int* +e+*ry and at the +*+ent that p*##i3lyEre#tricted *perati*n# are reDue#ted) =lth*ugh C-L i# n*t repre#entative *9 any real +achine c*de, it i# not interpreted) =9ter the C-L *9 a cla## i# l*aded int* +e+*ry, a "u#tE-nETi+e c*+piler G"-TH tran#9*r+# it 9r*+ C-L int* +achine language appr*priate t* the native CPU) One intere#ting 3ene9it *9 thi# i# that it# c*nceiva3le that di99erent "-T c*+piler# +ight 3ec*+e availa3le 9*r di99erent CPU# !ithin a general 9a+ily Gthu#, !e +ight eventually have an -taniu+ "-T, a Pentiu+ "-T, an =thl*n "-T, etc)H) The CLR c*ntain# a #u3#y#te+ re#p*n#i3le 9*r +e+*ry +anage+ent in#ide !hat i# called I+anaged c*de)J -n additi*n t* gar3age c*llecti*n Gthe pr*ce## *9 recycling +e+*ryH, the CLR +e+*ry +anager de9rag+ent# +e+*ry and decrea#e# the #pan *9 re9erence *9 inE+e+*ry re9erence# G3*th *9 !hich are 3ene9icial #ide e99ect# *9 the gar3age c*llecti*n architectureH) 5inally, all pr*gra+# reDuire #*+e 3a#ic e;ecuti*n #upp*rt at the level *9 thread #cheduling, c*de e;ecuti*n, and *ther #y#te+ #ervice#) Once again, at thi# l*! level, all *9 thi# #upp*rt can 3e #hared 3y any ) ET applicati*n, n* +atter !hat the *riginating pr*gra++ing language) The C*++*n Language Runti+e, the 3a#e 9ra+e!*rk cla##e# !ithin +#c*rli3)dll, and the C# language have all 3een #u3+itted t* Aicr*#*9t t* the Eur*pean C*+puter Aanu9acturer# =##*ciati*n GECA=H 9*r
&(
Thinking in C
www.ThinkingIn.!et
rati9icati*n a# #tandard#) The A*n* Pr*4ect G!!!)g*E+*n*)c*+H i# an e99*rt t* create an Open S*urce i+ple+entati*n *9 the#e #tandard# that include# Linu; #upp*rt)
4ocu#entation Co##ents
One *9 the th*ught9ul part# *9 the C# language i# that the de#igner# didnt c*n#ider !riting c*de t* 3e the *nly i+p*rtant activityRthey al#* th*ught a3*ut d*cu+enting it) P*##i3ly the 3igge#t pr*3le+ !ith d*cu+enting c*de ha# 3een +aintaining that d*cu+entati*n) -9 the d*cu+entati*n and
&1
the c*de are #eparate, it 3ec*+e# a ha##le t* change the d*cu+entati*n every ti+e y*u change the c*de) The #*luti*n #ee+# #i+ple1 link the c*de t* the d*cu+entati*n) The ea#ie#t !ay t* d* thi# i# t* put everything in the #a+e 9ile) T* c*+plete the picture, h*!ever, y*u need a #pecial c*++ent #ynta; t* +ark #pecial d*cu+entati*n, and a t**l t* e;tract th*#e c*++ent# and put the+ in a u#e9ul 9*r+) Thi# i# !hat C# ha# d*ne) C*++ent# that 3egin !ith <<< can 3e e;tracted 9r*+ #*urce 9ile# 3y running csc /docD1utput:ile6?.L) -n#ide the c*++ent# y*u can place any valid BAL tag# including #*+e tag# !ith prede9ined +eaning# di#cu##ed ne;t) The re#ulting BAL 9ile i# interpreted in certain !ay# in#ide *9 Ci#ual Studi* ) ET *r can 3e #tyled !ith BSLT t* pr*duce a ,e3 page *r printa3le d*cu+entati*n) -9 y*u d*nt under#tand BAL, d*nt !*rry a3*ut itQ y*ull 3ec*+e +uch +*re 9a+iliar !ith it in Chapter 0&K -9 y*u run c#c /doc:Ue o:ate.x! Ue o:ate.c#
The re#ulting BAL !ill 3e1 WYx! *er#ion9&".0&YZ WdocZ Wa##e!$ yZ Wna!eZUe o:ateW/na!eZ W/a##e!$ yZ W!e!$er#Z W/!e!$er#Z W/docZ The BAL c*n#i#t# *9 a Id*cJ ele+ent, !hich i# 9*r the a##e+3ly na+ed IHell*?ateJ and !hich d*e#nt have any d*cu+entati*n c*++ent#) Tag V#u++aryW V<#u++aryW Vre+ark#W V<re+ark#W Vpara+ Sugge#ted U#e = 3rie9 *vervie! *9 the c*de ele+ent Thi# i# u#ed 9*r a +*re c*+prehen#ive di#cu##i*n *9 the ele+ent# intended 3ehavi*r One *9 the#e tag# #h*uld 3e !ritten 9*r each argu+ent
&)
Thinking in C
www.ThinkingIn.!et
na+eXYna+eYW V<para+W
t* a +eth*dQ the value *9 the name attri3ute #peci9ie# !hich argu+ent) The de#cripti*n #h*uld include any prec*nditi*n# a##*ciated !ith the argu+ent) Prec*nditi*n# are !hat the +eth*d reDuire# *9 it# argu+ent# #* that the +eth*d can 9uncti*n c*rrectly) 5*r in#tance, a prec*nditi*n *9 a #Duare r**t 9uncti*n +ight 3e that the input integer 3e p*#itive) Aeth*d# that return anything *ther than v*id #h*uld have *ne *9 the#e tag#) The c*ntent# *9 the tag #h*uld de#cri3e !hat a3*ut the return value can 3e guaranteed) Can it 3e nullF ?*e# it al!ay# 9all !ithin a certain rangeF -# it al!ay# in a certain #tateF etc) Every e;cepti*n that i# e;plicitly rai#ed !ithin the +eth*d# 3*dy #h*uld 3e d*cu+ented in a tag #uch a# thi# Gthe type *9 the e;cepti*n #h*uld 3e the value *9 the cref attri3uteH) T* the e;tent p*##i3le, the circu+#tance# !hich give ri#e t* the e;cepti*n 3eing thr*!n #h*uld 3e detailed) Becau#e *9 C## e;cepti*n +*del Gdi#cu##ed in chapter #re9#H, #pecial attenti*n #h*uld 3e paid t* +aking #ure that the#e c*++ent# are c*n#i#tently and uni9*r+ly !ritten and +aintained) Thi# tag de#cri3e# the #ecurity per+i##i*n# that are reDuired 9*r the type) The cref attri3ute i# *pti*nal, 3ut i9 it e;i#t#, it #h*uld re9er t* a Per+i##i*nSet a##*ciated !ith the type) The Ve;a+pleW tag #h*uld c*ntain a de#cripti*n *9 a #a+ple u#e *9 the c*de ele+ent) The VcW tag i# intended t* #peci9y an inline c*de ele+ent !hile the Vc*deW tag i# intended 9*r +ultiline #nippet#)
Vreturn#W V<return#W
&3
V#ee cre9XY*therYW V<#eeW V#eeal#* cre9XY*therYW V<#eeal#*W VvalueW V<valueW Vpara+re9 na+eXYargY<W Vli#t typeX Z3ullet [ nu+3er [ ta3le\W Vli#theaderW Vter+WV<ter+W Vde#cripti*nW V<de#cripti*nW V<li#theaderW Vite+W Vter+WV<ter+W Vde#cripti*nW V<de#cripti*nW V<ite+W V<li#tW VparaWV<paraW
The#e tag# are intended 9*r cr*## re9erence# t* *ther c*de ele+ent# *r *ther d*cu+entati*n 9rag+ent#) The V#eeW tag i# intended 9*r inline cr*##Ere9erence#, !hile the V#eeal#*W tag i# intended t* 3e 3r*ken *ut int* a #eparate ISee =l#*J #ecti*n Every e;ternally vi#i3le pr*perty !ithin a cla## #h*uld 3e d*cu+ented !ith thi# tag Thi# e+pty tag i# u#ed !hen c*++enting a +eth*d t* indicate that the value *9 the name attri3ute i# actually the na+e *9 *ne *9 the +eth*d# argu+ent#) -ntended t* pr*vide a hint t* the BAL #tyler *n h*! t* generate d*cu+entati*n)
-ntended t* #peci9y #eparate paragraph# !ithin a de#cripti*n *r *ther lengthy te;t 3l*ck
4ocu#entation e&a#$le
Here# the Hell*?ate C# pr*gra+, thi# ti+e !ith d*cu+entati*n c*++ent# added1 // :c0T:Ue o:ate2.c# u#ing Sy#te!3
&4
Thinking in C
www.ThinkingIn.!et
na!e#pace 'hin%ing5n.CSharp.Chap0T; ///W#u!!aryZSho.# doc co!!ent#W/#u!!aryZ ///Wre!ar%#Z'he docu!entation co!!ent# .ithin C( ///are re!ar%a$ y u#efu 2 $oth .ithin the Ni#ua ///Studio en*iron!ent and a# the $a#i# for !ore ///#ignificant printed docu!entationW/re!ar%#Z pu$ ic c a## Ue o:ate2 ; ///W#u!!aryZ+ntry pointW/#u!!aryZ ///Wre!ar%#Z-rint# greeting to /// Wpara!ref na!e9&arg#J0K&/Z2 get# a /// W#ee cref9&Sy#te!.:ate'i!e&Z:ate'i!eW/#eeZ /// and #u$#e7uent y print# itW/re!ar%#Z ///Wpara! na!e9&arg#&ZCo!!and6 ine #hou d ha*e a ///#ing e na!e. ) other arg# .i $e ignored ///W/para!Z pu$ ic #tatic *oid Gain0#tringJK arg#1 ; Con#o e.VriteLine0&Ue o2 ;0< it'#: &2 arg#J0K13 Con#o e.VriteLine0:ate'i!e.Co.13 < < <//:8 ,hen csc e;tract# the data, it i# in thi# 9*r+1 WYx! *er#ion9&".0&YZ WdocZ Wa##e!$ yZ Wna!eZUe o:ateW/na!eZ W/a##e!$ yZ W!e!$er#Z W!e!$er na!e9&':'hin%ing5n.CSharp.Chap0T.Ue o:ate2&Z W#u!!aryZSho.# doc co!!ent#W/#u!!aryZ Wre!ar%#Z'he docu!entation co!!ent# .ithin C( are re!ar%a$ y u#efu 2 $oth .ithin the Ni#ua Studio en*iron!ent and a# the $a#i# for !ore #ignificant printed docu!entationW/re!ar%#Z W/!e!$erZ W!e!$er
&5
na!e9&G:'hin%ing5n.CSharp.Chap0T.Ue o:ate2.Gain0Sy#te !.StringJK1&Z W#u!!aryZ+ntry pointW/#u!!aryZ Wre!ar%#Z-rint# greeting to Wpara!ref na!e9&arg#J0K&/Z2 get# a W#ee cref9&':Sy#te!.:ate'i!e&Z:ate'i!eW/#eeZ and #u$#e7uent y print# itW/re!ar%#Z Wpara! na!e9&arg#&ZCo!!and6 ine #hou d ha*e a #ing e na!e. ) other arg# .i $e ignored W/para!Z W/!e!$erZ W/!e!$er#Z W/docZ The 9ir#t line *9 the Hell*?ate2)c# 9ile u#e# a c*nventi*n that !ill 3e u#ed thr*ugh*ut the 3**k) Every c*+pila3le #a+ple 3egin# !ith a c*++ent 9*ll*!ed 3y a T1 the chapter nu+3er, an*ther c*l*n, and the na+e *9 the 9ile that the e;a+ple #h*uld 3e #aved t*) The la#t line al#* 9ini#he# !ith a c*++ent, and thi# *ne indicate# the end *9 the #*urce c*de li#ting, !hich all*!# it t* 3e aut*+atically e;tracted 9r*+ the te;t *9 thi# 3**k and checked !ith a c*+piler) Thi# c*nventi*n #upp*rt# a t**l !hich can aut*+atically e;tract and c*+pile c*de directly 9r*+ the I#*urceJ ,*rd d*cu+ent)
Coding st5le
The un*99icial #tandard in C# i# t* capitali7e the 9ir#t letter *9 a cla## na+e) -9 the cla## na+e c*n#i#t# *9 #everal !*rd#, they are run t*gether Gthat i#, y*u d*nt u#e under#c*re# t* #eparate the na+e#H, and the 9ir#t letter *9 each e+3edded !*rd i# capitali7ed, #uch a#1 c a## ) 'heCo or#Of'heRain$o. ; // ...
Thi# #a+e #tyle i# al#* u#ed 9*r the part# *9 the cla## !hich are intended t* 3e re9ered t* 3y *ther# G+eth*d na+e# and pr*pertie#H) 5*r internal part# 9ield# G+e+3er varia3le#H and *34ect re9erence na+e#, the accepted #tyle i# 4u#t a# it i# 9*r cla##e# e%ce"t that the 9ir#t letter *9 the identi9ier i# l*!erca#e) 5*r e;a+ple1 c a## ) 'heCo or#Of'heRain$o. ; int an5ntegerRepre#entingCo or#3
&6
Thinking in C
www.ThinkingIn.!et
*oid Change'heUueOf'heCo or0int ne.Uue1 ; // ... < // ... < O9 c*ur#e, y*u #h*uld re+e+3er that the u#er +u#t al#* type all the#e l*ng na+e#, and #* 3e +erci9ul)
'u##ar5
-n thi# chapter y*u have #een en*ugh *9 C# pr*gra++ing t* under#tand h*! t* !rite a #i+ple pr*gra+, and y*u have g*tten an *vervie! *9 the language and #*+e *9 it# 3a#ic idea#) H*!ever, the e;a+ple# #* 9ar have all 3een *9 the 9*r+ Id* thi#, then d* that, then d* #*+ething el#e)J ,hat i9 y*u !ant the pr*gra+ t* +ake ch*ice#, #uch a# Ii9 the re#ult *9 d*ing thi# i# red, d* thatQ i9 n*t, then d* #*+ething el#eJF The #upp*rt in C# 9*r thi# 9unda+ental pr*gra++ing activity !ill 3e c*vered in the ne;t chapter)
%&ercises
1.
5*ll*!ing the "ello$ate6cs e;a+ple in thi# chapter, create a Ihell*, !*rldJ pr*gra+ that #i+ply print# *ut that #tate+ent) :*u need *nly a #ingle +eth*d in y*ur cla## Gthe IAainJ *ne that get# e;ecuted !hen the pr*gra+ #tart#H) Re+e+3er t* +ake it static) C*+pile the pr*gra+ !ith csc and run it 9r*+ the c*++andEline) 5ind the c*de 9rag+ent# inv*lving '+ype,ame and turn the+ int* a pr*gra+ that c*+pile# and run#) Turn the $ata1nly c*de 9rag+ent# int* a pr*gra+ that c*+pile# and run#) A*di9y E;erci#e / #* that the value# *9 the data in $ata1nly are a##igned t* and printed in .ain( )) ,rite a pr*gra+ that include# and call# the #torage( ) +eth*d de9ined a# a c*de 9rag+ent in thi# chapter)
2. 3. . !.
&#
". C.
Turn the #tatic:un c*de 9rag+ent# int* a !*rking pr*gra+) ,rite a pr*gra+ that print# three argu+ent# taken 9r*+ the c*++and line) T* d* thi#, y*ull need t* inde; int* the c*++andE line array *9 string#) Turn the 'll+heColors1f+he*ainbow e;a+ple int* a pr*gra+ that c*+pile# and run#) 5ind the c*de 9*r the #ec*nd ver#i*n *9 "ello$ate6cs, !hich i# the #i+ple c*++ent d*cu+entati*n e;a+ple) E;ecute csc /doc *n the 9ile and vie! the re#ult# !ith y*ur BALEa!are ,e3 3r*!#er) Turn $oc+est int* a 9ile that c*+pile# and then c*+pile it !ith csc /doc) Ceri9y the re#ulting d*cu+entati*n !ith y*ur ,e3 3r*!#er) =dd an HTAL li#t *9 ite+# t* the d*cu+entati*n in E;erci#e 0$) Take the pr*gra+ in E;erci#e 0 and add c*++ent d*cu+entati*n t* it) E;tract thi# c*++ent d*cu+entati*n and vie! it !ith y*ur ,e3 3r*!#er)
D. E.
1F.
11. 12.
&&
Thinking in C
www.ThinkingIn.!et
>sing C#o$erators
=n *perat*r take# *ne *r +*re argu+ent# and pr*duce# a ne! value) The argu+ent# are in a di99erent 9*r+ than *rdinary +eth*d call#, 3ut the e99ect i# the #a+e) :*u #h*uld 3e rea#*na3ly c*+9*rta3le !ith the general c*ncept *9 *perat*r# 9r*+ y*ur previ*u# pr*gra++ing e;perience) =dditi*n GCH, #u3tracti*n and unary +inu# G-H, +ultiplicati*n G;H, divi#i*n G/H, and a##ign+ent GIH all !*rk +uch the #a+e in any pr*gra++ing language) =ll *perat*r# pr*duce a value 9r*+ their *perand#) -n additi*n, an *perat*r can change the value *9 an *perand) Thi# i# called a side e$$ect) The +*#t c*++*n u#e 9*r *perat*r# that +*di9y their *perand# i# t* generate the #ide e99ect, 3ut y*u #h*uld keep in +ind that the value
&'
pr*duced i# availa3le 9*r y*ur u#e 4u#t a# in *perat*r# !ith*ut #ide e99ect#) Operat*r# !*rk !ith all pri+itive# and +any *34ect#) ,hen y*u pr*gra+ y*ur *!n *34ect#, y*u !ill 3e a3le t* e;tend the+ t* #upp*rt !hichever pri+itive# +ake #en#e Gy*ull 9ind y*ur#el9 creating T@ *perati*n# 9ar +*re *9ten than T< *perati*n#KH The *perat*r# 2I, TII and T!I, !*rk 9*r all *34ect# and are a p*int *9 c*n9u#i*n 9*r *34ect# that !ell deal !ith in #re9erence#)
Precedence
Operat*r precedence de9ine# h*! an e;pre##i*n evaluate# !hen #everal *perat*r# are pre#ent) C# ha# #peci9ic rule# that deter+ine the *rder *9 evaluati*n) The ea#ie#t *ne t* re+e+3er i# that +ultiplicati*n and divi#i*n happen 3e9*re additi*n and #u3tracti*n) Pr*gra++er# *9ten 9*rget the *ther precedence rule#, #* y*u #h*uld u#e parenthe#e# t* +ake the *rder *9 evaluati*n e;plicit) 5*r e;a+ple1 a 9 x R y 6 2/2 R M3 ha# a very di99erent +eaning 9r*+ the #a+e #tate+ent !ith a particular gr*uping *9 parenthe#e#1 a 9 x R 0y 6 21/02 R M13
)ssign#ent
=##ign+ent i# per9*r+ed !ith the *perat*r X) -t +ean# Itake the value *9 the rightEhand #ide G*9ten called the r-alueH and c*py it int* the le9tEhand #ide G*9ten called the l-alueH) =n rvalue i# any c*n#tant, varia3le *r e;pre##i*n that can pr*duce a value, 3ut an lvalue +u#t 3e a di#tinct, na+ed varia3le) GThat i#, there +u#t 3e a phy#ical #pace t* #t*re a value)H 5*r in#tance, y*u can a##ign a c*n#tant value t* a varia3le G ' I JFH, 3ut y*u cann*t a##ign anything t* c*n#tant valueRit cann*t 3e an lvalue) G:*u cant #ay J I 'F)H =##ign+ent *9 pri+itive# i# Duite #traight9*r!ard) Since the pri+itive h*ld# the actual value and n*t a re9erence t* an *34ect, !hen y*u a##ign pri+itive# y*u c*py the c*ntent# 9r*+ *ne place t* an*ther) 5*r e;a+ple, i9 y*u #ay ' I B 9*r pri+itive#, then the c*ntent# *9 B are c*pied int* ') -9
'(
y*u then g* *n t* +*di9y ', B i# naturally una99ected 3y thi# +*di9icati*n) =# a pr*gra++er, thi# i# !hat y*uve c*+e t* e;pect 9*r +*#t #ituati*n#) ,hen y*u a##ign *34ect#, h*!ever, thing# change) ,henever y*u +anipulate an *34ect, !hat y*ure +anipulating i# the re9erence, #* !hen y*u a##ign I9r*+ *ne *34ect t* an*therJ y*ure actually c*pying a re9erence 9r*+ *ne place t* an*ther) Thi# +ean# that i9 y*u #ay C I $ 9*r *34ect#, y*u end up !ith 3*th C and $ p*inting t* the *34ect that, *riginally, *nly $ p*inted t*) The 9*ll*!ing e;a+ple !ill de+*n#trate thi#) Here# the e;a+ple1 //: c0T: )##ign!ent.c# c a## Cu!$er; pu$ ic int i3 < pu$ ic c a## )##ign!ent; pu$ ic #tatic *oid Gain01; Cu!$er n" 9 ne. Cu!$er013 Cu!$er n2 9 ne. Cu!$er013 n".i 9 >3 n2.i 9 EF3 Sy#te!.Con#o e.VriteLine0 &": n".i: & R n".i R &2 n2.i: & R n2.i13 n".i 9 n2.i3 Sy#te!.Con#o e.VriteLine0 &2: n".i: & R n".i R &2 n2.i: & R n2.i13 n".i 9 2F3 Sy#te!.Con#o e.VriteLine0 &T: n".i: & R n".i R &2 n2.i: & R n2.i13 < < ///:8
]
The ,umber cla## i# #i+ple, and t!* in#tance# *9 it Gn7 and n8H are created !ithin Aain( )) The i value !ithin each ,umber i# given a di99erent value, and then n8 i# a##igned t* n7, and n7 i# changed) -n +any pr*gra++ing language# y*u !*uld e;pect n7 and n8 t* 3e independent
'1
at all ti+e#, 3ut 3ecau#e y*uve a##igned a re9erence here# the *utput y*ull #ee1 ": n".i: >2 n2.i: EF 2: n".i: EF2 n2.i: EF T: n".i: 2F2 n2.i: 2F Changing the n7 *34ect appear# t* change the n8 *34ect a# !ellK Thi# i# 3ecau#e 3*th n7 and n8 c*ntain the #a+e re9erence, !hich i# p*inting t* the #a+e *34ect) GThe *riginal re9erence that !a# in n7 that p*inted t* the *34ect h*lding a value *9 6 !a# *ver!ritten during the a##ign+ent and e99ectively l*#tQ it# *34ect !ill 3e cleaned up 3y the gar3age c*llect*r)H Thi# phen*+en*n i# called aliasing and it# a 9unda+ental !ay that C# !*rk# !ith *34ect#) But !hat i9 y*u d*nt !ant alia#ing t* *ccur in thi# ca#eF :*u c*uld 9*reg* the a##ign+ent and #ay1 n".i 9 n2.i3 Thi# retain# the t!* #eparate *34ect# in#tead *9 t*##ing *ne and tying n7 and n8 t* the #a+e *34ect, 3ut y*ull #**n reali7e that +anipulating the 9ield# !ithin *34ect# i# +e##y and g*e# again#t g**d *34ectE*riented de#ign principle#)
')
Thinking in C
www.ThinkingIn.!et
Sy#te!.Con#o e.VriteLine0&": x.c: & R x.c13 f0x13 Sy#te!.Con#o e.VriteLine0&2: x.c: & R x.c13 < < <///:8 -n +any pr*gra++ing language#, the +eth*d :( ) !*uld appear t* 3e +aking a c*py *9 it# argu+ent Letter y in#ide the #c*pe *9 the +eth*d) But *nce again a re9erence i# 3eing pa##ed #* the line y.c 9 'M'3 i# actually changing the *34ect *ut#ide *9 :( )) The *utput #h*!# thi#1 ": x.c: a 2: x.c: M
@athe#atical o$erators
The 3a#ic +athe+atical *perat*r# are the #a+e a# the *ne# availa3le in +*#t pr*gra++ing language#1 additi*n GCH, #u3tracti*n G-H, divi#i*n G/H, +ultiplicati*n G;H and +*dulu# GK, !hich pr*duce# the re+ainder 9r*+ integer divi#i*nH) -nteger divi#i*n truncate#, rather than r*und#, the re#ult) "ava al#* u#e# a #h*rthand n*tati*n t* per9*r+ an *perati*n and an a##ign+ent at the #a+e ti+e) Thi# i# den*ted 3y an *perat*r 9*ll*!ed 3y an eDual #ign, and i# c*n#i#tent !ith all the *perat*r# in the language G!henever it +ake# #en#eH) 5*r e;a+ple, t* add & t* the varia3le x and a##ign the re#ult t* x, u#e1 x CI J) Thi# e;a+ple #h*!# the u#e *9 the +athe+atical *perat*r#1 //: c0T:GathOp#.c# na!e#pace c0T; u#ing Sy#te!3 pu$ ic c a## GathOp#;
'3
///Create a #horthand function to #a*e typing #tatic *oid -rt0String #1; Sy#te!.Con#o e.VriteLine0#13 < ///-rint# a #tring and an int: #tatic *oid -5nt0String #2 int i1; -rt0# R & 9 & R i13 < //Shorthand to print a #tring and a f oat #tatic *oid -:ou$ e0String #2 dou$ e f1; -rt0# R & 9 & R f13 < pu$ ic #tatic *oid Gain01; //Create a rando! nu!$er generator2 //#eed# .ith current ti!e $y defau t Rando! rand 9 ne. Rando!013 int i2 D2 %3 //get a po#iti*e rando! nu!$er e## than the #pecified !axi!u! D 9 rand.Cext0"0013 % 9 rand.Cext0"0013 -5nt0&D&2D13 -5nt0&%&2%13 i 9 D R %3 -5nt0&D R %&2 i13 i 9 D 6 %3 -5nt0&D 6 %&2 i13 i 9 % / D3 -5nt0&% / D&2 i13 i 9 % = D3 -5nt0&% = D&2 i13 //Li!it# i to a po#iti*e nu!$er e## than D i 9 % [ D3 -5nt0&% [ D&2 i13 D [9 %3 -5nt0&D [9 %&2 D13 //H oating6point nu!$er te#t#: dou$ e u2 *2 .3 * 9 rand.Cext:ou$ e013 .9 rand.Cext:ou$ e013 -:ou$ e0&*&2 *13 -:ou$ e0&.&2.13 u 9 * R .3 -:ou$ e0&* R .&2 u13 u 9 * 6 .3 -:ou$ e0&* 6 .&2 u13 u 9 * = .3 -:ou$ e0&* = .&2 u13
'4
Thinking in C
www.ThinkingIn.!et
u 9 * / .3 -:ou$ e0&* / .&2 u13 //the fo o.ing a #o .or%# for //char2 $yte2 #hort2 int2 ong2 //and f oat \todo chec% u R9 *3 -:ou$ e0&u R9 *&2 u13 u 69 *3 -:ou$ e0&u 69 *&2 u13 u =9 *3 -:ou$ e0&u =9 *&2 u13 u /9 *3 -:ou$ e0&u /9 *&2 u13 < < <///:8 The 9ir#t thing y*u !ill #ee are #*+e #h*rthand +eth*d# 9*r printing1 the !rt( ) +eth*d print# a #tring, the !Bnt( ) print# a #tring 9*ll*!ed 3y an int and the !$ouble( ) print# a #tring 9*ll*!ed 3y a double) O9 c*ur#e, they all ulti+ately end up u#ing #ystem6Console6=riteLine( )) T* generate nu+3er#, the pr*gra+ 9ir#t create# a *andom *34ect) Becau#e n* argu+ent# are pa##ed during creati*n, C# u#e# the current ti+e a# a #eed 9*r the rand*+ nu+3er generat*r) The pr*gra+ generate# a nu+3er *9 di99erent type# *9 rand*+ nu+3er# !ith the *andom *34ect #i+ply 3y calling the +eth*d#1 ,ext ( ) and ,ext$ouble( ) Gy*u can al#* call extLong( ) *r ,ext(int)H)
'5
x 9 a = 06$13 The unary +inu# pr*duce# the negative *9 the value) Unary plu# pr*vide# #y++etry !ith unary +inu#, alth*ugh it d*e#nt have any e99ect)
'6
Thinking in C
www.ThinkingIn.!et
prt0&i66: & R i6613 //-o#t6incre!ent prt0&i: & R i13 < #tatic *oid prt0String #1; Sy#te!.Con#o e.VriteLine0#13 < < <///:8
]
The *utput 9*r thi# pr*gra+ i#1 i : RRi iRR i : 66i i66 i : " : : T : : " 2 2 2 2
:*u can #ee that 9*r the pre9i; 9*r+ y*u get the value a9ter the *perati*n ha# 3een per9*r+ed, 3ut !ith the p*#t9i; 9*r+ y*u get the value 3e9*re the *perati*n i# per9*r+ed) The#e are the *nly *perat*r# G*ther than th*#e inv*lving a##ign+entH that have #ide e99ect#) GThat i#, they change the *perand rather than u#ing 4u#t it# value)H The incre+ent *perat*r i# *ne e;planati*n 9*r the na+e C@@, i+plying I*ne #tep 3ey*nd C)J =# 9*r C#, the e;planati*n #ee+# t* 3e in +u#ic, !here the # #y+3*li7e# I#harpJ P a hal9E#tep Iup)J
6elational o$erators
Relati*nal *perat*r# generate a 3**lean re#ult) They evaluate the relati*n#hip 3et!een the value# *9 the *perand#) = relati*nal e;pre##i*n pr*duce# true i9 the relati*n#hip i# true, and false i9 the relati*n#hip i# untrue) The relati*nal *perat*r# are le## than GVH, greater than GWH, le## than *r eDual t* GVXH, greater than *r eDual t* GWXH, eDuivalent GXXH and n*t eDuivalent GKXH) EDuivalence and n*neDuivalence !*rk !ith all 3uiltE in data type#, 3ut the *ther c*+pari#*n# !*nt !*rk !ith type bool)
'#
'&
Thinking in C
www.ThinkingIn.!et
Logical o$erators
Each *9 the l*gical *perat*r# = ? G88H, OR G[[H and OT GKH pr*duce# a bool value *9 true *r false 3a#ed *n the l*gical relati*n#hip *9 it# argu+ent#) Thi# e;a+ple u#e# the relati*nal and l*gical *perat*r#1 //: c0T:Boo .c# na!e#pace c0T; u#ing Sy#te!3 // Re ationa and ogica operator#. pu$ ic c a## Boo ; pu$ ic #tatic *oid Gain01 ; Rando! rand 9 ne. Rando!013 int i 9 rand.Cext0"0013 int D 9 rand.Cext0"0013 prt0&i 9 & R i13 prt0&D 9 & R D13 prt0&i Z D i# & R 0i Z D113 prt0&i W D i# & R 0i W D113 prt0&i Z9 D i# & R 0i Z9 D113 prt0&i W9 D i# & R 0i W9 D113 prt0&i 99 D i# & R 0i 99 D113 prt0&i !9 D i# & R 0i !9 D113 // 'reating an int a# a $oo ean i# // not ega C( //! prt0&i @@ D i# & R 0i @@ D113 //! prt0&i SS D i# & R 0i SS D113 //! prt0&!i i# & R !i13 prt0&0i W "01 @@ 0D W "01 i# & R 00i W "01 @@ 0D W "011 13 prt0&0i W "01 SS 0D W "01 i# & R 00i W "01 SS 0D W "011 13 < #tatic *oid prt0String #1 ; Sy#te!.Con#o e.VriteLine0#13 < < <///:8
''
:*u can apply = ?, OR, *r OT t* bool value# *nly) :*u cant u#e a n*nE bool a# i9 it !ere a bool in a l*gical e;pre##i*n a# y*u can in #*+e *ther language#) :*u can #ee the 9ailed atte+pt# at d*ing thi# c*++ented *ut !ith a //! c*++ent +arker) The #u3#eDuent e;pre##i*n#, h*!ever, pr*duce bool value# u#ing relati*nal c*+pari#*n#, then u#e l*gical *perati*n# *n the re#ult#) One *utput li#ting l**ked like thi#1 i 9 IP D 9 E i Z D i# true i W D i# fa #e i Z9 D i# true i W9 D i# fa #e i 99 D i# fa #e i !9 D i# true 0i W "01 @@ 0D W "01 i# fa #e 0i W "01 SS 0D W "01 i# true *te that a bool value i# aut*+atically c*nverted t* an appr*priate te;t 9*r+ i9 it# u#ed !here a string i# e;pected) :*u can replace the de9initi*n 9*r int in the a3*ve pr*gra+ !ith any *ther pri+itive data type e;cept bool) Be a!are, h*!ever, that the c*+pari#*n *9 9l*atingEp*int nu+3er# i# very #trict) = nu+3er that i# the tinie#t 9racti*n di99erent 9r*+ an*ther nu+3er i# #till In*t eDual)J = nu+3er that i# the tinie#t 3it a3*ve 7er* i# #till n*n7er*)
'hort;circuiting
,hen dealing !ith l*gical *perat*r# y*u run int* a phen*+en*n called I#h*rt circuiting)J Thi# +ean# that the e;pre##i*n !ill 3e evaluated *nly until the truth *r 9al#eh**d *9 the entire e;pre##i*n can 3e una+3igu*u#ly deter+ined) =# a re#ult, all the part# *9 a l*gical e;pre##i*n +ight n*t 3e evaluated) Here# an e;a+ple that de+*n#trate# #h*rtEcircuiting1 //: c0T:ShortCircuit.c# na!e#pace c0T; u#ing Sy#te!3 // :e!on#trate# #hort6circuiting $eha*ior.
1((
Thinking in C
www.ThinkingIn.!et
// .ith ogica operator#. pu$ ic c a## ShortCircuit ; #tatic $oo 'e#t"0int *a 1 ; Sy#te!.Con#o e.VriteLine0&'e#t"0& R *a R &1&13 Sy#te!.Con#o e.VriteLine0&re#u t: & R 0*a W "113 return *a W "3 < #tatic $oo 'e#t20int *a 1 ; Sy#te!.Con#o e.VriteLine0&'e#t20& R *a R &1&13 Sy#te!.Con#o e.VriteLine0&re#u t: & R 0*a W 2113 return *a W 23 < #tatic $oo 'e#tT0int *a 1 ; Sy#te!.Con#o e.VriteLine0&'e#tT0& R *a R &1&13 Sy#te!.Con#o e.VriteLine0&re#u t: & R 0*a W T113 return *a W T3 < pu$ ic #tatic *oid Gain01 ; if 0'e#t"001 @@ 'e#t2021 @@ 'e#tT0211 Sy#te!.Con#o e.VriteLine0&expre##ion i# true&13 e #e Sy#te!.Con#o e.VriteLine0&expre##ion i# fa #e&13 < < < ///:8 Each te#t per9*r+# a c*+pari#*n again#t the argu+ent and return# true *r 9al#e) -t al#* print# in9*r+ati*n t* #h*! y*u that it# 3eing called) The te#t# are u#ed in the e;pre##i*n1 if0te#t"001 @@ te#t2021 @@ te#tT0211
1(1
:*u +ight naturally think that all three te#t# !*uld 3e e;ecuted, 3ut the *utput #h*!# *ther!i#e1 te#t"001 re#u t: true te#t2021 re#u t: fa #e expre##ion i# fa #e The 9ir#t te#t pr*duced a true re#ult, #* the e;pre##i*n evaluati*n c*ntinue#) H*!ever, the #ec*nd te#t pr*duced a false re#ult) Since thi# +ean# that the !h*le e;pre##i*n +u#t 3e false, !hy c*ntinue evaluating the re#t *9 the e;pre##i*nF -t c*uld 3e e;pen#ive) The rea#*n 9*r #h*rtE circuiting, in 9act, i# preci#ely thatQ y*u can get a p*tential per9*r+ance increa#e i9 all the part# *9 a l*gical e;pre##i*n d* n*t need t* 3e evaluated)
3itwise o$erators
The 3it!i#e *perat*r# all*! y*u t* +anipulate individual 3it# in an integral pri+itive data type) Bit!i#e *perat*r# per9*r+ 3**lean alge3ra *n the c*rre#p*nding 3it# in the t!* argu+ent# t* pr*duce the re#ult) The 3it!i#e *perat*r# c*+e 9r*+ C# l*!Elevel *rientati*nQ y*u !ere *9ten +anipulating hard!are directly and had t* #et the 3it# in hard!are regi#ter#) =lth*ugh +*#t applicati*n and ,e3 Service devel*per# !ill n*t 3e u#ing the 3it!i#e *perat*r# +uch, devel*per# 9*r Handheld PC#, #etE t*p 3*;e#, and the B B*; *9ten need every 3itEt!iddling advantage they can get) The 3it!i#e = ? *perat*r GLH pr*duce# a *ne in the *utput 3it i9 3*th input 3it# are *neQ *ther!i#e it pr*duce# a 7er*) The 3it!i#e OR *perat*r GMH pr*duce# a *ne in the *utput 3it i9 either input 3it i# a *ne and pr*duce# a 7er* *nly i9 3*th input 3it# are 7er*) The 3it!i#e EBCLUS-CE OR, *r BOR GNH, pr*duce# a *ne in the *utput 3it i9 *ne *r the *ther input 3it i# a *ne, 3ut n*t 3*th) The 3it!i#e OT GO, al#* called the ones com"lement *perat*rH i# a unary *perat*rQ it take# *nly *ne argu+ent) G=ll *ther 3it!i#e *perat*r# are 3inary *perat*r#)H Bit!i#e OT pr*duce#
1()
Thinking in C
www.ThinkingIn.!et
the *pp*#ite *9 the input 3itRa *ne i9 the input 3it i# 7er*, a 7er* i9 the input 3it i# *ne) The 3it!i#e *perat*r# and l*gical *perat*r# u#e the #a+e character#, #* it i# help9ul t* have a +ne+*nic device t* help y*u re+e+3er the +eaning#1 #ince 3it# are I#+all,J there i# *nly *ne character in the 3it!i#e *perat*r#) Bit!i#e *perat*r# can 3e c*+3ined !ith the I #ign t* unite the *perati*n and a##ign+ent1 LI, MI and NI are all legiti+ate) GSince O i# a unary *perat*r it cann*t 3e c*+3ined !ith the I #ign)H The bool type i# treated a# a *neE3it value #* it i# #*+e!hat di99erent) :*u can per9*r+ a 3it!i#e = ?, OR and BOR, 3ut y*u cant per9*r+ a 3it!i#e OT Gpre#u+a3ly t* prevent c*n9u#i*n !ith the l*gical OTH) 5*r bool# the 3it!i#e *perat*r# have the #a+e e99ect a# the l*gical *perat*r# e;cept that they d* n*t #h*rt circuit) =l#*, 3it!i#e *perati*n# *n bool# include an BOR l*gical *perat*r that i# n*t included under the li#t *9 Il*gicalJ *perat*r#) :*ure prevented 9r*+ u#ing bool# in #hi9t e;pre##i*n#, !hich i# de#cri3ed ne;t)
'hi0t o$erators
The #hi9t *perat*r# al#* +anipulate 3it#) They can 3e u#ed #*lely !ith pri+itive, integral type#) The le9tE#hi9t *perat*r GPPH pr*duce# the *perand t* the le9t *9 the *perat*r #hi9ted t* the le9t 3y the nu+3er *9 3it# #peci9ied a9ter the *perat*r Gin#erting 7er*e# at the l*!erE*rder 3it#H) The #igned rightE#hi9t *perat*r GQQH pr*duce# the *perand t* the le9t *9 the *perat*r #hi9ted t* the right 3y the nu+3er *9 3it# #peci9ied a9ter the *perat*r) The #igned right #hi9t QQ u#e# sign e%tension1 i9 the value i# p*#itive, 7er*e# are in#erted at the higherE*rder 3it#Q i9 the value i# negative, *ne# are in#erted at the higherE*rder 3it#) GC# d*e# n*t have an un#igned right #hi9t QQQ)H -9 y*u #hi9t a char, byte, *r short, it !ill 3e pr*+*ted t* int 3e9*re the #hi9t take# place, and the re#ult !ill 3e an int) Only the 9ive l*!E*rder 3it# *9 the rightEhand #ide !ill 3e u#ed) Thi# prevent# y*u 9r*+ #hi9ting +*re than the nu+3er *9 3it# in an int) -9 y*ure *perating *n a long, y*ull get a long re#ult) Only the #i; l*!E*rder 3it# *9 the rightEhand #ide !ill 3e u#ed #* y*u cant #hi9t +*re than the nu+3er *9 3it# in a long)
1(3
Shi9t# can 3e c*+3ined !ith the eDual #ign GPPI *r QQIH) The lvalue i# replaced 3y the lvalue #hi9ted 3y the rvalue) Here# an e;a+ple that de+*n#trate# the u#e *9 all the *perat*r# inv*lving 3it#1 //: c0T:BitGanipu ation.c# na!e#pace c0T; u#ing Sy#te!3 pu$ ic c a## BitGanipu ation ; pu$ ic #tatic *oid Gain01 ; Rando! rand 9 ne. Rando!013 int i 9 rand.Cext013 int D 9 rand.Cext013 -Bin5nt0&6"&2 6"13 -Bin5nt0&R"&2 R"13 int !axpo# 9 5ntT2.GaxNa ue3 -Bin5nt0&!axpo#&2 !axpo#13 int !axneg 9 5ntT2.GinNa ue3 -Bin5nt0&!axneg&2 !axneg13 -Bin5nt0&i&2 i13 -Bin5nt0&8i&2 8i13 -Bin5nt0&6i&2 6i13 -Bin5nt0&D&2 D13 -Bin5nt0&i @ D&2 i @ D13 -Bin5nt0&i S D&2 i S D13 -Bin5nt0&i ] D&2 i ] D13 -Bin5nt0&i WW P&2 i WW P13 -Bin5nt0&i ZZ P&2 i ZZ P13 -Bin5nt0&08i1 ZZ P&2 08i1 ZZ P13 ///\todo On#igned #hift# don't .or%! /= -Bin5nt0&i ZZZ P&2 i ZZZ P13 -Bn5nt0&08i1 ZZZ P&2 08i1 ZZZ P13 =/ ong XhighX$it# 9 rand.Cext013 XhighX$it# WW9 T23 ong 9 XhighX$it# R rand.Cext013 ong !XhighX$it# 9 rand.Cext013 !XhighX$it# WW9T23
1(4
Thinking in C
www.ThinkingIn.!et
ong ! 9 !XhighX$it# R rand.Cext013 -BinLong0&6"L&2 6"L13 -BinLong0&R"L&2 R"L13 ong 9 5nt?E.GaxNa ue3 -BinLong0&!axpo#&2 13 ong n 9 5nt?E.GinNa ue3 -BinLong0&!axneg&2 n13 -BinLong0& XhighX$it#&2 XhighX$it#13 -BinLong0& &2 13 -BinLong0&8 &2 8 13 -BinLong0&6 &2 6 13 -BinLong0&!XhighX$it#&2 !XhighX$it#13 -BinLong0&!&2 !13 -BinLong0& @ !&2 @ !13 -BinLong0& S !&2 S !13 -BinLong0& ] !&2 ] !13 -BinLong0& WW P&2 WW P13 -BinLong0& ZZ P&2 ZZ P13 -BinLong0&08 1 ZZ P&2 08 1 ZZ P13 /= \todo -BinLong0& ZZZ P&2 ZZZ P13 -BinLong0&08 1 ZZZ P&2 08 1 ZZZ P13 =/ < #tatic *oid -Bin5nt0String #2 int i1 ; Sy#te!.Con#o e.VriteLine0 # R &2 int: & R i R &2 $inary: &13 Sy#te!.Con#o e.Vrite0& &13 for0int D 9 T"3 D Z903 D661 if000" WW D1 @ i1 !9 01 Sy#te!.Con#o e.Vrite0&"&13 e #e Sy#te!.Con#o e.Vrite0&0&13 Sy#te!.Con#o e.VriteLine013 < #tatic *oid -BinLong0String #2 ong 1 ; Sy#te!.Con#o e.VriteLine0 # R &2 ong: & R R &2 $inary: &13 Sy#te!.Con#o e.Vrite0& &13 for0int i 9 ?T3 i Z903 i661
1(5
if000"L WW i1 @ 1 !9 01 Sy#te!.Con#o e.Vrite0&"&13 e #e Sy#te!.Con#o e.Vrite0&0&13 Sy#te!.Con#o e.VriteLine013 < < < //:8 The t!* +eth*d# at the end, PBinBnt( ) and !BinLong( ) take an int *r a long, re#pectively, and print it *ut in 3inary 9*r+at al*ng !ith a de#criptive #tring) :*u can ign*re the i+ple+entati*n *9 the#e 9*r n*!) :*ull n*te the u#e *9 #ystem6Console6=rite( ) in#tead *9 #ystem6Console6=riteLine( )) The =rite( ) +eth*d d*e# n*t e+it a ne! line, #* it all*!# y*u t* *utput a line in piece#) =# !ell a# de+*n#trating the e99ect *9 all the 3it!i#e *perat*r# 9*r int and long, thi# e;a+ple al#* #h*!# the +ini+u+, +a;i+u+, @0 and E0 value# 9*r int and long #* y*u can #ee !hat they l**k like) *te that the high 3it repre#ent# the #ign1 $ +ean# p*#itive and 0 +ean# negative) The *utput l**k# like thi#1 6"2 int: 6"2 $inary: """""""""""""""""""""""""""""""" R"2 int: "2 $inary: 0000000000000000000000000000000" !axpo#2 int: 2"EFEIT?EF2 $inary: 0""""""""""""""""""""""""""""""" !axneg2 int: 62"EFEIT?EI2 $inary: "0000000000000000000000000000000 i2 int: ""FFE">TT02 $inary: 0"000""000"0""0""""""""00"0000"0 8i2 int: 6""FFE">TT"2 $inary: "0"""00"""0"00"00000000""0""""0" 6i2 int: 6""FFE">TT02 $inary: "0"""00"""0"00"00000000""0"""""0 D2 int: II??>T>T22 $inary: 00""0"00""0""00""""0000000"0""00 i @ D2 int: ?FFP?0T22 $inary:
1(6
Thinking in C
www.ThinkingIn.!et
00000"000000"00""""0000000000000 i S D2 int: ">>?TPF2T02 $inary: 0"""0""0""""""0""""""""00""0"""0 i ] D2 int: ">2I?0"">I2 $inary: 0"""00"0""""0"00000""""00""0"""0 i WW P2 int: 6>FF2IF"0E2 $inary: ""000"0""0""""""""00"0000"000000 i ZZ P2 int: T?F>ETPE2 $inary: 000000"000""000"0""0""""""""00"0 08i1 ZZ P2 int: 6T?F>ETPP2 $inary: """"""0"""00"""0"00"00000000""0" 6"L2 ong: 6"2 $inary: """""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""" R"L2 ong: "2 $inary: 000000000000000000000000000000000000000000000000000000 000000000" !axpo#2 ong: >22TTF20T?IPEFFPI0F2 $inary: 0""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""" !axneg2 ong: 6>22TTF20T?IPEFFPI0I2 $inary: "00000000000000000000000000000000000000000000000000000 0000000000 XhighX$it#2 ong: E?PE>F2P>F2"2020FT?2 $inary: 0"000000"00""00"""00"000"""0"0"00000000000000000000000 0000000000 2 ong: E?PE>F2P>II2>0"E2>P2 $inary: 0"000000"00""00"""00"000"""0"0"00""000000""0000"0"0""" 0"000"0""" 8 2 ong: 6E?PE>F2P>II2>0"E2>?2 $inary: "0""""""0""00""000""0"""000"0"0""00""""""00""""0"0"000 "0"""0"000 6 2 ong: 6E?PE>F2P>II2>0"E2>P2 $inary:
1(#
"0""""""0""00""000""0"""000"0"0""00""""""00""""0"0"000 "0"""0"00" !XhighX$it#2 ong: E?ITPE2T0FTEI"P2T22 $inary: 00000""00""""""""""0""0""0""000"0000000000000000000000 0000000000 !2 ong: E?ITPE2T""PIF0PPEF2 $inary: 00000""00""""""""""0""0""0""000"000""00"0"000"000000"" 0""000"0"" @ !2 ong: F2PFE?T>E22I?P>P2 $inary: 00000000000""00"""00"000"0"00000000000000"0000000000"" 0"000000"" S !2 ong: P""?0?>T??0EPETT2EF2 $inary: 0"000""0"""""""""""0""0""""""0""0""""00"0""00"0"0"0""" 0""00""""" ] !2 ong: P"0II"">02"0T"E??P22 $inary: 0"000""0"""00""000"00"0"0"0""0""0""""00"00"00"0"0"0"00 00"00"""00 WW P2 ong: "TIP"F0PF2IP20EEP"22 $inary: 000"00""00"""00"000"""0"0"00""000000""0000"0"0"""0"000 "0"""00000 ZZ P2 ong: "EPE?FI>TF"TE0??>?2 $inary: 000000"000000"00""00"""00"000"""0"0"00""000000""0000"0 "0"""0"000 08 1 ZZ P2 ong: 6"EPE?FI>TF"TE0??>F2 $inary: """"""0""""""0""00""000""0"""000"0"0""00""""""00""""0" 0"000"0""" The 3inary repre#entati*n *9 the nu+3er# i# re9erred t* a# signed two:s com"lement)
1(&
Thinking in C
www.ThinkingIn.!et
1('
The #ec*nd 9*r+ i# ea#ier t* under#tand, and d*e#nt reDuire a l*t +*re typing) S* 3e #ure t* p*nder y*ur rea#*n# !hen ch**#ing the ternary *perat*r P it# generally !arranted !hen y*ure #etting a varia3le t* *ne *9 t!* value#1 int ternaryRe#u t 9 i W "0 Y i = "00 : i = "03
11(
Thinking in C
www.ThinkingIn.!et
= #i+ilar pr*3le+ in C and C@@ i# u#ing 3it!i#e = ? and OR in#tead *9 the l*gical ver#i*n#) Bit!i#e = ? and OR u#e *ne *9 the character# G L *r MH !hile l*gical = ? and OR u#e t!* GLL and MMH) "u#t a# !ith I and II, it# ea#y t* type 4u#t *ne character in#tead *9 t!*) -n C#, the c*+piler again prevent# thi# 3ecau#e it !*nt let y*u cavalierly u#e *ne type !here it d*e#nt 3el*ng)
Casting o$erators
The !*rd cast i# u#ed in the #en#e *9 Ica#ting int* a +*ld)J C# !ill aut*+atically change *ne type *9 data int* an*ther !hen appr*priate) 5*r in#tance, i9 y*u a##ign an integral value t* a 9l*atingEp*int varia3le, the c*+piler !ill aut*+atically c*nvert the int t* a float) Ca#ting all*!# y*u t* +ake thi# type c*nver#i*n e;plicit, *r t* 9*rce it !hen it !*uldnt n*r+ally happen) T* per9*r+ a ca#t, put the de#ired data type Gincluding all +*di9ier#H in#ide parenthe#e# t* the le9t *9 any value) Here# an e;a+ple1 *oid ca#t#01 ; int i 9 2003 ong 9 0 ong1i3 ong 2 9 0 ong12003 < =# y*u can #ee, it# p*##i3le t* per9*r+ a ca#t *n a nu+eric value a# !ell a# *n a varia3le) -n 3*th ca#t# #h*!n here, h*!ever, the ca#t i# #uper9lu*u#, #ince the c*+piler !ill aut*+atically pr*+*te an int value t* a long !hen nece##ary) H*!ever, y*u are all*!ed t* u#e #uper9lu*u# ca#t# t* +ake a p*int *r t* +ake y*ur c*de +*re clear) -n *ther #ituati*n#, a ca#t +ay 3e e##ential 4u#t t* get the c*de t* c*+pile) -n C and C@@, ca#ting can cau#e #*+e headache#) -n C#, ca#ting i# #a9e, !ith the e;cepti*n that !hen y*u per9*r+ a #*Ecalled narrowing con-ersion Gthat i#, !hen y*u g* 9r*+ a data type that can h*ld +*re in9*r+ati*n t* *ne that d*e#nt h*ld a# +uchH y*u run the ri#k *9 l*#ing in9*r+ati*n) Here the c*+piler 9*rce# y*u t* d* a ca#t, in e99ect #aying Ithi# can 3e a danger*u# thing t* d*Ri9 y*u !ant +e t* d* it any!ay y*u +u#t +ake the ca#t e;plicit)J ,ith a widening con-ersion an e;plicit ca#t
111
i# n*t needed 3ecau#e the ne! type !ill +*re than h*ld the in9*r+ati*n 9r*+ the *ld type #* that n* in9*r+ati*n i# ever l*#t) "ava all*!# y*u t* ca#t any pri+itive type t* any *ther pri+itive type, e;cept 9*r bool, !hich d*e#nt all*! any ca#ting at all) Cla## type# d* n*t all*! ca#ting) T* c*nvert *ne t* the *ther there +u#t 3e #pecial +eth*d#) G:*ull 9ind *ut later in thi# 3**k that *34ect# can 3e ca#t !ithin a $amil4 *9 type#Q an 1a( can 3e ca#t t* a +ree and viceEver#a, 3ut n*t t* a 9*reign type #uch a# a *oc()H
Literals
Ordinarily !hen y*u in#ert a literal value int* a pr*gra+ the c*+piler kn*!# e;actly !hat type t* +ake it) S*+eti+e#, h*!ever, the type i# a+3igu*u#) ,hen thi# happen# y*u +u#t guide the c*+piler 3y adding #*+e e;tra in9*r+ati*n in the 9*r+ *9 character# a##*ciated !ith the literal value) The 9*ll*!ing c*de #h*!# the#e character#1 //: c0T:Litera #.c# na!e#pace c0T; u#ing Sy#te!3 pu$ ic c a## Litera # ; //!char c 9 0xffff3 // !ax char hex *a ue $yte $ 9 0xFf3 // !ax $yte hex *a ue #hort # 9 0xFfff3 // !ax #hort hex *a ue int i" 9 0x2f3 // Uexadeci!a 0 o.erca#e1 int i2 9 0,2H3 // Uexadeci!a 0upperca#e1 int iT 9 0"FF3 // Octa 0 eading Mero1 // Uex and Oct a #o .or% .ith ong. ong n" 9 200L3 // ong #uffix ong n2 9 200 3 // ong #uffix 6 generate# a .arning ong nT 9 2003 //! ong ?020013 // not a o.ed f oat f" 9 "3 f oat f2 9 "H3 // f oat #uffix f oat fT 9 "f3 // f oat #uffix f oat fE 9 "e6EPf3 // "0 to the po.er f oat fP 9 "eR>f3 // f oat #uffix dou$ e d" 9 "d3 // dou$ e #uffix
11)
Thinking in C
www.ThinkingIn.!et
dou$ e d2 9 ":3 // dou$ e #uffix dou$ e dT 9 EFeEFd3 // "0 to the po.er < < //:8 \todo: )ppropriate p ace for ^u00I" type# of thing#Y He;adeci+al G3a#e 0.H, !hich !*rk# !ith all the integral data type#, i# den*ted 3y a leading 4x *r 4? 9*ll*!ed 3y $R6 and aR9 either in upper *r l*!erca#e) -9 y*u try t* initiali7e a varia3le !ith a value 3igger than it can h*ld Gregardle## *9 the nu+erical 9*r+ *9 the valueH, the c*+piler !ill give y*u an err*r +e##age) *tice in the a3*ve c*de the +a;i+u+ p*##i3le he;adeci+al value# 9*r char, byte, and short) -9 y*u e;ceed the#e, the c*+piler !ill aut*+atically +ake the value an int and tell y*u that y*u need a narr*!ing ca#t 9*r the a##ign+ent) :*ull kn*! y*uve #tepped *ver the line) Octal G3a#e (H i# den*ted 3y a leading 7er* in the nu+3er and digit# 9r*+ $E%) :*ud think that, i9 they !ere g*ing t* pr*vide *ctal G!hich - havent #een u#ed in a pr*gra+ in +*re than a decadeH, theyd pr*vide a literal repre#entati*n 9*r 3inary nu+3er#, 3ut #adly, that i# n*t the ca#e) = trailing character a9ter a literal value e#ta3li#he# it# type) Upper *r l*!erca#e L +ean# long, upper *r l*!erca#e : +ean# float and upper *r l*!erca#e $ +ean# double) E;p*nent# u#e a n*tati*n that #*+e 9ind rather di#+aying1 769R e-JSf) -n #cience and engineering, Te re9er# t* the 3a#e *9 natural l*garith+#, appr*;i+ately 2)%0() G= +*re preci#e double value i# availa3le in C# a# .ath6&)H Thi# i# u#ed in e;p*nentiati*n e;pre##i*n# #uch a# 0)/6 ; e E&%, !hich +ean# 0)/6 ; 2)%0(E&%) H*!ever, !hen 5ORTR= !a# invented they decided that e !*uld naturally +ean Iten t* the p*!er,J !hich i# an *dd deci#i*n 3ecau#e 5ORTR= !a# de#igned 9*r #cience and engineering and *ne !*uld think it# de#igner# !*uld 3e #en#itive a3*ut intr*ducing #uch an a+3iguity)0 =t any rate, thi# cu#t*+ !a# 9*ll*!ed in C, C@@ and
0 "*hn Nirkha+ !rite#, I- #tarted c*+puting in 06.2 u#ing 5ORTR=
-- *n an -BA 0.2$) =t that ti+e, and thr*ugh*ut the 06.$# and int* the 06%$#, 5ORTR= !a# an all upperca#e language) Thi# pr*3a3ly #tarted 3ecau#e +any *9 the early input device# !ere *ld teletype unit# that u#ed ' 3it Baud*t c*de, !hich had n* l*!erca#e capa3ility) The TE in the e;p*nential n*tati*n !a# al#* al!ay# upper ca#e and !a# never c*n9u#ed !ith the
113
n*! C#) S* i9 y*ure u#ed t* thinking in ter+# *9 e a# the 3a#e *9 natural l*garith+#, y*u +u#t d* a +ental tran#lati*n !hen y*u #ee an e;pre##i*n #uch a# 769R e-JSf in "avaQ it +ean# 0)/6 ; 0$E&%) *te that y*u d*nt need t* u#e the trailing character !hen the c*+piler can 9igure *ut the appr*priate type) ,ith ong nT 9 2003 there# n* a+3iguity, #* an L a9ter the 2$$ !*uld 3e #uper9lu*u#) H*!ever, !ith f oat fE 9 "e6EFf3 // "0 to the po.er the c*+piler n*r+ally take# e;p*nential nu+3er# a# d*u3le#, #* !ith*ut the trailing f it !ill give y*u an err*r telling y*u that y*u +u#t u#e a ca#t t* c*nvert double t* float)
Pro#otion
:*ull di#c*ver that i9 y*u per9*r+ any +athe+atical *r 3it!i#e *perati*n# *n pri+itive data type# that are #+aller than an int Gthat i#, char, byte, *r shortH, th*#e value# !ill 3e pr*+*ted t* int 3e9*re per9*r+ing the *perati*n#, and the re#ulting value !ill 3e *9 type int) S* i9 y*u !ant t* a##ign 3ack int* the #+aller type, y*u +u#t u#e a ca#t) G=nd, #ince y*ure a##igning 3ack int* a #+aller type, y*u +ight 3e l*#ing in9*r+ati*n)H -n general, the large#t data type in an e;pre##i*n i# the *ne that deter+ine# the #i7e *9 the re#ult *9 that e;pre##i*nQ i9 y*u +ultiply a float and a double, the re#ult !ill 3e doubleQ i9 y*u add an int and a long, the re#ult !ill 3e long)
natural l*garith+ 3a#e Te, !hich i# al!ay# l*!erca#e) The TE #i+ply #t**d 9*r e;p*nential, !hich !a# 9*r the 3a#e *9 the nu+3er #y#te+ u#edRu#ually 0$) =t the ti+e *ctal !a# al#* !idely u#ed 3y pr*gra++er#) =lth*ugh - never #a! it u#ed, i9 - had #een an *ctal nu+3er in e;p*nential n*tati*n - !*uld have c*n#idered it t* 3e 3a#e () The 9ir#t ti+e - re+e+3er #eeing an e;p*nential u#ing a l*!erca#e Te !a# in the late 06%$# and - al#* 9*und it c*n9u#ing) The pr*3le+ ar*#e a# l*!erca#e crept int* 5ORTR= , n*t at it# 3eginning) ,e actually had 9uncti*n# t* u#e i9 y*u really !anted t* u#e the natural l*garith+ 3a#e, 3ut they !ere all upperca#e)J
114
Thinking in C
www.ThinkingIn.!et
C# has Gsi:eo0H
The siTeof( ) *perat*r #ati#9ie# a #peci9ic need1 it tell# y*u the nu+3er *9 3yte# all*cated 9*r data ite+#) The +*#t c*+pelling need 9*r siTeof( ) in C and C@@ i# p*rta3ility) ?i99erent data type# +ight 3e di99erent #i7e# *n di99erent +achine#, #* the pr*gra++er +u#t 9ind *ut h*! 3ig th*#e type# are !hen per9*r+ing *perati*n# that are #en#itive t* #i7e) 5*r e;a+ple, *ne c*+puter +ight #t*re integer# in /2 3it#, !herea# an*ther +ight #t*re integer# a# 0. 3it#) Pr*gra+# c*uld #t*re larger value# in integer# *n the 9ir#t +achine) =# y*u +ight i+agine, p*rta3ility i# a huge headache 9*r C and C@@ pr*gra++er#) -n C#, thi# +*#t c*++*n u#e *9 #i7e*9GH i# n*t relevant, 3ut it can c*+e int* play !hen inter9acing !ith e;ternal data #tructure# *r !hen y*ure +anipulating 3l*ck# *9 ra! data and y*ure !illing t* 9*reg* c*nvenience and #a9ety 9*r every la#t 3it *9 #peed G#ay, i9 y*ure !riting a r*utine 9*r pr*ce##ing vide* dataH) The siTeof() *perat*r i# *nly u#a3le in#ide un#a9e c*de G#ee #H)
C#s Pre$rocessor
C## prepr*ce##ing directive# #h*uld 3e u#ed !ith cauti*n) .1*& The#e are "re"rocessor directi-es a# de#cri3ed in chapter #prepr*ce##ing# and +u#t 3e the *nly #tate+ent# *n a line) C# d*e# n*t actually have a #eparate prepr*ce##ing #tep that run# pri*r t* c*+pilati*n 3ut the 9*r+ and u#e *9 the#e #tate+ent# i# intended t* 3e 9a+iliar t* C and C@@ pr*gra++er#) ,hile there# n* har+ in the #regi*n directive#, the *ther directive# #upp*rt conditional com"ilation, !hich all*!# a #ingle c*de3a#e t* generate +ultiple 3inary *utput#) The +*#t c*++*n u#e *9 c*nditi*nal c*+pilati*n i# t* re+*ve de3ugging 3ehavi*r 9r*+ a #hipping pr*ductQ thi# i# d*ne 3y de9ining a #y+3*l *n the c*+pilati*n c*++andEline, and u#ing the Uif, Uendif, Uelse, and Uelif directive# t* create c*nditi*nal l*gic depending *n the e;i#tence *r a3#ence *9 *ne *r +*re #uch #y+3*l#) Here# a #i+ple e;a+ple1 //:c"T:CondCo!p.c# //:e!on#trate# conditiona co!pi ation
115
c a## CondCo!p; pu$ ic #tatic *oid Gain01; (if :+BO_ Sy#te!.Con#o e.VriteLine0&:e$ug $eha*ior&13 (endif < < -9 CondComp i# c*+piled !ith the c*++andEline csc /defineD$ebug CondComp6cs it !ill print the lineQ i9 !ith a #traight csc CondComp6cs, it !*nt) ,hile thi# #ee+# like a rea#*na3le idea, in practice it *9ten lead# t* #ituati*n# !here a change i# +ade in *ne c*nditi*nal 3ranch and n*t in an*ther, and the prepr*ce##*r leave# n* trace in the c*de *9 the c*+pilati*n *pti*n#Q in general, it# a 3etter idea t* u#e a readonly bool 9*r #uch thing#) = rea#*na3le c*+pr*+i#e i# t* u#e the prepr*ce##*r directive# t* #et the value# *9 varia3le# that are u#ed t* change runti+e 3ehavi*r1 //:c"T:Gar%edCondCo!p.c# //:e!on#trate# conditiona c a## CondCo!p; #tatic readon y $oo (if :+BO_ true3 (e #e fa #e3 (endif co!pi ation
:+BO_ 9
pu$ ic #tatic *oid Gain01; if0:+BO_1 Sy#te!.Con#o e.VriteLine0&:e$ug $eha*ior&13 < <///:8 -n .ar(edCondComp, i9 a pr*3le+ ar*#e, a de3ugger *r l*gging 9acility !*uld 3e a3le t* read the value *9 the $&BV bool, thu# all*!ing the +aintenance pr*gra++er# t* deter+ine the c*+pilati*n c*++and# that lead t* the tr*u3le#*+e 3ehavi*r) The trivial di#advantage# *9 thi# +*del are the #light penalty *9 a runti+e c*+pari#*n and the increa#e in the a##e+3ly# #i7e due t* the pre#ence *9 the de3ugging c*de)
116
Thinking in C
www.ThinkingIn.!et
Precedence revisited
Operat*r precedence i# di99icult t* re+e+3er, 3ut here i# a help9ul +ne+*nic 1 IUlcer =ddict# Really Like C# = l*t)J .nemonic Ulcer =ddict# Really Like C# = L*t 1perator type Unary =rith+etic Gand #hi9tH Relati*nal L*gical Gand 3it!i#eH C*nditi*nal GternaryH =##ign+ent 1perators C - CC-; / K C - PP QQ Q P QI PI II !I LL MM L M N 'QBW?D@ I Gand c*+p*und a##ign+ent like ;IH
O9 c*ur#e, !ith the #hi9t and 3it!i#e *perat*r# di#tri3uted ar*und the ta3le it i# n*t a per9ect +ne+*nic, 3ut 9*r n*nE3it *perati*n# it !*rk#)
) co#$endiu# o0 o$erators
The 9*ll*!ing e;a+ple #h*!# !hich pri+itive data type# can 3e u#ed !ith particular *perat*r#) Ba#ically, it i# the #a+e e;a+ple repeated *ver and *ver, 3ut u#ing di99erent pri+itive data type#) The 9ile !ill c*+pile !ith*ut err*r 3ecau#e the line# that !*uld cau#e err*r# are c*++ented *ut !ith a //!) //:c0T.) Op#.c# na!e#pace c0T; u#ing Sy#te!3 // 'e#t# a the operator# on a the // pri!iti*e data type# to #ho. .hich // one# are accepted $y the `a*a co!pi er. pu$ ic c a## ) Op# ; // 'o accept the re#u t# of a $oo ean te#t: *oid H0$oo $1 ;< *oid $oo 'e#t0$oo x2 $oo y1 ; // )rith!etic operator#: //! x 9 x = y3 //! x 9 x / y3
11#
//! x 9 x [ y3 //! x 9 x R y3 //! x 9 x 6 y3 //! xRR3 //! x663 //! x 9 Ry3 //! x 9 6y3 // Re ationa and ogica : //! H0x Z y13 //! H0x Z9 y13 //! H0x W y13 //! H0x W9 y13 H0x 99 y13 H0x !9 y13 H0!y13 x 9 x @@ y3 x 9 x SS y3 // Bit.i#e operator#: //! x 9 8y3 x 9 x @ y3 x 9 x S y3 x 9 x ] y3 //! x 9 x WW "3 //! x 9 x ZZ "3 //! x 9 x ZZZ "3 // Co!pound a##ign!ent: //! x R9 y3 //! x 69 y3 //! x =9 y3 //! x /9 y3 //! x [9 y3 //! x WW9 "3 //! x ZZ9 "3 //! x ZZZ9 "3 x @9 y3 x ]9 y3 x S9 y3 // Ca#ting: //! char c 9 0char1x3 //! $yte B 9 0$yte1x3 //! #hort # 9 0#hort1x3
11&
Thinking in C
www.ThinkingIn.!et
//! int i 9 0int1x3 //! ong 9 0 ong1x3 //! f oat f 9 0f oat1x3 //! dou$ e d 9 0dou$ e1x3 < *oid char'e#t0char x2 char y1 ; // )rith!etic operator#: x 9 0char10x = y13 x 9 0char10x / y13 x 9 0char10x [ y13 x 9 0char10x R y13 x 9 0char10x 6 y13 xRR3 x663 x 9 0char1Ry3 x 9 0char16y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13 //! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: x9 0char18y3 x 9 0char10x @ y13 x 9 0char10x S y13 x 9 0char10x ] y13 x 9 0char10x WW "13 x 9 0char10x ZZ "13 //! \todo x 9 0char10x ZZZ "13 // Co!pound a##ign!ent: x R9 y3 x 69 y3 x =9 y3 x /9 y3 x [9 y3 x WW9 "3
11'
x ZZ9 "3 //\todo x ZZZ9 "3 x @9 y3 x ]9 y3 x S9 y3 // Ca#ting: //! $oo $ 9 0$oo 1x3 $yte B 9 0$yte1x3 #hort # 9 0#hort1x3 int i 9 0int1x3 ong 9 0 ong1x3 f oat f 9 0f oat1x3 dou$ e d 9 0dou$ e1x3 < *oid $yte'e#t0$yte x2 $yte y1 ; // )rith!etic operator#: x 9 0$yte10x= y13 x 9 0$yte10x / y13 x 9 0$yte10x [ y13 x 9 0$yte10x R y13 x 9 0$yte10x 6 y13 xRR3 x663 x 9 0$yte1R y3 x 9 0$yte16 y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13 //! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: x 9 0$yte18y3 x 9 0$yte10x @ y13 x 9 0$yte10x S y13 x 9 0$yte10x ] y13 x 9 0$yte10x WW "13
1)(
Thinking in C
www.ThinkingIn.!et
x 9 0$yte10x ZZ "13 //\todo x 9 0$yte10x ZZZ "13 // Co!pound a##ign!ent: x R9 y3 x 69 y3 x =9 y3 x /9 y3 x [9 y3 x WW9 "3 x ZZ9 "3 //\todo x ZZZ9 "3 x @9 y3 x ]9 y3 x S9 y3 // Ca#ting: //! $oo $ 9 0$oo 1x3 char c 9 0char1x3 #hort # 9 0#hort1x3 int i 9 0int1x3 ong 9 0 ong1x3 f oat f 9 0f oat1x3 dou$ e d 9 0dou$ e1x3 < *oid #hort'e#t0#hort x2 #hort y1 ; // )rith!etic operator#: x 9 0#hort10x = y13 x 9 0#hort10x / y13 x 9 0#hort10x [ y13 x 9 0#hort10x R y13 x 9 0#hort10x 6 y13 xRR3 x663 x 9 0#hort1Ry3 x 9 0#hort16y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13
1)1
//! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: x 9 0#hort18y3 x 9 0#hort10x @ y13 x 9 0#hort10x S y13 x 9 0#hort10x ] y13 x 9 0#hort10x WW "13 x 9 0#hort10x ZZ "13 //\todo x 9 0#hort10x ZZZ "13 // Co!pound a##ign!ent: x R9 y3 x 69 y3 x =9 y3 x /9 y3 x [9 y3 x WW9 "3 x ZZ9 "3 //\todo x ZZZ9 "3 x @9 y3 x ]9 y3 x S9 y3 // Ca#ting: //! $oo $ 9 0$oo 1x3 char c 9 0char1x3 $yte B 9 0$yte1x3 int i 9 0int1x3 ong 9 0 ong1x3 f oat f 9 0f oat1x3 dou$ e d 9 0dou$ e1x3 < *oid int'e#t0int x2 int y1 ; // )rith!etic operator#: x 9 x = y3 x 9 x / y3 x 9 x [ y3 x 9 x R y3 x 9 x 6 y3 xRR3 x663
1))
Thinking in C
www.ThinkingIn.!et
x 9 Ry3 x 9 6y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13 //! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: x 9 8y3 x 9 x @ y3 x 9 x S y3 x 9 x ] y3 x 9 x WW "3 x 9 x ZZ "3 //\todo x 9 x ZZZ "3 // Co!pound a##ign!ent: x R9 y3 x 69 y3 x =9 y3 x /9 y3 x [9 y3 x WW9 "3 x ZZ9 "3 //\todo x ZZZ9 "3 x @9 y3 x ]9 y3 x S9 y3 // Ca#ting: //! $oo $ 9 0$oo 1x3 char c 9 0char1x3 $yte B 9 0$yte1x3 #hort # 9 0#hort1x3 ong 9 0 ong1x3 f oat f 9 0f oat1x3 dou$ e d 9 0dou$ e1x3 <
1)3
*oid ong'e#t0 ong x2 ong y1 ; // )rith!etic operator#: x 9 x = y3 x 9 x / y3 x 9 x [ y3 x 9 x R y3 x 9 x 6 y3 xRR3 x663 x 9 Ry3 x 9 6y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13 //! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: x 9 8y3 x 9 x @ y3 x 9 x S y3 x 9 x ] y3 x 9 x WW "3 x 9 x ZZ "3 //\todo x 9 x ZZZ "3 // Co!pound a##ign!ent: x R9 y3 x 69 y3 x =9 y3 x /9 y3 x [9 y3 x WW9 "3 x ZZ9 "3 //\todo x ZZZ9 "3 x @9 y3 x ]9 y3 x S9 y3
1)4
Thinking in C
www.ThinkingIn.!et
// Ca#ting: //! $oo $ 9 0$oo 1x3 char c 9 0char1x3 $yte B 9 0$yte1x3 #hort # 9 0#hort1x3 int i 9 0int1x3 f oat f 9 0f oat1x3 dou$ e d 9 0dou$ e1x3 < *oid f oat'e#t0f oat x2 f oat y1 ; // )rith!etic operator#: x 9 x = y3 x 9 x / y3 x 9 x [ y3 x 9 x R y3 x 9 x 6 y3 xRR3 x663 x 9 Ry3 x 9 6y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13 //! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: //! x 9 8y3 //! x 9 x @ y3 //! x 9 x S y3 //! x 9 x ] y3 //! x 9 x WW "3 //! x 9 x ZZ "3 //! x 9 x ZZZ "3 // Co!pound a##ign!ent: x R9 y3 x 69 y3
1)5
x =9 y3 x /9 y3 x [9 y3 //! x WW9 "3 //! x ZZ9 "3 //! x ZZZ9 "3 //! x @9 y3 //! x ]9 y3 //! x S9 y3 // Ca#ting: //! $oo $ 9 0$oo 1x3 char c 9 0char1x3 $yte B 9 0$yte1x3 #hort # 9 0#hort1x3 int i 9 0int1x3 ong 9 0 ong1x3 dou$ e d 9 0dou$ e1x3 < *oid dou$ e'e#t0dou$ e x2 dou$ e y1 ; // )rith!etic operator#: x 9 x = y3 x 9 x / y3 x 9 x [ y3 x 9 x R y3 x 9 x 6 y3 xRR3 x663 x 9 Ry3 x 9 6y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13 //! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: //! x 9 8y3
1)6
Thinking in C
www.ThinkingIn.!et
//! x 9 x @ y3 //! x 9 x S y3 //! x 9 x ] y3 //! x 9 x WW "3 //! x 9 x ZZ "3 //! x 9 x ZZZ "3 // Co!pound a##ign!ent: x R9 y3 x 69 y3 x =9 y3 x /9 y3 x [9 y3 //! x WW9 "3 //! x ZZ9 "3 //! x ZZZ9 "3 //! x @9 y3 //! x ]9 y3 //! x S9 y3 // Ca#ting: //! $oo $ 9 0$oo 1x3 char c 9 0char1x3 $yte B 9 0$yte1x3 #hort # 9 0#hort1x3 int i 9 0int1x3 ong 9 0 ong1x3 f oat f 9 0f oat1x3 < < < //:8 *te that bool i# Duite li+ited) :*u can a##ign t* it the value# true and false, and y*u can te#t it 9*r truth *r 9al#eh**d, 3ut y*u cann*t add 3**lean# *r per9*r+ any *ther type *9 *perati*n *n the+) -n char, byte, and short y*u can #ee the e99ect *9 pr*+*ti*n !ith the arith+etic *perat*r#) Each arith+etic *perati*n *n any *9 th*#e type# re#ult# in an int re#ult, !hich +u#t 3e e;plicitly ca#t 3ack t* the *riginal type Ga narr*!ing c*nver#i*n that +ight l*#e in9*r+ati*nH t* a##ign 3ack t* that type) ,ith int value#, h*!ever, y*u d* n*t need t* ca#t, 3ecau#e everything i# already an int) ?*nt 3e lulled int* thinking everything i#
1)#
#a9e, th*ugh) -9 y*u +ultiply t!* int# that are 3ig en*ugh, y*ull *ver9l*! the re#ult) The 9*ll*!ing e;a+ple de+*n#trate# thi#1 //:c0T:O*erH o..c# na!e#pace c0T; u#ing Sy#te!3 pu$ ic c a## O*erf o. ; pu$ ic #tatic *oid Gain01 ; int $ig 9 0xFfffffff3 // !ax int *a ue -rt0&$ig 9 & R $ig13 int $igger 9 $ig = E3 -rt0&$igger 9 & R $igger13 $igger 9 chec%ed0$ig = E13 //! -rt0&ne*er reached&13 < #tatic *oid -rt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 < < < //:8 The *utput *9 thi# i#1 $ig 9 2"EFEIT?EF $igger 9 6E Onhand ed +xception: Sy#te!.O*erf o.+xception: +xception of type Sy#te!.O*erf o.+xception .a# thro.n. at c0T.O*erf o..Gain01
-9 a p*tentially *ver9l*!ing +athe+atical *perati*n i# n*t !rapped in the chec(ed() key!*rd, y*u !ill get n* err*r# *r !arning# 9r*+ the c*+piler, and n* e;cepti*n# at runEti+e) Ot*d*1 Mue#ti*n P !hy arent all arith+etic *perati*n# in #a9e c*de checked and all arith+etic in un#a9e c*de n*tF C*+p*und a##ign+ent# d* not reDuire ca#t# 9*r char, byte, *r short, even th*ugh they are per9*r+ing pr*+*ti*n# that have the #a+e re#ult#
1)&
Thinking in C
www.ThinkingIn.!et
a# the direct arith+etic *perati*n#) On the *ther hand, the lack *9 the ca#t certainly #i+pli9ie# the c*de) :*u can #ee that, !ith the e;cepti*n *9 boolean, any pri+itive type can 3e ca#t t* any *ther pri+itive type) =gain, y*u +u#t 3e a!are *9 the e99ect *9 a narr*!ing c*nver#i*n !hen ca#ting t* a #+aller type, *ther!i#e y*u +ight unkn*!ingly l*#e in9*r+ati*n during the ca#t)
%&ecution control
C# u#e# all *9 C# e;ecuti*n c*ntr*l #tate+ent#, #* i9 y*uve pr*gra++ed !ith C *r C@@ then +*#t *9 !hat y*u #ee !ill 3e 9a+iliar) A*#t pr*cedural pr*gra++ing language# have #*+e kind *9 c*ntr*l #tate+ent#, and there i# *9ten *verlap a+*ng language#) -n C#, the key!*rd# include if-else, while, do-while, for, foreach, and a #electi*n #tate+ent called switch) C# 4u+ping key!*rd# are brea(, continue, goto Gye#, gotoH, and return)
i0;else
The if-else #tate+ent i# pr*3a3ly the +*#t 3a#ic !ay t* c*ntr*l pr*gra+ 9l*!) The else i# *pti*nal, #* y*u can u#e if in t!* 9*r+#1 if(Boo ean6expre##ion) #tate!ent
1)'
*r if(Boo ean6expre##ion) #tate!ent else #tate!ent The c*nditi*nal +u#t pr*duce a bool re#ult) The statement +ean# either a #i+ple #tate+ent ter+inated 3y a #e+ic*l*n *r a c*+p*und #tate+ent, !hich i# a gr*up *9 #i+ple #tate+ent# encl*#ed in 3race#) =ny ti+e the !*rd IstatementJ i# u#ed, it al!ay# i+plie# that the #tate+ent can 3e #i+ple *r c*+p*und) =# an e;a+ple *9 if-else, here i# a test( ) +eth*d that !ill tell y*u !hether a gue## i# a3*ve, 3el*!, *r eDuivalent t* a target nu+3er1 //:c0T:5f+ #e.c# na!e#pace c0T; pu$ ic c a## 5f+ #e ; #tatic int 'e#t0int te#t*a 2 int target1 ; int re#u t 9 03 if 0te#t*a Z target1 re#u t 9 R"3 e #e if 0te#t*a W target1 re#u t 9 6"3 e #e re#u t 9 03 // Gatch return re#u t3 < pu$ ic #tatic *oid Gain01 ; Sy#te!.Con#o e.VriteLine0'e#t0"02 P113 Sy#te!.Con#o e.VriteLine0'e#t0P2 "0113 Sy#te!.Con#o e.VriteLine0'e#t0P2 P113 < < <///:8 -t i# c*nventi*nal t* indent the 3*dy *9 a c*ntr*l 9l*! #tate+ent #* the reader +ight ea#ily deter+ine !here it 3egin# and end#)
13(
Thinking in C
www.ThinkingIn.!et
$eturn
The return key!*rd ha# t!* purp*#e#1 it #peci9ie# !hat value a +eth*d !ill return Gi9 it d*e#nt have a void return valueH and it cau#e# that value t* 3e returned i++ediately) The test( ) +eth*d a3*ve can 3e re!ritten t* take advantage *9 thi#1 //:c0T:5f+ #e2.c# pu$ ic c a## 5f+ #e2 ; #tatic int 'e#t0int te#t*a 2 int target1 ; int re#u t 9 03 if 0te#t*a Z target1 return "3 e #e if 0te#t*a W target1 return 6"3 e #e return 03 // Gatch < pu$ ic #tatic *oid Gain01 ; Sy#te!.Con#o e.VriteLine0'e#t0"02 P113 Sy#te!.Con#o e.VriteLine0'e#t0P2 "0113 Sy#te!.Con#o e.VriteLine0'e#t0P2 P113 < < ///:8 =lth*ugh thi# c*de ha# t!* else#, they are actually unnece##ary, 3ecau#e the +eth*d !ill n*t c*ntinue a9ter e;ecuting a return) -t i# g**d pr*gra++ing practice t* have a# 9e! e;it p*int# a# p*##i3le in a +eth*dQ a reader #h*uld 3e a3le t* #ee at a glance the I#hapeJ *9 a +eth*d !ith*ut having t* think IOhK Unle## #*+ething happen# in thi# c*nditi*nal, in !hich ca#e it never get# t* thi# *ther area)J) =9ter re!riting the +eth*d #* that there# *nly *ne e;it p*int, !e can add e;tra 9uncti*nality t* the +eth*d and kn*! that it !ill al!ay# 3e called1 //:c0T:5f+ #eT.c# pu$ ic c a## 5f+ #eT ; #tatic int 'e#t0int te#t*a 2 int target1 ; int re#u t 9 03 //Gatch if 0te#t*a Z target1
131
re#u t 9 "3 e #e if 0te#t*a W target1 re#u t 9 6"3 Sy#te!.Con#o e.VriteLine0&) here&13 return re#u t3
path# pa##
< pu$ ic #tatic *oid Gain01 ; Sy#te!.Con#o e.VriteLine0'e#t0"02 P113 Sy#te!.Con#o e.VriteLine0'e#t0P2 "0113 Sy#te!.Con#o e.VriteLine0'e#t0P2 P113 < < ///:8
Iteration
while, do-while, and for c*ntr*l l**ping and are #*+eti+e# cla##i9ied a# iteration statements) = statement repeat# until the c*ntr*lling BooleanEe%"ression evaluate# t* 9al#e) The 9*r+ 9*r a while l**p i# while(Boo ean6expre##ion) #tate!ent The Boolean9e%"ression i# evaluated *nce at the 3eginning *9 the l**p and again 3e9*re each 9urther iterati*n *9 the statement) Here# a #i+ple e;a+ple that generate# rand*+ nu+3er# until a particular c*nditi*n i# +et1 //:c0T:Vhi e'e#t.c# na!e#pace c0T; u#ing Sy#te!3 // :e!on#trate# the .hi e oop. pu$ ic c a## Vhi e'e#t ; pu$ ic #tatic *oid Gain01 ; Rando! rand 9 ne. Rando!013 dou$ e r 9 03 .hi e 0r W 0.>>d1 ; r 9 rand.Cext:ou$ e013 Sy#te!.Con#o e.VriteLine0r13 <
13)
Thinking in C
www.ThinkingIn.!et
< < <///:8 Thi# u#e# the static +eth*d random( ) in the .ath li3rary, !hich generate# a double value 3et!een $ and 0) G-t include# $, 3ut n*t 0)H The c*nditi*nal e;pre##i*n 9*r the while #ay# Ikeep d*ing thi# l**p until the nu+3er i# $)66 *r greater)J Each ti+e y*u run thi# pr*gra+ y*ull get a di99erentE#i7ed li#t *9 nu+3er#)
do;while
The 9*r+ 9*r do-while i# do #tate!ent while(Boo ean6expre##ion); The #*le di99erence 3et!een while and do-while i# that the #tate+ent *9 the do-while al!ay# e;ecute# at lea#t *nce, even i9 the e;pre##i*n evaluate# t* 9al#e the 9ir#t ti+e) -n a while, i9 the c*nditi*nal i# 9al#e the 9ir#t ti+e the #tate+ent never e;ecute#) -n practice, do-while i# le## c*++*n than while)
0or
= for l**p per9*r+# initiali7ati*n 3e9*re the 9ir#t iterati*n) Then it per9*r+# c*nditi*nal te#ting and, at the end *9 each iterati*n, #*+e 9*r+ *9 I#tepping)J The 9*r+ *9 the for l**p i#1 for(initia iMation; Boo ean6expre##ion; #tep) #tate!ent =ny *9 the e;pre##i*n# initiali;ation, Boolean9e%"ression *r ste" can 3e e+pty) The e;pre##i*n i# te#ted 3e9*re each iterati*n, and a# #**n a# it evaluate# t* false e;ecuti*n !ill c*ntinue at the line 9*ll*!ing the for #tate+ent) =t the end *9 each l**p, the ste" e;ecute#) for l**p# are u#ually u#ed 9*r Ic*untingJ ta#k#1 //:c0T:Li#tCharacter#.c#
133
na!e#pace c0T; u#ing Sy#te!3 // :e!on#trate# &for& oop $y i#ting // a the )SC55 character#. pu$ ic c a## Li#tCharacter# ; pu$ ic #tatic *oid Gain01 ; for 0 char c 9 0char1 03 c W 0char1 "2I3 cRR1 if 0c !9 2? 1 // )CS5 C ear #creen Sy#te!.Con#o e.VriteLine0 &*a ue: & R 0int1c R & character: & R c13 < < <///:8 *te that the varia3le c i# de9ined at the p*int !here it i# u#ed, in#ide the c*ntr*l e;pre##i*n *9 the for l**p, rather than at the 3eginning *9 the 3l*ck den*ted 3y the *pen curly 3race) The #c*pe *9 c i# the e;pre##i*n c*ntr*lled 3y the for) Traditi*nal pr*cedural language# like C reDuire that all varia3le# 3e de9ined at the 3eginning *9 a 3l*ck #* !hen the c*+piler create# a 3l*ck it can all*cate #pace 9*r th*#e varia3le#) -n C#, y*u can #pread y*ur varia3le declarati*n# thr*ugh*ut the 3l*ck, de9ining the+ at the p*int that y*u need the+) Thi# all*!# a +*re natural c*ding #tyle and +ake# c*de ea#ier t* under#tand) :*u can de9ine +ultiple varia3le# !ithin a for #tate+ent, 3ut they +u#t 3e *9 the #a+e type1 for0int i 9 02 D 9 "3 i W "0 @@ D !9 ""3 iRR2 DRR1 /= $ody of for oop =/3 The int de9initi*n in the for #tate+ent c*ver# 3*th i and )) The a3ility t* de9ine varia3le# in the c*ntr*l e;pre##i*n i# li+ited t* the for l**p) :*u
134
Thinking in C
www.ThinkingIn.!et
cann*t u#e thi# appr*ach !ith any *9 the *ther #electi*n *r iterati*n #tate+ent#)
0oreach
C# ha# a #peciali7ed iterati*n *perat*r called foreach) Unlike the *ther#, 9*reach d*e# n*t l**p 3a#ed *n a 3**lean e;pre##i*n) Rather, it e;ecute# a 3l*ck *9 c*de *n each ele+ent in an array *r *ther c*llecti*n) The 9*r+ 9*r foreach i#1 foreach0type oopNaria$ e in co ection1; #tate!ent < The foreach #tate+ent i# a ter#e !ay t* #peci9y the +*#t c*++*n type *9 l**p and d*e# #* !ith*ut intr*ducing p*tentially c*n9u#ing inde; varia3le#) C*+pare the clarity *9 foreach and for in thi# e;a+ple1
//:c0T:Hor+ach.c# c a## Hor+ach ; pu$ ic #tatic *oid Gain01 ; #tringJK !onth# 9 ;&`anuary&2 &He$ruary&2 &Garch&2 &)pri &<3 //etc #tringJK .ee%# 9 ;&"#t&2 &2nd&2 &Trd&2 &Eth&<3 #tringJK day# 9 ;&Sunday&2 &Gonday&2 &'ue#day&2 &Vedne#day&<3 //etc foreach0#tring !onth in !onth#1 foreach0#tring .ee% in .ee%#1 foreach0#tring day in day#1 Sy#te!.Con#o e.VriteLine0&;0< ;"< .ee% ;2<&2 !onth2 .ee%2 day13 for0int !onth 9 03 !onth W !onth#.Length3 !onthRR1 for0int .ee% 9 03 .ee% W .ee%#.Length3 .ee%RR1 for0int day 9 03 day W day#.Length3 dayRR1
135
Sy#te!.Con#o e.VriteLine0&;0< ;"< .ee% ;2<&2 !onth#J!onthK2 .ee%#J.ee%K2 day#JdayK13 < < ///:8 =n*ther advantage *9 foreach i# that it per9*r+# an i+plicit typeca#t *n *34ect# #t*red in c*llecti*n#, #aving a 9e! +*re key#tr*ke# !hen *34ect# are #t*red n*t in array#, 3ut in +*re c*+ple; data #tructure#) ,ell c*ver thi# a#pect *9 foreach in Chapter #)
136
Thinking in C
www.ThinkingIn.!et
:*u can #ee that in 3*th the initiali7ati*n and #tep p*rti*n# the #tate+ent# are evaluated in #eDuential *rder) =l#*, the initiali7ati*n p*rti*n can have any nu+3er *9 de9initi*n# o$ one t4"e)
13#
<///:8 -n the for l**p the value *9 i never get# t* 0$$ 3ecau#e the brea( #tate+ent 3reak# *ut *9 the l**p !hen i i# %&) *r+ally, y*ud u#e a brea( like thi# *nly i9 y*u didnt kn*! !hen the ter+inating c*nditi*n !a# g*ing t* *ccur) The continue #tate+ent cau#e# e;ecuti*n t* g* 3ack t* the t*p *9 the iterati*n l**p Gthu# incre+enting iH !henever i i# n*t evenly divi#i3le 3y 6) ,hen it i#, the value i# printed) The #ec*nd p*rti*n #h*!# an Iin9inite l**pJ that !*uld, in the*ry, c*ntinue 9*rever) H*!ever, in#ide the l**p there i# a brea( #tate+ent that !ill 3reak *ut *9 the l**p) -n additi*n, y*ull #ee that the continue +*ve# 3ack t* the t*p *9 the l**p !ith*ut c*+pleting the re+ainder) GThu# printing happen# in the #ec*nd l**p *nly !hen the value *9 i i# divi#i3le 3y 0$)H The *utput i#1 0 > "I 2F T? EP PE ?T F2 "0 20 T0 E0 The value $ i# printed 3ecau#e $ ^ 6 pr*duce# $) = #ec*nd 9*r+ *9 the in9inite l**p i# for(FF)) The c*+piler treat# 3*th while(true) and for(FF) in the #a+e !ay, #* !hichever *ne y*u u#e i# a +atter *9 pr*gra++ing ta#te) G=lth*ugh while(true) i# clearly the *nly ch*ice 9*r a per#*n *9 di#cri+inating ta#te)H
13&
Thinking in C
www.ThinkingIn.!et
language1 Ii9 c*nditi*n =, then 4u+p here, *ther!i#e 4u+p there)J -9 y*u read the a##e+3ly c*de that i# ulti+ately generated 3y virtually any c*+piler, y*ull #ee that pr*gra+ c*ntr*l c*ntain# +any 4u+p#) H*!ever, a goto i# a 4u+p at the #*urceEc*de level, and that# !hat 3r*ught it int* di#repute) -9 a pr*gra+ !ill al!ay# 4u+p 9r*+ *ne p*int t* an*ther, i#nt there #*+e !ay t* re*rgani7e the c*de #* the 9l*! *9 c*ntr*l i# n*t #* 4u+pyF goto 9ell int* true di#9av*r !ith the pu3licati*n *9 the 9a+*u# 06.( paper I>* T* State+ent C*n#idered Har+9ulJ 3y Ed#ger ?i4k#tra Ghttp1<<!!!)ac+)*rg<cla##ic#<*ct6'<H) ?i4k#tra argued that !hen y*u have a 4u+p, the c*nte;t that created the pr*gra+ #tate 3ec*+e# di99icult t* vi#uali7e) Since then, g*t*E3a#hing ha# 3een a p*pular #p*rt, !ith adv*cate# *9 the ca#tE*ut key!*rd #currying 9*r c*ver) =# i# typical in #ituati*n# like thi#, the +iddle gr*und i# the +*#t 9ruit9ul) The pr*3le+ i# n*t the u#e *9 goto, 3ut the *veru#e *9 goto *r, indeed, any #tate+ent that +ake# it di99icult t* #ay I,hen thi# line i# reached, the #tate *9 the #y#te+ i# nece##arily #uchEandE#uch)J The 3e#t !ay t* !rite c*de that +ake# #y#te+ #tate ea#y t* deter+ine i# t* +ini+i7e cycl*+atic c*+ple;ity, !hich i# a 9ancy !ay *9 #aying Iu#e a# 9e! #electi*n and 4u+p #tate+ent# a# p*##i3le)J Cycl*+atic c*+ple;ity i# the +ea#ure *9 the nu+3er *9 p*##i3le path# thr*ugh a 3l*ck *9 c*de)
Error! Not a valid link.
-n 9igure #, the +eth*d# #i+pleGH and al#*Si+pleGH have a cycl*+atic c*+ple;ity *9 0Q there i# *nly a #ingle path thr*ugh the c*de) -t d*e# n*t +atter h*! l*ng the +eth*d i#, !hether the +eth*d create# *34ect#, *r even i9 the +eth*d call# *ther, +*re c*+ple;, +eth*d# Gi9 th*#e +eth*d# have high c*+ple;ity, #* 3e it, it d*e#nt a99ect the c*+ple;ity *9 the +eth*d at handH) Thi# #i+plicity i# re9lected in the c*ntr*l graph #h*!nQ a #ingle line #h*!ing the directi*n *9 e;ecuti*n t*!ard# the e;it p*int) The +eth*d *neL**pGH i# #lightly +*re c*+ple;) * +atter !hat it# input para+eter, it !ill print *ut IBeginJ and a##ign ; t* y at the very 3eginning *9 the 9*r l**p) That# the 9ir#t edge *n it# c*ntr*l graph Gt* help align !ith the #*urce c*de, the 9igure #h*!# a #ingle IedgeJ a# a #traight length *9 c*de and a curving 4u+pH) Then, it ma4 c*ntinue int* the l**p, a##ign 7 and print it, incre+ent y, and l**pQ that# the #ec*nd edge) 5inally, at #*+e p*int, y !ill 3e eDual t* 0$ and c*ntr*l !ill 4u+p t* the
13'
end *9 the +eth*d) Thi# i# the third edge, a# +arked *n the 9igure) Aeth*d t!*E;it#GH al#* ha# a cycl*+atic c*+ple;ity *9 /, alth*ugh it# #ec*nd edge d*e#nt l**p, 3ut e;it#) The ne;t +eth*d, t!*L**p#GH, hardly #ee+# +*re c*+ple; than *neL**pGH, 3ut i9 y*u l**k at it# c*ntr*l graph, y*u can c*unt 9ive di#tinct edge#) 5inally, !e #ee a vi#ual repre#entati*n *9 !hat pr*gra++er# call I#paghetti c*de)J ,ith a cycl*+atic c*+ple;ity *9 02, #paghettiGH i# a3*ut a# c*+ple; a# a +eth*d #h*uld e-er 3e) Once a +eth*d ha# +*re than a3*ut #i; c*nditi*nal and iterati*n *perat*r#, it #tart# t* 3ec*+e di99icult t* under#tand the ra+i9icati*n# *9 any change#) -n the 06'$#, the p#ych*l*gi#t >e*rge Ailler pu3li#hed a paper that #aid that ISeven plu# *r +inu# t!*J i# the li+it *9 *ur I#pan *9 a3#*lute 4udg+ent)J Trying t* keep +*re than thi# nu+3er *9 thing# in *ur head at *nce i# very err*rEpr*ne) Luckily, !e have thi# thing called I!ritingJ G*r, in *ur ca#e, c*ding C#H !hich all*!# u# t* 3reak the pr*3le+ *9 Ia3#*lute 4udg+entJ int* #ucce##ive #u3Epr*3le+#, !hich can then 3e treated a# unit# 9*r the purp*#e *9 +aking higherElevel 4udg+ent#) S*und# like c*+puter pr*gra++ing t* +eK GThe paper p*int# *ut that 3y increa#ing the di+en#i*n *9 vi#ual varia3le#, !e can achieve a#t*ni#hing level# *9 di#cri+inati*n a# !e d*, #ay, !hen !e rec*gni7e a 9riend !eve n*t #een in year# !hile ru#hing thr*ugh an airp*rt) -t# intere#ting t* n*te that c*+puter pr*gra++ing hardly leverage# thi# capacity at all) :*u can read the paper, !hich anticipate# e;actly the #*rt *9 thinking and ch*iceE+aking c*++*n t* pr*gra++ing, at http1<<!!!)!ell)c*+<u#er<#+alin<+iller)ht+lH -n C#, goto can 3e u#ed t* 4u+p !ithin a +eth*d t* a la3el) = la3el i# an identi9ier 9*ll*!ed 3y a c*l*n, like thi#1 a$e ": =lth*ugh it# legal t* place a la3el any!here in a +eth*d, the *nly place !here it# a g**d idea i# right 3e9*re an iterati*n #tate+ent) =nd the #*le rea#*n t* put a la3el 3e9*re an iterati*n i# i9 y*ure g*ing t* ne#t an*ther iterati*n *r a #!itch in#ide it) That# 3ecau#e !hile brea( and continue interrupt *nly the l**p that c*ntain# the+, goto can interrupt the l**p#
14(
Thinking in C
www.ThinkingIn.!et
up t* !here the la3el e;i#t#) Here i# an e;a+ple *9 the u#e and a3u#e *9 goto1 //:c0T:_oto.c# // O#ing _oto u#ing Sy#te!3 pu$ ic c a## _oto ; pu$ ic #tatic *oid Gain01 ; int i 9 03 Rando! rand 9 ne. Rando!013 outer: //La$e $efore iterator for03 true 31 ; // infinite oop prt0&-rior to entering inner oop&13 inner: // )nother a$e for03 i W "03 iRR1 ; prt0&i 9 & R i13 if0i 99 F1 ; prt0&goto outer&13 iRR3 // Other.i#e i ne*er // get# incre!ented. goto outer3 < if0i 99 I1 ; prt0&goto inner&13 iRR3 //Other.i#e i ne*er //get# incre!ented goto inner3 < dou$ e d 9 rand.Cext:ou$ e013 if0i 99 > @@ d W 0.?1; prt0&Lega 2 $ut terri$ e&13 goto $ad5dea3 < prt0&Bac% in the oop&13 if0i 99 >1 goto $u#tOut3 < < $u#tOut: prt0&+xit oop&13
141
if0rand.Cext:ou$ e01 W 0.P1; goto #paghetti`u!p3 < $ad5dea: prt0&Uo. did 5 get hereY&13 goto outer3 #paghetti`u!p: prt0&:on't e*er2 e*er do thi#.&13 < #tatic *oid prt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 < < ///:8 Thing# #tart *ut appr*priately en*ugh, !ith the la3eling *9 the t!* l**p# a# outer and inner) =9ter c*unting t* % and getting lulled int* a 9al#e #en#e *9 #ecurity, c*ntr*l 4u+p# *ut *9 3*th l**p#, and reEenter# 9*ll*!ing the outer la3el) On the ne;t l**p, c*ntr*l 4u+p# t* the inner la3el) Then thing# get !eird1 i9 the rand*+ nu+3er generat*r c*+e# up !ith a value le## than $)., c*ntr*l 4u+p# d*!n!ard#, t* the la3el +arked badBdea, the +eth*d print# IH*! did - get hereFJ and then 4u+p# all the !ay 3ack t* the outer la3el) On the ne;t run thr*ugh the inner l**p, i i# #till eDual t* 6 3ut, eventually, the rand*+ nu+3er generat*r !ill c*+e up !ith a value that !ill #kip the 4u+p t* badBdea and print that !ere I3ack in the l**p)J Then, in#tead *9 u#ing the for #tate+ent# ter+inating c*nditi*n, !e decide that !ere g*ing t* 4u+p t* the bust1ut la3el) ,e d* the pr*gra++atic eDuivalent *9 9lipping a c*in and either I9all thr*ughJ int* the badBdea area G!hich, *9 c*ur#e, 4u+p# u# 3ack t* outerH *r 4u+p t* the spaghettiXump la3el) S* !hy i# thi# c*de c*n#idered #* terri3leF 5*r *ne thing, it ha# a high cycl*+atic c*+ple;ity P it# 4u#t plain c*n9u#ing) =l#*, n*te h*! +uch harder it i# t* under#tand pr*gra+ 9l*! !hen *ne cant rely *n 3racket# and indenting) =nd t* +ake thing# !*r#e, let# #ay y*u !ere de3ugging thi# c*de and y*u placed a 3reakp*int at the line prt0AUo. did 5 get hereYB1. ,hen the 3reakp*int i# reached, there i# n* !ay, #h*rt *9 e;a+ining the *utput, 9*r y*u t* deter+ine !hether y*u reached it 9r*+ the 4u+p 9r*+ the inner l**p *r 9r*+ 9alling thr*ugh 9r*+ the i++ediately preceding line# Gin thi# ca#e, the pr*gra+# *utput i#
14)
Thinking in C
www.ThinkingIn.!et
#u99icient t* thi# cau#e, 3ut in the real !*rld *9 c*+ple; #y#te+#, >U-#, and ,e3 Service#, it never i#H) =# ?i4k#tra put it, Iit 3ec*+e# terri3ly hard t* 9ind a +eaning9ul #et *9 c**rdinate# in !hich t* de#cri3e the pr*ce## pr*gre##)J By Ic**rdinate#J ?i4k#tra +eant a !ay t* kn*! the path 3y !hich a #y#te+ arrived in it# current #tate) -t# *nly !ith #uch a path in hand that *ne can de3ug, #ince challenging de9ect# *nly 3ec*+e apparent #*+eti+e a$ter the +i#take ha# 3een +ade) G-t i#, *9 c*ur#e, c*++*n t* +ake +i#take# i++ediately *r 4u#t 3e9*re the pr*3le+ 3ec*+e# apparent, 3ut #uch +i#take# arent hard t* r**t *ut and c*rrect)H ?i4k#tra !ent *n t* #ay that hi# critici#+ !a# n*t 4u#t a3*ut goto, 3ut that all language c*n#truct# Ishould satis$4 the re8uirement that a "rogrammer inde"endent coordinate s4stem can 2e maintained to descri2e the "rocess in a hel"$ul and managea2le wa4.< ,ell revi#it thi# c*ncern !hen #peaking *9 the !ay that C# and the ) ET 9ra+e!*rk handle e;cepti*n# G*3eying the reDuire+entH and threading G!hich d*e#nt *3ey the reDuire+ent, 3ut c*uldH)
'witch
The switch i# #*+eti+e# cla##i9ied a# a selection statement) The switch #tate+ent #elect# 9r*+ a+*ng piece# *9 c*de 3a#ed *n the value *9 an integral e;pre##i*n) -t# 9*r+ i#1 switch(integra 6#e ector) { case integra 6*a ue" : #tate!ent; break; case integra 6*a ue2 : #tate!ent; return; case integra 6*a ueT : #tate!ent; continue; case integra 6*a ueE : #tate!ent; throw exception; case integra 6*a ueP : #tate!ent; goto externa 6 a$e ; case integra 6*a ue? : //Co #tate!ent# case integra 6*a ueF : #tate!ent3 goto case integra 6*a ue3 // ... default: #tate!ent; break; <
143
Integral9selector i# an e;pre##i*n that pr*duce# an integral value) The switch c*+pare# the re#ult *9 integral9selector t* each integral9-alue) -9 it 9ind# a +atch, the c*rre#p*nding statement G#i+ple *r c*+p*undH e;ecute#) -9 n* +atch *ccur#, the default statement e;ecute#) :*u !ill n*tice in the a3*ve de9initi*n that each case end# !ith #*+e kind *9 4u+p #tate+ent) The 9ir#t *ne #h*!n, brea(, i# 3y 9ar the +*#t c*++*nly u#ed) *te that goto can 3e u#ed in 3*th the 9*r+ di#cu##ed previ*u#ly, !hich 4u+p# t* an ar3itrary la3el in the encl*#ing #tate+ent 3l*ck, and in a ne! 9*r+, goto case, !hich tran#9er# c*ntr*l t* the #peci9ied ca#e 3l*ck) Unlike "ava and C@@, each ca#e 3l*ck, including the de9ault 3l*ck, +u#t end in a 4u+p #tate+ent) There i# n* I9allEthr*ugh,J alth*ugh #elect*r# +ay i++ediately precede *ther #elect*r#) -n the de9initi*n, thi# i# #een at the #elect*r 9*r integralEvalue., !hich !ill e;ecute the #tate+ent# in integralEvalue%# ca#e 3l*ck) The switch #tate+ent i# a clean !ay t* i+ple+ent +ultiE!ay #electi*n Gi)e), #electing 9r*+ a+*ng a nu+3er *9 di99erent e;ecuti*n path#H, 3ut it reDuire# a #elect*r that evaluate# t* a prede9ined type #uch a# int, char, *r string, *r t* an enu+erati*n) 5*r *ther type#, y*u +u#t u#e either a #erie# *9 if #tate+ent#, *r i+ple+ent #*+e kind *9 c*nver#i*n t* *ne *9 the #upp*rted type#) A*re generally, a !ellEde#igned *34ectE*riented pr*gra+ !ill generally +*ve a l*t *9 c*ntr*l #!itching a!ay 9r*+ e;plicit te#t# in c*de int* p*ly+*rphi#+ G!hich !ell get t* in #H Here# an e;a+ple that create# letter# rand*+ly and deter+ine# !hether theyre v*!el# *r c*n#*nant#1 //:c0T: No.e #)ndCon#onant#.c# /// :e!on#trate# the #.itch #tate!ent. na!e#pace c0T; u#ing Sy#te!3 pu$ ic c a## No.e #)ndCon#onant# ; pu$ ic #tatic *oid Gain01 ; Rando! rand 9 ne. Rando!013 for0int i 9 03 i W "003 iRR1 ; char c 9 0char10rand.Cext0'a'2'M'113
144
Thinking in C
www.ThinkingIn.!et
Sy#te!.Con#o e.VriteLine0c R &: &13 #.itch0c1 ; ca#e 'a': ca#e 'e': ca#e 'i': ca#e 'o': ca#e 'u': Sy#te!.Con#o e.VriteLine0&*o.e &13 $rea%3 ca#e 'y': ca#e '.': Sy#te!.Con#o e.VriteLine0 &So!eti!e# a *o.e &13 $rea%3 defau t: Sy#te!.Con#o e.VriteLine0&con#onant&13 $rea%3 < < < < <///:8 Since char# can 3e i+plicitly pr*+*ted t* int#, Rand*+) e;tGint l*!erB*und, int upperB*undH can 3e u#ed t* return value# in the appr*priate =SC-- range)
Calculation details
TH-S -S N- ? O5 - TEREST- > STU55 BUT -S OT RELEC= T TO THE =BOCE) AOCE ELSE,HEREF RE,R-TE TEBT
The #tate+ent1 char c 9 0char10Gath.rando!01 = 2? R 'a'13 de#erve# a cl*#er l**k) .ath6random( ) pr*duce# a double, #* the value 2. i# c*nverted t* a double t* per9*r+ the +ultiplicati*n, !hich
145
al#* pr*duce# a double) Thi# +ean# that 2a5 +u#t 3e c*nverted t* a double t* per9*r+ the additi*n) The double re#ult i# turned 3ack int* a char !ith a ca#t) ,hat d*e# the ca#t t* char d*F That i#, i9 y*u have the value 26)% and y*u ca#t it t* a char, i# the re#ulting value /$ *r 26F The an#!er t* thi# can 3e #een in thi# e;a+ple1 //:c0T:Ca#tingCu!$er#.c# na!e#pace c0T; u#ing Sy#te!3 // Vhat happen# .hen you ca#t a f oat // or dou$ e to an integra *a ueY pu$ ic c a## Ca#tingCu!$er# ; pu$ ic #tatic *oid Gain01 ; dou$ e a$o*e 9 0.F2 $e o. 9 0.E3 Sy#te!.Con#o e.VriteLine0&a$o*e: & R a$o*e13 Sy#te!.Con#o e.VriteLine0&$e o.: & R $e o.13 Sy#te!.Con#o e.VriteLine0 &0int1a$o*e: & R 0int1a$o*e13 Sy#te!.Con#o e.VriteLine0 &0int1$e o.: & R 0int1$e o.13 Sy#te!.Con#o e.VriteLine0 &0char10'a' R a$o*e1: & R 0char10'a' R a$o*e113 Sy#te!.Con#o e.VriteLine0 &0char10'a' R $e o.1: & R 0char10'a' R $e o.113 < <
146
Thinking in C
www.ThinkingIn.!et
<///:8 The *utput i#1 a$o*e: 0.F $e o.: 0.E 0int1a$o*e: 0 0int1$e o.: 0 0char10'a' R a$o*e1: a 0char10'a' R $e o.1: a S* the an#!er i# that ca#ting 9r*+ a float *r double t* an integral value al!ay# truncate#) = #ec*nd Due#ti*n c*ncern# .ath6random( )) ?*e# it pr*duce a value 9r*+ 7er* t* *ne, inclu#ive *r e;clu#ive *9 the value T0F -n +ath ling*, i# it G$,0H, *r Z$,0\, *r G$,0\ *r Z$,0HF GThe #Duare 3racket +ean# Iinclude#J !herea# the parenthe#i# +ean# Id*e#nt include)JH =gain, a te#t pr*gra+ +ight pr*vide the an#!er1 //:c0T:Rando!Bound#.c# na!e#pace c0T; u#ing Sy#te!3 // :oe# Rando!.Cext01 produce 0 and 5ntT2.GaxXNa ueY pu$ ic c a## Rando!Bound# ; #tatic *oid u#age01 ; Sy#te!.Con#o e.VriteLine0&O#age: ^n^t& R &Rando!Bound# o.er^n^t& R &Rando!Bound# upper^n^t& R &Rando!Bound# $ounded&13 +n*iron!ent.+xit0"13 < pu$ ic #tatic *oid Gain0#tringJK arg#1 ; if 0arg#.Length !9 "1 u#age013 Rando! rand 9 ne. Rando!013 if 0arg#J0K 99 & o.er&1 ; .hi e 0rand.Cext01 !9 01 3 // aeep trying
14#
Sy#te!.Con#o e.VriteLine0&-roduced 0!&13 < e #e if 0arg#J0K 99 &upper&1 ; .hi e 0rand.Cext01 !9 5ntT2.GaxNa ue1 3 // aeep trying Sy#te!.Con#o e.VriteLine0&-roduced & R 5ntT2.GaxNa ue13 < e #e if 0arg#J0K 99 &$ounded&1 ; $oo foundLo.erBound 9 fa #e3 $oo foundOpperBound 9 fa #e3 do ; int $ounded 9 rand.Cext002 "013 if 0$ounded 99 01 ; Sy#te!.Con#o e.VriteLine0&Hound o.er $ound!&13 foundLo.erBound 9 true3 < if 0$ounded 99 "01 ; Sy#te!.Con#o e.VriteLine0&Hound upper $ound!&13 foundOpperBound 9 true3 < <.hi e 0!foundLo.erBound SS ! foundOpperBound13 < e #e u#age013 < < < ///:8 T* run the pr*gra+, y*u type a c*++and line *9 either1 Rando!Bound# *r Rando!Bound# upper -n 3*th ca#e# y*u are 9*rced t* 3reak *ut *9 the pr*gra+ +anually, #* it !*uld appear that Aath)rand*+G H never pr*duce# either $)$ *r 0)$) But o.er
14&
Thinking in C
www.ThinkingIn.!et
thi# i# !here #uch an e;peri+ent can 3e deceiving) -9 y*u c*n#ider 2 that there are a3*ut 2.2 di99erent d*u3le 9racti*n# 3et!een $ and 0, the likelih**d *9 reaching any *ne value e;peri+entally +ight e;ceed the li9eti+e *9 *ne c*+puter, *r even *ne e;peri+enter) -t turn# *ut that $)$ i# included in the *utput *9 Aath)rand*+G H) Or, in +ath ling*, it i# Z$,0H)
'u##ar5
Thi# chapter c*nclude# the #tudy *9 9unda+ental 9eature# that appear in +*#t pr*gra++ing language#1 calculati*n, *perat*r precedence, type ca#ting, and #electi*n and iterati*n) *! y*ure ready t* 3egin taking #tep# that +*ve y*u cl*#er t* the !*rld *9 *34ectE*riented pr*gra++ing) The ne;t chapter !ill c*ver the i+p*rtant i##ue# *9 initiali7ati*n and cleanup *9 *34ect#, 9*ll*!ed in the #u3#eDuent chapter 3y the e##ential c*ncept *9 i+ple+entati*n hiding)
%&ercises
2 Chuck =lli#*n !rite#1 The t*tal nu+3er *9 nu+3er# in a 9l*atingEp*int nu+3er #y#te+ i#
8(.-mC7)bN(p-7) C 7 !here b i# the 3a#e Gu#ually 2H, p i# the preci#i*n Gdigit# in the +anti##aH, . i# the large#t e;p*nent, and m i# the #+alle#t e;p*nent) -EEE %'& u#e#1 . I 7489, m I -7488, p I Y9, b I 8 #* the t*tal nu+3er *9 nu+3er# i# 8(7489C7488C7)8NY8 I 8((8N74-7) C (8N74-7))8NY8 I (8N74-7)8NYJ I 8NZJ - 8NYJ Hal9 *9 the#e nu+3er# Gc*rre#p*nding t* e;p*nent# in the range ZE0$22, $\H are le## than 0 in +agnitude G3*th p*#itive and negativeH, #* 0<& *9 that e;pre##i*n, *r 2_.2 E 2_'2 @ 0 Gappr*;i+ately 2_.2H i# in the range Z$,0H) See +y paper at http1<<!!!)9re#h#*urce#)c*+<066'$$.a)ht+ Gla#t *9 te;tH)
14'
!, Initiali:ation I Cleanu$
=# the c*+puter rev*luti*n pr*gre##e#, Iun#a9eJ pr*gra++ing ha# 3ec*+e *ne *9 the +a4*r culprit# that +ake# pr*gra++ing e;pen#ive)
T!* *9 the#e #a9ety i##ue# are initiali;ation and cleanu") Aany C 3ug# *ccur !hen the pr*gra++er 9*rget# t* initiali7e a varia3le) Thi# i# e#pecially true !ith li3rarie# !hen u#er# d*nt kn*! h*! t* initiali7e a li3rary c*+p*nent, *r even that they +u#t) Cleanup i# a #pecial pr*3le+ 3ecau#e it# ea#y t* 9*rget a3*ut an ele+ent !hen y*ure d*ne !ith it, #ince it n* l*nger c*ncern# y*u) Thu#, the re#*urce# u#ed 3y that ele+ent are retained and y*u can ea#ily end up running *ut *9 re#*urce# G+*#t n*ta3ly, +e+*ryH) C@@ intr*duced the c*ncept *9 a constructor and a destructor, #pecial +eth*d# aut*+atically called !hen an *34ect i# created and de#tr*yed) C# ha# the#e 9acilitie#, and in additi*n ha# a gar3age c*llect*r that aut*+atically relea#e# +e+*ry re#*urce# !hen theyre n* l*nger 3eing u#ed) Thi# chapter e;a+ine# the i##ue# *9 initiali7ati*n and cleanup, and their #upp*rt in C#)
151
created, 3e9*re u#er# can even get their hand# *n it) S* initiali7ati*n i# guaranteed) The ne;t challenge i# !hat t* na+e thi# +eth*d) There are t!* i##ue#) The 9ir#t i# that any na+e y*u u#e c*uld cla#h !ith a na+e y*u +ight like t* u#e a# a +e+3er in the cla##) The #ec*nd i# that 3ecau#e the c*+piler i# re#p*n#i3le 9*r calling the c*n#truct*r, it +u#t al!ay# kn*! !hich +eth*d t* call) The C@@ #*luti*n #ee+# the ea#ie#t and +*#t l*gical, #* it# al#* u#ed in C#1 the na+e *9 the c*n#truct*r i# the #a+e a# the na+e *9 the cla##) -t +ake# #en#e that #uch a +eth*d !ill 3e called aut*+atically *n initiali7ati*n) Here# a #i+ple cla## !ith a c*n#truct*r1 //:c0E:Si!p eCon#tructor.c# na!e#pace c0E; u#ing Sy#te!3 // :e!on#tration of a #i!p e con#tructor. c a## Roc% ; pu$ ic Roc%01 ; // 'hi# i# the con#tructor Sy#te!.Con#o e.VriteLine0&Creating Roc%&13 < < pu$ ic c a## Si!p eCon#tructor ; pu$ ic #tatic *oid Gain01 ; for0int i 9 03 i W "03 iRR1 ne. Roc%013 < < <///:8 *!, !hen an *34ect i# created1 ne. Roc%013 #t*rage i# all*cated and the c*n#truct*r i# called) -t i# guaranteed that the *34ect !ill 3e pr*perly initiali7ed 3e9*re y*u can get y*ur hand# *n it) *te that the na+e *9 the c*n#truct*r +u#t +atch the na+e *9 the cla## e%actl4)
15)
Like any +eth*d, the c*n#truct*r can have argu+ent# t* all*! y*u t* #peci9y how an *34ect i# created) The a3*ve e;a+ple can ea#ily 3e changed #* the c*n#truct*r take# an argu+ent1 //:c0E:Si!p eCon#trutor2.c# na!e#pace c0E; u#ing Sy#te!3 // :e!on#tration of a #i!p e con#tructor. c a## Roc%2 ; pu$ ic Roc%20int i1 ; // 'hi# i# the con#tructor Sy#te!.Con#o e.VriteLine0&Creating Roc% nu!$er: & R i13 < < pu$ ic c a## Si!p eCon#tructor ; pu$ ic #tatic *oid Gain01 ; for0int i 9 03 i W "03 iRR1 ne. Roc%20i13 < < <///:8 C*n#truct*r argu+ent# pr*vide y*u !ith a !ay t* pr*vide para+eter# 9*r the initiali7ati*n *9 an *34ect) 5*r e;a+ple, i9 the cla## +ree ha# a c*n#truct*r that take# a #ingle integer argu+ent den*ting the height *9 the tree, y*u !*uld create a +ree *34ect like thi#1 'ree t 9 ne. 'ree0"213 // "26foot tree
-9 +ree(int) i# y*ur *nly c*n#truct*r, then the c*+piler !*nt let y*u create a +ree *34ect any *ther !ay) C*n#truct*r# eli+inate a large cla## *9 pr*3le+# and +ake the c*de ea#ier t* read) -n the preceding c*de 9rag+ent, 9*r e;a+ple, y*u d*nt #ee an e;plicit call t* #*+e initialiTe( ) +eth*d that i# c*nceptually #eparate 9r*+ de9initi*n) -n C#, de9initi*n and initiali7ati*n are uni9ied c*ncept#R y*u cant have *ne !ith*ut the *ther) The c*n#truct*r i# an unu#ual type *9 +eth*d 3ecau#e it ha# n* return value) Thi# i# di#tinctly di99erent 9r*+ a void return value, in !hich the
153
+eth*d return# n*thing 3ut y*u #till have the *pti*n t* +ake it return #*+ething el#e) C*n#truct*r# return n*thing and y*u d*nt have an *pti*n) -9 there !a# a return value, and i9 y*u c*uld #elect y*ur *!n, the c*+piler !*uld #*+eh*! need t* kn*! !hat t* d* !ith that return value) =ccidentally typing a return type #uch a# void 3e9*re declaring a +eth*d i# a c*++*n thing t* d* *n a A*nday +*rning, 3ut the C# c*+piler !*nt all*! it, telling y*u I+e+3er na+e# cann*t 3e the #a+e a# their encl*#ing type)J
@ethod overloading
One *9 the i+p*rtant 9eature# in any pr*gra++ing language i# the u#e *9 na+e#) ,hen y*u create an *34ect, y*u give a na+e t* a regi*n *9 #t*rage) = +eth*d i# a na+e 9*r an acti*n) By u#ing na+e# t* de#cri3e y*ur #y#te+, y*u create a pr*gra+ that i# ea#ier 9*r pe*ple t* under#tand and change) -t# a l*t like !riting pr*#eRthe g*al i# t* c*++unicate !ith y*ur reader#) :*u re9er t* all *34ect# and +eth*d# 3y u#ing na+e#) ,ellEch*#en na+e# +ake it ea#ier 9*r y*u and *ther# t* under#tand y*ur c*de) = pr*3le+ ari#e# !hen +apping the c*ncept *9 nuance in hu+an language *nt* a pr*gra++ing language) O9ten, the #a+e !*rd e;pre##e# a nu+3er *9 di99erent +eaning#Rit# o-erloaded) Thi# i# u#e9ul, e#pecially !hen it c*+e# t* trivial di99erence#) :*u #ay I!a#h the #hirt,J I!a#h the car,J and I!a#h the d*g)J -t !*uld 3e #illy t* 3e 9*rced t* #ay, I#hirt,a#h the #hirt,J Icar,a#h the car,J and Id*g,a#h the d*gJ 4u#t #* the li#tener d*e#nt need t* +ake any di#tincti*n a3*ut the acti*n per9*r+ed) A*#t hu+an language# are redundant, #* even i9 y*u +i## a 9e! !*rd#, y*u can #till deter+ine the +eaning) ,e d*nt need uniDue identi9ier#R!e can deduce +eaning 9r*+ c*nte;t) A*#t pr*gra++ing language# GC in particularH reDuire y*u t* have a uniDue identi9ier 9*r each 9uncti*n) S* y*u c*uld n*t have *ne 9uncti*n called print( ) 9*r printing integer# and an*ther called print( ) 9*r printing 9l*at#Reach 9uncti*n reDuire# a uniDue na+e) -n C# and *ther language# in the C@@ 9a+ily, an*ther 9act*r 9*rce# the *verl*ading *9 +eth*d na+e#1 the c*n#truct*r) Becau#e the c*n#truct*r#
154
Thinking in C
www.ThinkingIn.!et
na+e i# predeter+ined 3y the na+e *9 the cla##, there can 3e *nly *ne c*n#truct*r na+e) But !hat i9 y*u !ant t* create an *34ect in +*re than *ne !ayF 5*r e;a+ple, #upp*#e y*u 3uild a cla## that can initiali7e it#el9 in a #tandard !ay *r 3y reading in9*r+ati*n 9r*+ a 9ile) :*u need t!* c*n#truct*r#, *ne that take# n* argu+ent# Gthe de$ault c*n#truct*r, al#* called the no9arg c*n#truct*rH, and *ne that take# a string a# an argu+ent, !hich i# the na+e *9 the 9ile 9r*+ !hich t* initiali7e the *34ect) B*th are c*n#truct*r#, #* they +u#t have the #a+e na+eRthe na+e *9 the cla##) Thu#, method o-erloading i# e##ential t* all*! the #a+e +eth*d na+e t* 3e u#ed !ith di99erent argu+ent type#) =nd alth*ugh +eth*d *verl*ading i# a +u#t 9*r c*n#truct*r#, it# a general c*nvenience and can 3e u#ed !ith any +eth*d) Here# an e;a+ple that #h*!# 3*th *verl*aded c*n#truct*r# and *verl*aded *rdinary +eth*d#1 //:c0E:O*erLoading.c# // :e!on#tration of $oth con#tructor // and ordinary !ethod o*er oading. u#ing Sy#te!3 c a## 'ree ; int height3 pu$ ic 'ree01 ; -rt0&- anting a #eed ing&13 height 9 03 < pu$ ic 'ree0int i1 ; -rt0&Creating ne. 'ree that i# & R i R & feet ta &13 height 9 i3 < interna *oid 5nfo01 ; -rt0&'ree i# & R height R & feet ta &13 < interna *oid 5nfo0#tring #1 ; -rt0# R &: 'ree i# & R height R & feet ta &13 <
155
#tatic *oid -rt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 < < pu$ ic c a## O*er oading ; pu$ ic #tatic *oid Gain01 ; for0int i 9 03 i W P3 iRR1 ; 'ree t 9 ne. 'ree0i13 t.5nfo013 t.5nfo0&o*er oaded !ethod&13 < // O*er oaded con#tructor: ne. 'ree013 < < ///:8 = +ree *34ect can 3e created either a# a #eedling, !ith n* argu+ent, *r a# a plant gr*!n in a nur#ery, !ith an e;i#ting height) T* #upp*rt thi#, there are t!* c*n#truct*r#, *ne that take# n* argu+ent# G!e call c*n#truct*r# that take n* argu+ent# de$ault constructors0H and *ne that take# the e;i#ting height) :*u +ight al#* !ant t* call the info( ) +eth*d in +*re than *ne !ay) 5*r e;a+ple, !ith a string argu+ent i9 y*u have an e;tra +e##age y*u !ant printed, and !ith*ut i9 y*u have n*thing +*re t* #ay) -t !*uld #ee+ #trange t* give t!* #eparate na+e# t* !hat i# *3vi*u#ly the #a+e c*ncept) 5*rtunately, +eth*d *verl*ading all*!# y*u t* u#e the #a+e na+e 9*r 3*th)
0 S*+eti+e# the#e c*n#truct*r# are de#cri3ed !ith the clu+#y 3ut th*r*ugh na+e In*Earg
c*n#truct*r#)J The ter+ Ide9ault c*n#truct*rJ ha# 3een in u#e 9*r +any year# and #* - !ill u#e that)
156
Thinking in C
www.ThinkingIn.!et
-9 y*u think a3*ut thi# 9*r a #ec*nd, it +ake# #en#e1 h*! el#e c*uld a pr*gra++er tell the di99erence 3et!een t!* +eth*d# that have the #a+e na+e, *ther than 3y the type# *9 their argu+ent#F Even di99erence# in the *rdering *9 argu+ent# are #u99icient t* di#tingui#h t!* +eth*d#1 G=lth*ugh y*u d*nt n*r+ally !ant t* take thi# appr*ach, a# it pr*duce# di99icultEt*E+aintain c*de)H //:c0E:O*erLoadingOrder.c# // O*er oading $a#ed on the order of // the argu!ent#. pu$ ic c a## O*er oadingOrder ; #tatic *oid print0#tring #2 int i1 ; Sy#te!.Con#o e.VriteLine0 &#tring: & R # R &2 int: & R i13 < #tatic *oid print0int i2 #tring #1 ; Sy#te!.Con#o e.VriteLine0 &int: & R i R &2 #tring: & R #13 < pu$ ic #tatic *oid Gain01 ; print0&#tring fir#t&2 ""13 print0>>2 &5nt fir#t&13 < < ///:8 The t!* print( ) +eth*d# have identical argu+ent#, 3ut the *rder i# di99erent, and that# !hat +ake# the+ di#tinct)
15#
pu$ ic c a## -ri!iti*eO*er oading ; // $oo ean can't $e auto!atica y con*erted #tatic *oid -rt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 < *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid H"0char x1 ; -rt0&H"0char1&13 < H"0$yte x1 ; -rt0&H"0$yte1&13 < H"0#hort x1 ; -rt0&H"0#hort1&13 < H"0int x1 ; -rt0&H"0int1&13 < H"0 ong x1 ; -rt0&H"0 ong1&13 < H"0f oat x1 ; -rt0&H"0f oat1&13 < H"0dou$ e x1 ; -rt0&H"0dou$ e1&13 < H20$yte x1 ; -rt0&H20$yte1&13 < H20#hort x1 ; -rt0&H20#hort1&13 < H20int x1 ; -rt0&H20int1&13 < H20 ong x1 ; -rt0&H20 ong1&13 < H20f oat x1 ; -rt0&H20f oat1&13 < H20dou$ e x1 ; -rt0&H20dou$ e1&13 < HT0#hort x1 ; -rt0&HT0#hort1&13 < HT0int x1 ; -rt0&HT0int1&13 < HT0 ong x1 ; -rt0&HT0 ong1&13 < HT0f oat x1 ; -rt0&HT0f oat1&13 < HT0dou$ e x1 ; -rt0&HT0dou$ e1&13 < HE0int x1 ; -rt0&HE0int1&13 < HE0 ong x1 ; -rt0&HE0 ong1&13 < HE0f oat x1 ; -rt0&HE0f oat1&13 < HE0dou$ e x1 ; -rt0&HE0dou$ e1&13 <
*oid HP0 ong x1 ; -rt0&HP0 ong1&13 < *oid HP0f oat x1 ; -rt0&HP0f oat1&13 < *oid HP0dou$ e x1 ; -rt0&HP0dou$ e1&13 < *oid H?0f oat x1 ; -rt0&H?0f oat1&13 < *oid H?0dou$ e x1 ; -rt0&H?0dou$ e1&13 < *oid HF0dou$ e x1 ; -rt0&HF0dou$ e1&13 <
15&
Thinking in C
www.ThinkingIn.!et
*oid 'e#tCon#tNa 01 ; -rt0&'e#ting .ith P&13 H"0P13H20P13HT0P13HE0P13HP0P13H?0P13HF0P13 < *oid 'e#tChar01 ; char x 9 'x'3 -rt0&char argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < *oid 'e#tByte01 ; $yte x 9 03 -rt0&$yte argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < *oid 'e#tShort01 ; #hort x 9 03 -rt0&#hort argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < *oid 'e#t5nt01 ; int x 9 03 -rt0&int argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < *oid 'e#tLong01 ; ong x 9 03 -rt0& ong argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < *oid 'e#tH oat01 ; f oat x 9 03 -rt0&H oat argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < *oid 'e#t:ou$ e01 ; dou$ e x 9 03 -rt0&dou$ e argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < pu$ ic #tatic *oid Gain01 ; -ri!iti*eO*er oading p 9
15'
ne. -ri!iti*eO*er oading013 p.'e#tCon#tNa 013 p.'e#tChar013 p.'e#tByte013 p.'e#tShort013 p.'e#t5nt013 p.'e#tLong013 p.'e#tH oat013 p.'e#t:ou$ e013 < < ///:8 -9 y*u vie! the *utput *9 thi# pr*gra+, y*ull #ee that the c*n#tant value ' i# treated a# an int, #* i9 an *verl*aded +eth*d i# availa3le that take# an int it i# u#ed) -n all *ther ca#e#, i9 y*u have a data type that i# #+aller than the argu+ent in the +eth*d, that data type i# pr*+*ted) char pr*duce# a #lightly di99erent e99ect, #ince i9 it d*e#nt 9ind an e;act char +atch, it i# pr*+*ted t* int) ,hat happen# i9 y*ur argu+ent i# 2igger than the argu+ent e;pected 3y the *verl*aded +eth*dF = +*di9icati*n *9 the a3*ve pr*gra+ give# the an#!er1 //:c0E::e!otion.c# // :e!otion of pri!iti*e# and o*er oading. pu$ ic c a## :e!otion ; #tatic *oid -rt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 < *oid *oid *oid *oid *oid *oid *oid H"0char x1 ; -rt0&H"0char1&13 < H"0$yte x1 ; -rt0&H"0$yte1&13 < H"0#hort x1 ; -rt0&H"0#hort1&13 < H"0int x1 ; -rt0&H"0int1&13 < H"0 ong x1 ; -rt0&H"0 ong1&13 < H"0f oat x1 ; -rt0&H"0f oat1&13 < H"0dou$ e x1 ; -rt0&H"0dou$ e1&13 <
*oid H20char x1 ; -rt0&H20char1&13 < *oid H20$yte x1 ; -rt0&H20$yte1&13 < *oid H20#hort x1 ; -rt0&H20#hort1&13 <
16(
Thinking in C
www.ThinkingIn.!et
*oid H20int x1 ; -rt0&H20int1&13 < *oid H20 ong x1 ; -rt0&H20 ong1&13 < *oid H20f oat x1 ; -rt0&H20f oat1&13 < *oid *oid *oid *oid *oid *oid *oid *oid *oid HT0char x1 ; -rt0&HT0char1&13 < HT0$yte x1 ; -rt0&HT0$yte1&13 < HT0#hort x1 ; -rt0&HT0#hort1&13 < HT0int x1 ; -rt0&HT0int1&13 < HT0 ong x1 ; -rt0&HT0 ong1&13 < HE0char x1 ; -rt0&HE0char1&13 < HE0$yte x1 ; -rt0&HE0$yte1&13 < HE0#hort x1 ; -rt0&HE0#hort1&13 < HE0int x1 ; -rt0&HE0int1&13 <
*oid HP0char x1 ; -rt0&HP0char1&13 < *oid HP0$yte x1 ; -rt0&HP0$yte1&13 < *oid HP0#hort x1 ; -rt0&HP0#hort1&13 < *oid H?0char x1 ; -rt0&H?0char1&13 < *oid H?0$yte x1 ; -rt0&H?0$yte1&13 < *oid HF0char x1 ; -rt0&HF0char1&13 < *oid 'e#t:ou$ e01 ; dou$ e x 9 03 -rt0&dou$ e argu!ent:&13 H"0x13H200f oat1x13HT00 ong1x13HE00int1x13 HP00#hort1x13H?00$yte1x13HF00char1x13 < pu$ ic #tatic *oid Gain01 ; :e!otion p 9 ne. :e!otion013 p.'e#t:ou$ e013 < < ///:8 Here, the +eth*d# take narr*!er pri+itive value#) -9 y*ur argu+ent i# !ider then y*u +u#t cast t* the nece##ary type u#ing the type na+e in parenthe#e#) -9 y*u d*nt d* thi#, the c*+piler !ill i##ue an err*r +e##age)
161
:*u #h*uld 3e a!are that thi# i# a narrowing con-ersion6 !hich +ean# y*u +ight l*#e in9*r+ati*n during the ca#t) Thi# i# !hy the c*+piler 9*rce# y*u t* d* itRt* 9lag the narr*!ing c*nver#i*n)
4e0ault constructors
=# +enti*ned previ*u#ly, a de9ault c*n#truct*r Ga)k)a) a In*EargJ c*n#truct*rH i# *ne !ith*ut argu+ent#, u#ed t* create a Ivanilla *34ect)J -9 y*u create a cla## that ha# n* c*n#truct*r#, the c*+piler !ill aut*+atically create a de9ault c*n#truct*r 9*r y*u) 5*r e;a+ple1 //:c0E::efau tCon#tructor.c# c a## Bird ; int i3 < pu$ ic c a## :efau tCon#tructor ; pu$ ic #tatic *oid Gain01 ; Bird nc 9 ne. Bird013 // defau t!
16)
Thinking in C
www.ThinkingIn.!et
< <///:8 The line ne. Bird013 create# a ne! *34ect and call# the de9ault c*n#truct*r, even th*ugh *ne !a# n*t e;plicitly de9ined) ,ith*ut it !e !*uld have n* +eth*d t* call t* 3uild *ur *34ect) H*!ever, i9 y*u de9ine any c*n#truct*r# G!ith *r !ith*ut argu+ent#H, the c*+piler !ill not #ynthe#i7e *ne 9*r y*u1 c a## Bu#h ; Bu#h0int i1 ;< Bu#h0dou$ e d1 ;< < *! i9 y*u #ay1 ne. Bu#h013 the c*+piler !ill c*+plain that it cann*t 9ind a c*n#truct*r that +atche#) -t# a# i9 !hen y*u d*nt put in any c*n#truct*r#, the c*+piler #ay# I:*u are 3*und t* need some c*n#truct*r, #* let +e +ake *ne 9*r y*u)J But i9 y*u !rite a c*n#truct*r, the c*+piler #ay# I:*uve !ritten a c*n#truct*r #* y*u kn*! !hat y*ure d*ingQ i9 y*u didnt put in a de9ault it# 3ecau#e y*u +eant t* leave it *ut)J
163
+eth*d f( ), and that argu+ent i# the re9erence t* the *34ect that# 3eing +anipulated) S* the t!* +eth*d call# a3*ve 3ec*+e #*+ething like1 Banana.f0a2"13 Banana.f0$2213 Thi# i# internal and y*u cant !rite the#e e;pre##i*n# and get the c*+piler t* interchange the+ !ith a)9GHE#tyle call#, 3ut it give# y*u an idea *9 !hat# happening) Supp*#e y*ure in#ide a +eth*d and y*ud like t* get the re9erence t* the current *34ect) Since that re9erence i# pa##ed secretl4 3y the c*+piler, there# n* identi9ier 9*r it) H*!ever, 9*r thi# purp*#e there# a key!*rd1 this) The this key!*rd pr*duce# a re9erence t* the *34ect the +eth*d ha# 3een called 9*r) :*u can treat thi# re9erence 4u#t like any *ther *34ect re9erence) Neep in +ind that i9 y*ure calling a +eth*d *9 y*ur cla## 9r*+ !ithin an*ther +eth*d *9 y*ur cla##, y*u d*nt need t* u#e thisQ y*u #i+ply call the +eth*d) The current this re9erence i# aut*+atically u#ed 9*r the *ther +eth*d) Thu# y*u can #ay1 c a## )pricot ; int id3 *oid pic%01 ; /= ... =/ < *oid pit01 ; pic%013 id3 /= ... =/ < < -n#ide pit( ), y*u could #ay this6pic(( ) *r this6id 3ut there# n* need t*) The c*+piler d*e# it 9*r y*u aut*+atically) The this key!*rd i# u#ed *nly 9*r th*#e #pecial ca#e# in !hich y*u need t* e;plicitly u#e the re9erence t* the current *34ect) 5*r e;a+ple, it# *9ten u#ed in return #tate+ent# !hen y*u !ant t* return the re9erence t* the current *34ect1 //:c0E:Leaf.c# // Si!p e u#e of the &thi#& %ey.ord. pu$ ic c a## Leaf ; int i 9 03 Leaf 5ncre!ent01 ; iRR3 return thi#3
164
Thinking in C
www.ThinkingIn.!et
< *oid -rint01 ; Sy#te!.Con#o e.VriteLine0&i 9 & R i13 < pu$ ic #tatic *oid Gain01 ; Leaf x 9 ne. Leaf013 x.5ncre!ent01.5ncre!ent01.5ncre!ent01.-rint013 < < ///:8 Becau#e increment( ) return# the re9erence t* the current *34ect via the this key!*rd, +ultiple *perati*n# can ea#ily 3e per9*r+ed *n the #a+e *34ect) =n*ther place !here it# *9ten u#ed i# t* all*! +eth*d para+eter# t* have the #a+e na+e a# in#tance varia3le#) Previ*u#ly, !e talked a3*ut the value *9 *verl*ading +eth*d# #* that the pr*gra++er *nly had t* re+e+3er the *ne, +*#t l*gical na+e) Si+ilarly, the na+e# *9 +eth*d para+eter# and the na+e# *9 in#tance varia3le# +ay al#* have a #ingle l*gical na+e) C# all*!# y*u t* u#e the this re9erence t* di#a+3iguate +eth*d varia3le# Gal#* called I#tack varia3le#JH 9r*+ in#tance varia3le#) 5*r clarity, y*u #h*uld u#e thi# capa3ility *nly !hen the para+eter i# g*ing t* either 3e a##igned t* the in#tance varia3le G#uch a# in a c*n#truct*rH *r !hen the para+eter i# t* 3e c*+pared again#t the in#tance varia3le) Aeth*d varia3le# that have n* c*rrelati*n !ith #a+eE na+ed in#tance varia3le# are a c*++*n #*urce *9 la7y de9ect#1 //:c0E:Ca!e.c# c a## Ca!e; #tring gi*enCa!e3 #tring #urna!e3 pu$ ic Ca!e0#tring gi*enCa!e2 #tring #urna!e1; thi#.gi*enCa!e 9 gi*enCa!e3 thi#.#urna!e 9 #urna!e3 < pu$ ic $oo perhap#Re ated0#tring #urna!e1; return thi#.#urna!e 99 #urna!e3 <
165
pu$ ic *oid print_i*enCa!e01; /= Lega 2 $ut un.i#e =/ #tring gi*enCa!e 9 &!ethod *aria$ e&3 Sy#te!.Con#o e.VriteLine0&gi*enCa!e i#: & R gi*enCa!e13 Sy#te!.Con#o e.VriteLine0&thi#.gi*enCa!e i#: & R thi#.gi*enCa!e13 < pu$ ic #tatic *oid Gain01; Ca!e *an_ogh 9 ne. Ca!e0&Nincent&2 &*an _ogh&13 *an_ogh.print_i*enCa!e013 $oo $ 9 *an_ogh.perhap#Re ated0&*an _ogh&13 if0$1; Sy#te!.Con#o e.VriteLine0&Ue'# a *an _ogh.&13 < < <///:8 -n the c*n#truct*r, the para+eter# given,ame and surname are a##igned t* the #i+ilarlyEna+ed in#tance varia3le# and thi# i# Duite appr*priate P calling the para+eter# in iven,ame and in#urname G*r !*r#e, u#ing para+eter na+e# #uch a# first,ame *r last,ame that d* n*t c*rre#p*nd t* the in#tance varia3le#H !*uld reDuire e;plaining in the d*cu+entati*n) The perhaps*elated() +eth*d #h*!# the *ther appr*priate u#e P the surname pa##ed in i# t* 3e c*+pared t* the in#tance# surname) Un9*rtunately, the u#age in print iven,ame() i# al#* legal) Here, a varia3le called given,ame i# created *n the #tackQ it ha# n*thing t* d* !ith the in#tance varia3le al#* called given,ame) -t +ay 3e unlikely that #*+e*ne !*uld accidentally create a +eth*d varia3le called given,ame, 3ut y*ud 3e a+a7ed at h*! +any name, id, and flag# -ve #een in +y dayK -t# an*ther rea#*n !hy +eaning9ul varia3le na+e# are i+p*rtant) Side3ar1 Stack, -n#tance, and Para+eter Caria3le# S*+eti+e# y*ull #ee c*de !here hal9 the varia3le# 3egin !ith under#c*re# and hal9 the varia3le# d*nt1
166
Thinking in C
www.ThinkingIn.!et
foo 9 X$ar3 The intent i# t* u#e the pre9i; t* di#tingui#h 3et!een +eth*d varia3le# that are created *n the #tack and g* *ut *9 #c*pe a# #**n a# the +eth*d e;it# and varia3le# that have l*nger li9e#pan#) - hate thi# idi*+) 5*r *ne thing, it# *rigin had t* d* !ith vi#i3ility, n*t #t*rage, and C# ha# e;plicit and in9initely 3etter vi#i3ility #peci9ier#) 5*r an*ther, it# u#ed inc*n#i#tently P al+*#t a# +any pe*ple u#e the under#c*re# 9*r #tack varia3le# a# u#e the+ 9*r in#tance varia3le#) S*+eti+e# y*u #ee c*de that prepend# an T+ t* +e+3er varia3le# na+e#1 foo 9 !Bar3 - hate thi# a little le## than - hate the under#c*re#) Thi# type *9 na+ing c*nventi*n i# an *99#h**t *9 a C na+ing idi*+ called IHungarian n*tati*n,J that prepended type in9*r+ati*n t* a varia3le na+e G#* #tring# !*uld 3e str:ooH) Thi# i# a great idea i9 y*ure pr*gra++ing in C and every*ne !h* ha# pr*gra++ed ,ind*!# ha# #een their #hare *9 varia3le# #tarting !ith Th, 3ut the ti+e 9*r thi# na+ing c*nventi*n ha# pa##ed) -9 y*u !ant t* di#tingui#h 3et!een +eth*d and in#tance varia3le#, u#e this) -t# *34ectE*riented, de#criptive, and e;plicit) <<end #ide3ar
16#
//:c0E:H o.er.c# // Ca ing con#tructor# .ith &: thi#.& pu$ ic c a## H o.er ; int peta Count 9 03 #tring # 9 &nu &3 H o.er0int peta #1 ; peta Count 9 peta #3 Sy#te!.Con#o e.VriteLine0 &Con#tructor ./ int arg on y2 peta Count9 & R peta Count13 < H o.er0#tring ##1 ; Sy#te!.Con#o e.VriteLine0 &Con#tructor ./ #tring arg on y2 #9& R ##13 # 9 ##3 < H o.er0#tring #2 int peta #1 : thi#0peta #1; //! thi#0#13 // Can't ca t.o! thi#.# 9 #3 // )nother u#e of &thi#& Sy#te!.Con#o e.VriteLine0&#tring @ int arg#&13 < H o.er01 : thi#0&hi&2 EF1 ; Sy#te!.Con#o e.VriteLine0 &defau t con#tructor 0no arg#1&13 < *oid -rint01 ; Sy#te!.Con#o e.VriteLine0 &peta Count 9 & R peta Count R & # 9 &R #13 < pu$ ic #tatic *oid Gain01 ; H o.er x 9 ne. H o.er013 x.-rint013 < <//:8 The c*n#truct*r :lower(#tring s, int petals) #h*!# that, !hile y*u can call *ne c*n#truct*r u#ing this, y*u cann*t call t!*) Ot*d*1 c*n9ir+
16&
Thinking in C
www.ThinkingIn.!et
particular +eth*d) :*u cann*t call n*nEstatic +eth*d# 9r*+ in#ide static +eth*d# Galth*ugh the rever#e i# p*##i3leH, and y*u can call a static +eth*d 9*r the cla## it#el9, !ith*ut any *34ect) -n 9act, that# pri+arily !hat a static +eth*d i# 9*r) -t# a# i9 y*ure creating the eDuivalent *9 a gl*3al 9uncti*n G9r*+ CH) E;cept gl*3al 9uncti*n# are n*t per+itted in C#, and putting the static +eth*d in#ide a cla## all*!# it acce## t* *ther static +eth*d# and static 9ield#) S*+e pe*ple argue that static +eth*d# are n*t *34ectE*riented #ince they d* have the #e+antic# *9 a gl*3al 9uncti*nQ !ith a static +eth*d y*u d*nt #end a +e##age t* an *34ect, #ince there# n* this) Thi# i# pr*3a3ly a 9air argu+ent, and i9 y*u 9ind y*ur#el9 u#ing a lot *9 #tatic +eth*d# y*u #h*uld pr*3a3ly rethink y*ur #trategy) H*!ever, static# are prag+atic and there are ti+e# !hen y*u genuinely need the+, #* !hether *r n*t they are Ipr*per OOPJ #h*uld 3e le9t t* the the*retician#) -ndeed, even S+alltalk ha# the eDuivalent in it# Icla## +eth*d#)J Ot*d*1 C*n9ir+ that p*ly+*rphi#+ di#cu##i*n ha# n*nEp*ly+*rphi#+ *9 #tatic +eth*d#
16'
C@@ pr*gra++er# !ill 9ind thi# #ynta; 9a+iliar, 3ut thi# i# actually a danger*u# +i+ic P the C# de#truct*r ha# va#tly di99erent #e+antic#, a# y*ull #ee) Here# h*! it# su""osed t* !*rk) ,hen the gar3age c*llect*r i# ready t* relea#e the #t*rage u#ed 9*r y*ur *34ect, it !ill 9ir#t call the *34ect# de#truct*r, and *nly *n the ne;t gar3ageEc*llecti*n pa## !ill it reclai+ the *34ect# +e+*ry) S* i9 y*u ch**#e t* u#e the de#truct*r, it give# y*u the a3ility t* per9*r+ #*+e i+p*rtant cleanup at the time o$ gar2age collection) Thi# i# a p*tential pr*gra++ing pit9all 3ecau#e #*+e pr*gra++er#, e#pecially C@@ pr*gra++er#, 3ecau#e in C@@ o23ects alwa4s get destro4ed Gin a 3ugE9ree pr*gra+H, !herea# in C# *34ect# d* n*t al!ay# get gar3ageEc*llected) Or, put an*ther !ay1
1#(
Thinking in C
www.ThinkingIn.!et
1#1
#tatic *oid u#eNa ua$ eRe#ource#01; for0int i 9 03 i W G),XR+SOORC+S3 iRR1; Na ua$ eRe#ource *r 9 ne. Na ua$ eRe#ource013 < < #tatic int idCounter3 #tatic int G),XR+SOORC+S 9 "03 #tatic int 5CN)L5:X5: 9 6"3 int id3
1#)
Thinking in C
www.ThinkingIn.!et
Na ua$ eRe#ource01; if0idCounter 99 G),XR+SOORC+S1; Sy#te!.Con#o e.VriteLine0&Co re#ource# a*ai a$ e&13 id 9 5CN)L5:X5:3 <e #e; id 9 idCounterRR3 Sy#te!.Con#o e.VriteLine0&Re#ourceJ;0<K Con#tructed&2 id13 < < 8Na ua$ eRe#ource01; if0id 99 5CN)L5:X5:1; Sy#te!.Con#o e.VriteLine0&'hing# are a.ry!&13 <e #e; idCounter663 Sy#te!.Con#o e.VriteLine0&Re#ourceJ;0<K :e#tructed&2 id 13 < < <///:8 -n thi# e;a+ple, the 9ir#t thing that happen# up*n entering AainGH i# the u#eCalua3leRe#*urce#GH +eth*d i# called) Thi# i# #traight9*r!ard P the A=B`RESOURCES nu+3er *9 Calua3leRe#*urce *34ect# are created and then i++ediately all*!ed t* Ig* a!ayJ) -n the Calua3leRe#*urceGH c*n#truct*r, the #tatic idC*unter varia3le i# checked t* #ee i9 it eDual# the A=B`RESOURCES value) -9 #*, a I * re#*urce# availa3leJ +e##age i# !ritten and the id *9 the Calua3le Re#*urce i# #et t* an invalid value Gin thi# ca#e, the idC*unter i# the #*urce *9 the I#carceJ re#*urce !hich i# Ic*n#u+edJ 3y the id varia3leH) The Calua3leRe#*urce de#truct*r either *utput# a !arning +e##age *r decre+ent# the idC*unter Gthu#, +aking an*ther Ire#*urceJ availa3leH) ,hen u#eCalua3leRe#*urce#GH return#, the #y#te+ pau#e# 9*r 0$ #ec*nd# G!ell di#cu## Thread)SleepGH in great detail in Chapter #AULT-THRE=?- >#H, and 9inally a ne! Calua3leRe#*urce i# created) -t #ee+# like that #h*uld 3e 9ine, #ince th*#e created in
1#3
u#eCalua3leRe#*urce#GH are l*ng g*ne) But the *utput tell# a di99erent #t*ry1 Re#ourceJ0K Con#tructed Re#ourceJ"K Con#tructed Re#ourceJ2K Con#tructed Re#ourceJTK Con#tructed Re#ourceJEK Con#tructed Re#ourceJPK Con#tructed Re#ourceJ?K Con#tructed Re#ourceJFK Con#tructed Re#ourceJIK Con#tructed Re#ourceJ>K Con#tructed Na ua$ e re#ource# u#ed and di#carded "0 #econd# ater... Co re#ource# a*ai a$ e 'hing# are a.ry! Re#ourceJ>K :e#tructed Re#ourceJIK :e#tructed Re#ourceJFK :e#tructed Re#ourceJ?K :e#tructed Re#ourceJPK :e#tructed Re#ourceJEK :e#tructed Re#ourceJTK :e#tructed Re#ourceJ2K :e#tructed Re#ourceJ"K :e#tructed Re#ourceJ0K :e#tructed Even a9ter ten #ec*nd# Gan eternity in c*+puting ti+eH, n* id# are availa3le and the 9inal atte+pt t* create a Calua3leRe#*urce 9ail#) -ntere#tingly, the AainGH e;it# i++ediately a9ter the I * re#*urce# availa3leKJ +e##age i# !ritten) -n thi# ca#e, the CLR did d* a gar3age c*llecti*n a# the pr*gra+ e;ited and the aCalua3leRe#*urceGH de#truct*r# g*t called) -n thi# ca#e, they happen t* 3e deleted in the rever#e *rder *9 their creati*n, 3ut the *rder *9 de#tructi*n *9 re#*urce# i# yet an*ther Ia3#*lutely n*t guaranteedJ characteri#tic *9 gar3age c*llecti*n) ,*r#e, thi# i# the *utput i9 *ne pre##e# CtlEC during the pau#e1 Re#ourceJ0K Con#tructed Re#ourceJ"K Con#tructed Re#ourceJ2K Con#tructed
1#4
Thinking in C
www.ThinkingIn.!et
Re#ourceJTK Con#tructed Re#ourceJEK Con#tructed Re#ourceJPK Con#tructed Re#ourceJ?K Con#tructed Re#ourceJFK Con#tructed Re#ourceJIK Con#tructed Re#ourceJ>K Con#tructed Na ua$ e re#ource# u#ed and di#carded ]C ::^tic^chapEZ That# it) * cleanup) -9 the valua3le re#*urce# !ere, #ay, net!*rk #*cket# *r data3a#e c*nnecti*n# *r 9ile# *r, !ell, anything that actually had any value, theyd 3e l*#t until y*u re3**t G*r #*+e *ther pr*ce## +anage# t* re#t*re their #tate 3y 3rute 9*rce, a# can happen !ith 9ile#H) //:c0E:Na ua$ eRe#ource2.c# u#ing Sy#te!3 u#ing Sy#te!.'hreading3 c a## Na ua$ eRe#ource; #tatic int idCounter3 #tatic int G),XR+SOORC+S 9 "03 #tatic int 5CN)L5:X5: 9 6"3 int id3 Na ua$ eRe#ource01; if0idCounter 99 G),XR+SOORC+S1; Sy#te!.Con#o e.VriteLine0&Co re#ource# a*ai a$ e&13 id 9 5CN)L5:X5:3 <e #e; id 9 idCounterRR3 Sy#te!.Con#o e.VriteLine0&Re#ourceJ;0<K Con#tructed&2 id13 < < *oid :i#po#e01; idCounter663 Sy#te!.Con#o e.VriteLine0&Re#ourceJ;0<K :e#tructed&2 id 13 if0id 99 5CN)L5:X5:1;
1#5
Sy#te!.Con#o e.VriteLine0&'hing# are a.ry!&13 < _C.Suppre##Hina iMe0thi#13 < 8Na ua$ eRe#ource01; thi#.:i#po#e013 < pu$ ic #tatic *oid Gain01; u#eNa ua$ eRe#ource#013 Sy#te!.Con#o e.VriteLine0&Na ua$ e re#ource# u#ed and di#carded&13 'hread.S eep0"000013 Sy#te!.Con#o e.VriteLine0&"0 #econd# ater...&13 //'hi# Xi#X fine Na ua$ eRe#ource *r 9 ne. Na ua$ eRe#ource013 < #tatic *oid u#eNa ua$ eRe#ource#01; for0int i 9 03 i W G),XR+SOORC+S3 iRR1; Na ua$ eRe#ource *r 9 ne. Na ua$ eRe#ource013 *r.:i#po#e013 < < <///:8 ,eve +*ved the c*de that !a# previ*u#ly in the de#truct*r int* a +eth*d called $ispose()) =dditi*nally, !eve added the line1 _C.Suppre##Hina iMe0thi#13 ,hich tell# the >ar3age C*llect*r Gthe >C *34ectH n*t t* call the de#truct*r during gar3age c*llecti*n) ,eve kept the de#truct*r, 3ut it d*e# n*thing 3ut call $ispose()) -n thi# ca#e, the de#truct*r i# 4u#t a #a9etyEnet) -t re+ain# *ur re#p*n#i3ility t* e;plicitly call ?i#p*#eGH, 3ut i9 !e d*nt and it #* happen# that the gar3age c*llect*r get# 9ir#t up, then *ur 3ac*n i# pulled *ut *9 the 9ire) S*+e argue thi# i# !*r#e than u#ele## EE a +eth*d !hich i#nt guaranteed t* 3e called 3ut !hich per9*r+# a critical 9uncti*n)
1#6
Thinking in C
www.ThinkingIn.!et
,hen Calua3leRe#*urce#2 i# run, n*t *nly are there n* pr*3le+# !ith running *ut *9 re#*urce#, the idC*unter never get# a3*ve $K
1##
< O#ingC eanup01; Sy#te!.Con#o e.VriteLine0&Con#tructor ed&13 < pu$ ic *oid :i#po#e01; Sy#te!.Con#o e.VriteLine0&:i#po#e ca < ed&13
ca
ed&13
< //:8 One *9 the thing# $ispose( ) can 3e u#e9ul 9*r i# pr*3ing the #*+eti+e# +y#teri*u# pr*ce## *9 gar3age c*llecti*n) Ot*d*1 ,rite a ne! pr*gra+ that illu#trate# 3etter C## de#truct*r < ?i#p*#e i##ue# The 9*ll*!ing e;a+ple #h*!# y*u !hat# g*ing *n and #u++ari7e# the previ*u# de#cripti*n# *9 gar3age c*llecti*n1 //:c0E:_ar$age.c# // :e!on#tration of the gar$age // co ector and di#po#a c a## Chair ; #tatic $oo gcrun 9 fa #e3 interna #tatic $oo f 9 fa #e3 interna #tatic int created 9 03 interna #tatic int fina iMed 9 03 int i3 interna Chair01 ; i 9 RRcreated3 if0created 99 EF1; Sy#te!.Con#o e.VriteLine0&Created EF&13
1#&
Thinking in C
www.ThinkingIn.!et
Sy#te!.Con#o e.VriteLine0&Byte# of !e!ory a ocated $efore _C: & R Sy#te!._C._et'ota Ge!ory0fa #e113 Sy#te!.Con#o e.VriteLine0&Byte# of !e!ory a ocated after _C: & R Sy#te!._C._et'ota Ge!ory0true113 < < 8Chair01 ; if0!gcrun1 ; // 'he fir#t ti!e the de#tructor i# ca ed: gcrun 9 true3 Sy#te!.Con#o e.VriteLine0 &Beginning to de#truct after & R created R & Chair# ha*e $een created&13 < if0i 99 EF1 ; Sy#te!.Con#o e.VriteLine0 &:e#troying Chair (EF2 & R &Setting f ag to #top Chair creation&13 f 9 true3 < fina iMedRR3 if0fina iMed Z9 created1 Sy#te!.Con#o e.VriteLine0 &) & R fina iMed R & fina iMed&13 < < pu$ ic c a## _ar$age ; pu$ ic #tatic *oid Gain0#tringJK arg#1 ; Sy#te!.Con#o e.VriteLine0&Byte# of !e!ory a ocated: & R Sy#te!._C._et'ota Ge!ory0fa #e113 // )# ong a# the f ag ha#n't $een #et2 // !a%e Chair#: .hi e0!Chair.f1 ; ne. Chair013 < Sy#te!.Con#o e.VriteLine0 &)fter a Chair# ha*e $een created:^n& R &tota created 9 & R Chair.created R
1#'
&2 tota fina iMed 9 & R Chair.fina iMed13 // Optiona argu!ent# force gar$age // co ection @ fina iMation: if0arg#.Length Z 01 ; if0arg#J0K 99 &gc& SS arg#J0K 99 &a &1 ; Sy#te!.Con#o e.VriteLine0&gc01:&13 Sy#te!._C.Co ect013 < /= \todo: Hind e7ui*a entY if0arg#J0K.e7ua #0&fina iMe&1 SS arg#J0K.e7ua #0&a &11 ; Sy#te!.Contro .VriteLine0&runHina iMation01:&13 Sy#te!.runHina iMation013 < < =/ Sy#te!.Con#o e.VriteLine0&$ye!&13 < < <///:8 The a3*ve pr*gra+ create# +any Chair *34ect#, and at #*+e p*int a9ter the gar3age c*llect*r 3egin# running, the pr*gra+ #t*p# creating Chair#) Since the gar3age c*llect*r can run at any ti+e, y*u d*nt kn*! e;actly !hen it !ill #tart up, #* there# a 9lag called gcrun t* indicate !hether the gar3age c*llect*r ha# #tarted running yet) = #ec*nd 9lag f i# a !ay 9*r Chair t* tell the .ain( ) l**p that it #h*uld #t*p +aking *34ect#) B*th *9 the#e 9lag# are #et !ithin OChair( ), !hich i# called during gar3age c*llecti*n) T!* *ther static varia3le#, created and finaliTed, keep track *9 the nu+3er *9 Chair# created ver#u# the nu+3er that get 9inali7ed 3y the gar3age c*llect*r) 5inally, each Chair ha# it# *!n Gn*nEstaticH int i #* it can keep track *9 !hat nu+3er it i#) ,hen Chair nu+3er &% i# 9inali7ed, the 9lag i# #et t* true t* 3ring the pr*ce## *9 Chair creati*n t* a #t*p) =ll thi# happen# in .ain( ), in the l**p .hi e0!Chair.f1 ; ne. Chair013
1&(
Thinking in C
www.ThinkingIn.!et
< :*u +ight !*nder h*! thi# l**p c*uld ever 9ini#h, #ince there# n*thing in#ide the l**p that change# the value *9 Chair6f) H*!ever, the finaliTe( ) pr*ce## !ill, eventually, !hen it 9inali7e# nu+3er &%) ,hen y*u run the pr*gra+, y*u pr*vide a c*++andEline argu+ent *9 Igc,J I9inali7e,J *r Iall)J The IgcJ argu+ent !ill call the #ystem6gc( ) +eth*d Gt* 9*rce e;ecuti*n *9 the gar3age c*llect*rH) U#ing the I9inali7eJ argu+ent call# #ystem6run:inaliTation( ) !hichRin the*ryR!ill cau#e any un9inali7ed *34ect# t* 3e 9inali7ed) =nd IallJ cau#e# 3*th +eth*d# t* 3e called) The preceding pr*gra+ #h*!# that the pr*+i#e that 9inali7er# !ill al!ay# 3e run h*ld# true, 3ut *nly i9 y*u e;plicitly 9*rce it t* happen y*ur#el9) -9 y*u d*nt cau#e #ystem6gc( ) t* 3e called, y*ull get an *utput like thi#1 Created EF Beginning to fina iMe created Hina iMing Chair (EF2 creation )fter a Chair# ha*e tota created 9 TII"2 $ye!
after TEI? Chair# ha*e $een Setting f ag to #top Chair $een created: tota fina iMed 9 2?IE
Thu#, n*t all 9inali7er# get called 3y the ti+e the pr*gra+ c*+plete#) -9 #ystem6gc( ) i# called, it !ill 9inali7e and de#tr*y all the *34ect# that are n* l*nger in u#e up t* that p*int) Re+e+3er that neither gar3age c*llecti*n n*r 9inali7ati*n i# guaranteed) -9 the "ava Cirtual Aachine G"CAH i#nt cl*#e t* running *ut *9 +e+*ry, then it !ill G!i#elyH n*t !a#te ti+e rec*vering +e+*ry thr*ugh gar3age c*llecti*n)
1&1
1&)
Thinking in C
www.ThinkingIn.!et
Boo% no*e 9 ne. Boo%0true13 // -roper c eanup: no*e .Chec%5n013 // :rop the reference2 forget to c ean up: ne. Boo%0true13 // Horce gar$age co ection @ fina iMation: Sy#te!._C.Co ect013 < < ///:8 The death c*nditi*n i# that all Boo( *34ect# are #upp*#ed t* 3e checked in 3e9*re they are gar3ageEc*llected, 3ut in .ain( ) a pr*gra++er err*r d*e#nt check in *ne *9 the 3**k#) ,ith*ut the de#truct*r# validati*n *9 the death c*nditi*n, thi# c*uld 3e a di99icult 3ug t* 9ind) *te that #ystem6 C6Collect( ) i# u#ed t* 9*rce cleanup Gand y*u #h*uld d* thi# during pr*gra+ devel*p+ent t* #peed de3uggingH) But even i9 it i#nt, the gar3age c*llect*r i# al!ay# 9ired *n the end *9 an applicati*n pr*ce## Gunle## 3r*ken int* !ith an e;plicit IC*ntr*lECJ interruptH, #* the errant Boo( !ill Duickly 3e di#c*vered)
1&3
#earching 9*r #t*rage)H :e#, y*u heard right P all*cati*n *n the +anaged heap i# $aster than all*cati*n !ithin a C@@E#tyle un+anaged heap) *! y*u +ight *3#erve that the heap i#nt in 9act a c*nvey*r 3elt, and i9 y*u treat it that !ay y*ull eventually #tart paging +e+*ry a l*t G!hich i# a 3ig per9*r+ance hitH and later run *ut) The trick i# that the gar3age c*llect*r #tep# in and !hile it c*llect# the gar3age it c*+pact# all the *34ect# in the heap #* that y*uve e99ectively +*ved the Iheap p*interJ cl*#er t* the 3eginning *9 the c*nvey*r 3elt and 9urther a!ay 9r*+ a page 9ault) The gar3age c*llect*r rearrange# thing# and +ake# it p*##i3le 9*r the highE#peed, in9initeE9reeEheap +*del t* 3e u#ed !hile all*cating #t*rage) T* under#tand h*! thi# !*rk#, y*u need t* get a little 3etter idea *9 the !ay the C*++*n Language Runti+e gar3age c*llect*r G>CH !*rk#) >ar3age c*llecti*n in the CLR Gre+e+3er that +e+*ry +anage+ent e;i#t# in the CLR I3el*!J the level *9 the C*++*n Type Sy#te+, #* thi# di#cu##i*n eDually applie# t* pr*gra+# !ritten in Ci#ual Ba#ic ) ET, Ei99el ) ET, and Pyth*n ) ET a# t* C# pr*gra+#H i# 3a#ed *n the idea that any n*ndead *34ect +u#t ulti+ately 3e tracea3le 3ack t* a re9erence that live# either *n the #tack *r in #tatic #t*rage) The chain +ight g* thr*ugh #everal layer# *9 *34ect#) Thu#, i9 y*u #tart in the #tack and the #tatic #t*rage area and !alk thr*ugh all the re9erence# y*ull 9ind all the live *34ect#) 5*r each re9erence that y*u 9ind, y*u +u#t trace int* the *34ect that it p*int# t* and then 9*ll*! all the re9erence# in that *34ect, tracing int* the *34ect# they p*int t*, etc), until y*uve +*ved thr*ugh the entire !e3 that *riginated !ith the re9erence *n the #tack *r in #tatic #t*rage) Each *34ect that y*u +*ve thr*ugh +u#t #till 3e alive) *te that there i# n* pr*3le+ !ith detached #el9Ere9erential gr*up#Rthe#e are #i+ply n*t 9*und, and are there9*re aut*+atically gar3age) =l#*, i9 y*u trace t* an *34ect that ha# already 3een !alked t*, y*u d* n*t have t* reEtrace it) Having l*cated all the IliveJ *34ect#, the >C #tart# at the end *9 the +anaged heap and #hi9t# the 9ir#t live *34ect in +e+*ry t* 3e directly ad4acent t* the penulti+ate live *34ect) Thi# pair *9 live *34ect# i# then #hi9ted t* the ne;t live *34ect, the three are #hi9ted en +a##e t* the ne;t, and #* 9*rth, until the heap i# c*+pacted)
1&4
Thinking in C
www.ThinkingIn.!et
O3vi*u#ly, gar3age c*llecti*n i# a l*t *9 !*rk, even *n a +*dern, highE #peed +achine) -n *rder t* i+pr*ve per9*r+ance, the gar3age c*llect*r re9ine# the 3a#ic appr*ach de#cri3ed here !ith generations) The 3a#ic c*ncept *9 generati*nal gar3age c*llecti*n i# that an *34ect all*cated recently i# +*re likely t* 3e gar3age than an *34ect !hich ha# already #urvived +ultiple pa##e# *9 the gar3age c*llect*r) S* in#tead *9 !alking the heap all the !ay 9r*+ the #tack *r #tatic #t*rage, *nce the >C ha# run *nce, the c*llect*r +ay a##u+e that the previ*u#ly c*+pacted *34ect# Gthe *lder generati*nH are all valid and *nly !alk the +*#t recently all*cated part *9 the heap Gthe ne! generati*nH) >ar3age c*llecti*n i# a 9av*rite t*pic *9 re#earcher#, and there !ill und*u3tedly 3e inn*vati*n# in >C that !ill eventually 9ind their !ay int* the 9ield) H*!ever, gar3age c*llecti*n and c*+puter p*!er have already g*tten t* the #tage !here the +*#t re+arka3le thing a3*ut >C i# h*! tran#parent it i#)
@e#+er initiali:ation
C# g*e# *ut *9 it# !ay t* guarantee that varia3le# are pr*perly initiali7ed 3e9*re they are u#ed) -n the ca#e *9 varia3le# that are de9ined l*cally t* a +eth*d, thi# guarantee c*+e# in the 9*r+ *9 a c*+pileEti+e err*r) S* i9 y*u #ay1 *oid H01 ; int i3 iRR3 < y*ull get an err*r +e##age that #ay# that i i# an una##igned l*cal varia3le) O9 c*ur#e, the c*+piler c*uld have given i a de9ault value, 3ut it# +*re likely that thi# i# a pr*gra++er err*r and a de9ault value !*uld have c*vered that up) 5*rcing the pr*gra++er t* pr*vide an initiali7ati*n value i# +*re likely t* catch a 3ug) -9 a pri+itive i# a data +e+3er *9 a cla##, h*!ever, thing# are a 3it di99erent) Since any +eth*d can initiali7e *r u#e that data, it +ight n*t 3e practical t* 9*rce the u#er t* initiali7e it t* it# appr*priate value 3e9*re the data i# u#ed) H*!ever, it# un#a9e t* leave it !ith a gar3age value, #* each
1&5
pri+itive data +e+3er *9 a cla## i# guaranteed t* get an initial value) Th*#e value# can 3e #een here1 //:c0E:5nitia Na ue#.c# // Sho.# defau t initia *a ue#. c a## Gea#ure!ent ; $oo t3 char c3 $yte $3 #hort #3 int i3 ong 3 f oat f3 dou$ e d3 interna *oid -rint01 ; Sy#te!.Con#o e.VriteLine0 &:ata type 5nitia *a ue^n& R &$oo & R t R &^n& R &char J& R c R &K &R 0int1c R&^n&R &$yte & R $ R &^n& R &#hort & R # R &^n& R &int & R i R &^n& R & ong & R R &^n& R &f oat & R f R &^n& R &dou$ e & R d13 < < pu$ ic c a## 5nitia Na ue# ; pu$ ic #tatic *oid Gain01 ; Gea#ure!ent d 9 ne. Gea#ure!ent013 d.-rint013 /= 5n thi# ca#e you cou d a #o #ay: ne. Gea#ure!ent01.print013 =/ < < ///:8 The *utput *9 thi# pr*gra+ i#1 :ata type $oo ean 5nitia fa #e *a ue
1&6
Thinking in C
www.ThinkingIn.!et
J K 0 0 0 0 0 0.0 0.0
The char value i# a 7er*, !hich print# a# a #pace) :*ull #ee later that !hen y*u de9ine an *34ect re9erence in#ide a cla## !ith*ut initiali7ing it t* a ne! *34ect, that re9erence i# given a #pecial value *9 null G!hich i# a C# key!*rdH) :*u can #ee that even th*ugh the value# are n*t #peci9ied, they aut*+atically get initiali7ed) S* at lea#t there# n* threat *9 !*rking !ith uninitiali7ed varia3le#)
'$eci05ing initiali:ation
,hat happen# i9 y*u !ant t* give a varia3le an initial valueF One direct !ay t* d* thi# i# #i+ply t* a##ign the value at the p*int y*u de9ine the varia3le in the cla##) Here the 9ield de9initi*n# in cla## .easurement are changed t* pr*vide initial value#1 c a## Gea#ure!ent ; $oo $ 9 true3 char c 9 'x'3 $yte B 9 EF3 #hort # 9 0xff3 int i 9 >>>3 ong 9 "3 f oat f 9 T."Ef3 dou$ e d 9 T."E"P>3 //. . . :*u can al#* initiali7e n*npri+itive *34ect# in thi# #a+e !ay) -9 $epth i# a cla##, y*u can in#ert a varia3le and initiali7e it like #*1 c a## Gea#ure!ent ; :epth o 9 ne. :epth013 $oo ean $ 9 true3
1&#
// . . . -9 y*u havent given o an initial value and y*u try t* u#e it any!ay, y*ull get a runEti+e err*r called an e%ce"tion Gc*vered in Chapter #e;cepti*n#H) :*u can even call a #tatic +eth*d t* pr*vide an initiali7ati*n value1 c a## C5nit ; int i 9 5nit5013 //... #tatic int 5nit501; //L < < Thi# +eth*d can have argu+ent#, 3ut th*#e argu+ent# cann*t 3e in#tance varia3le#) "ava pr*gra++er# !ill n*te that thi# i# +*re re#trictive than "ava# in#tance initiali7ati*n, !hich can call n*nE#tatic +eth*d# and u#e previ*u#ly in#tantiated in#tance varia3le#) Thi# appr*ach t* initiali7ati*n i# #i+ple and #traight9*r!ard) -t ha# the li+itati*n that e-er4 *34ect *9 type .easurement !ill get the#e #a+e initiali7ati*n value#) S*+eti+e# thi# i# e;actly !hat y*u need, 3ut at *ther ti+e# y*u need +*re 9le;i3ility)
Constructor initiali:ation
The c*n#truct*r can 3e u#ed t* per9*r+ initiali7ati*n, and thi# give# y*u greater 9le;i3ility in y*ur pr*gra++ing #ince y*u can call +eth*d# and per9*r+ acti*n# at runEti+e t* deter+ine the initial value#) There# *ne thing t* keep in +ind, h*!ever1 y*u arent precluding the aut*+atic initiali7ati*n, !hich happen# 3e9*re the c*n#truct*r i# entered) S*, 9*r e;a+ple, i9 y*u #ay1 c a## Counter ; int i3 Counter01 ; i 9 F3 < // . . . then i !ill 9ir#t 3e initiali7ed t* $, then t* %) Thi# i# true !ith all the pri+itive type# and !ith *34ect re9erence#, including th*#e that are given e;plicit initiali7ati*n at the p*int *9 de9initi*n) 5*r thi# rea#*n, the c*+piler d*e#nt try t* 9*rce y*u t* initiali7e ele+ent# in the c*n#truct*r
1&&
Thinking in C
www.ThinkingIn.!et
Order o0 initiali:ation
,ithin a cla##, the *rder *9 initiali7ati*n i# deter+ined 3y the *rder that the varia3le# are de9ined !ithin the cla##) The varia3le de9initi*n# +ay 3e #cattered thr*ugh*ut and in 3et!een +eth*d de9initi*n#, 3ut the varia3le# are initiali7ed 3e9*re any +eth*d# can 3e calledReven the c*n#truct*r) 5*r e;a+ple1 //:c0E:OrderOf5nitia iMation.c# // :e!on#trate# initia iMation order. // Vhen the con#tructor i# ca ed to create a // 'ag o$Dect2 you' #ee a !e##age: c a## 'ag ; interna 'ag0int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&'ag0& R !ar%er R &1&13 < < c a## Card ; 'ag t" 9 ne. 'ag0"13 // Before con#tructor interna Card01 ; // 5ndicate .e're in the con#tructor: Sy#te!.Con#o e.VriteLine0&Card01&13 tT 9 ne. 'ag0TT13 // Reinitia iMe tT < 'ag t2 9 ne. 'ag0213 // )fter con#tructor interna *oid H01 ; Sy#te!.Con#o e.VriteLine0&H01&13 < 'ag tT 9 ne. 'ag0T13 // )t end < pu$ ic c a## OrderOf5nitia iMation ; pu$ ic #tatic *oid Gain01 ;
/ -n c*ntra#t, C@@ ha# the constructor initiali;er list that cau#e# initiali7ati*n t* *ccur
3e9*re entering the c*n#truct*r 3*dy, and i# en9*rced 9*r *34ect#) See Thinking in C++6 )nd edition Gavaila3le *n thi# 3**k# C? ROA and at www.BruceEckel.comH)
1&'
Card t 9 ne. Card013 t.H013 // Sho.# that con#truction i# done < < ///:8 -n Card, the de9initi*n# *9 the +ag *34ect# are intenti*nally #cattered a3*ut t* pr*ve that theyll all get initiali7ed 3e9*re the c*n#truct*r i# entered *r anything el#e can happen) -n additi*n, t9 i# reinitiali7ed in#ide the c*n#truct*r) The *utput i#1 'ag0"1 'ag021 'ag0T1 Card01 'ag0TT1 f01 Thu#, the t9 re9erence get# initiali7ed t!ice, *nce 3e9*re and *nce during the c*n#truct*r call) GThe 9ir#t *34ect i# dr*pped, #* it can 3e gar3ageE c*llected later)H Thi# +ight n*t #ee+ e99icient at 9ir#t, 3ut it guarantee# pr*per initiali7ati*nR!hat !*uld happen i9 an *verl*aded c*n#truct*r !ere de9ined that did not initiali7e t9 and there !a#nt a Ide9aultJ initiali7ati*n 9*r t9 in it# de9initi*nF
1'(
Thinking in C
www.ThinkingIn.!et
interna Bo. 0int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&Bo. 0& R !ar%er R &1&13 < interna *oid H0int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&H0& R !ar%er R &1&13 < < c a## 'a$ e ; #tatic Bo. $" 9 ne. Bo. 0"13 interna 'a$ e01 ; Sy#te!.Con#o e.VriteLine0&'a$ e01&13 $2.H0"13 < interna *oid H20int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&H20& R !ar%er R &1&13 < #tatic Bo. $2 9 ne. Bo. 0213 < c a## Cup$oard ; Bo. $T 9 ne. Bo. 0T13 #tatic Bo. $E 9 ne. Bo. 0E13 interna Cup$oard01 ; Sy#te!.Con#o e.VriteLine0&Cup$oard01&13 $E.H0213 < interna *oid HT0int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&HT0& R !ar%er R &1&13 < #tatic Bo. $P 9 ne. Bo. 0P13 < pu$ ic c a## Static5nitia iMation ; pu$ ic #tatic *oid Gain01 ; Sy#te!.Con#o e.VriteLine0 &Creating ne. Cup$oard01 in !ain&13 ne. Cup$oard013 Sy#te!.Con#o e.VriteLine0 &Creating ne. Cup$oard01 in !ain&13 ne. Cup$oard013
1'1
t2.H20"13 tT.HT0"13 < #tatic 'a$ e t2 9 ne. 'a$ e013 #tatic Cup$oard tT 9 ne. Cup$oard013 < ///:8 Bowl all*!# y*u t* vie! the creati*n *9 a cla##, and +able and Cupboard create static +e+3er# *9 Bowl #cattered thr*ugh their cla## de9initi*n#) *te that Cupboard create# a n*nEstatic Bowl b9 pri*r t* the static de9initi*n#) The *utput #h*!# !hat happen#1 Bo. 0"1 Bo. 021 'a$ e01 f0"1 Bo. 0E1 Bo. 0P1 Bo. 0T1 Cup$oard01 f021 Creating ne. Cup$oard01 in !ain Bo. 0T1 Cup$oard01 f021 Creating ne. Cup$oard01 in !ain Bo. 0T1 Cup$oard01 f021 f20"1 fT0"1 The static initiali7ati*n *ccur# *nly i9 it# nece##ary) -9 y*u d*nt create a +able *34ect and y*u never re9er t* +able6b7 *r +able6b8, the static Bowl b7 and b8 !ill never 3e created) H*!ever, they are initiali7ed *nly !hen the $irst +able *34ect i# created G*r the 9ir#t static acce## *ccur#H) =9ter that, the static *34ect# are n*t reinitiali7ed) The *rder *9 initiali7ati*n i# static# 9ir#t, i9 they havent already 3een initiali7ed 3y a previ*u# *34ect creati*n, and then the n*nEstatic *34ect#) :*u can #ee the evidence *9 thi# in the *utput)
1')
Thinking in C
www.ThinkingIn.!et
-t# help9ul t* #u++ari7e the pr*ce## *9 creating an *34ect) C*n#ider a cla## called $og1 C. The 9ir#t ti+e an *34ect *9 type $og i# created, or the 9ir#t ti+e a static +eth*d *r static 9ield *9 cla## $og i# acce##ed, the C# runti+e +u#t l*cate the a##e+3ly in !hich $og# cla## de9initi*n i# #t*red) =# the $og cla## i# l*aded Gcreating a +ype *34ect, !hich y*ull learn a3*ut laterH, all *9 it# static initiali7er# are run) Thu#, static initiali7ati*n take# place *nly *nce, a# the +ype *34ect i# l*aded 9*r the 9ir#t ti+e) ,hen y*u create a new $og( ), the c*n#tructi*n pr*ce## 9*r a $og *34ect 9ir#t all*cate# en*ugh #t*rage 9*r a $og *34ect *n the heap) Thi# #t*rage i# !iped t* 7er*, aut*+atically #etting all the pri+itive# in that $og *34ect t* their de9ault value# G7er* 9*r nu+3er# and the eDuivalent 9*r boolean and charH and the re9erence# t* null) =ny initiali7ati*n# that *ccur at the p*int *9 9ield de9initi*n are e;ecuted) C*n#truct*r# are e;ecuted) =# y*u #hall #ee in Chapter #inheritance#, thi# +ight actually inv*lve a 9air a+*unt *9 activity, e#pecially !hen inheritance i# inv*lved)
D.
E.
1F.
11. 12.
'tatic Constructor
C# all*!# y*u t* gr*up *ther static initiali7ati*n# in#ide a #pecial Istatic c*n#truct*r)J -t l**k# like thi#1 c a## Spoon ; #tatic int i3 #tatic Spoon01; i 9 EF3 < // . . .
1'3
Thi# c*de, like *ther static initiali7ati*n#, i# e;ecuted *nly *nce, the 9ir#t ti+e y*u +ake an *34ect *9 that cla## or the 9ir#t ti+e y*u acce## a static +e+3er *9 that cla## Geven i9 y*u never +ake an *34ect *9 that cla##H) 5*r e;a+ple1 //:c0E:StaticCon#tructor.c# // +xp icit #tatic initia iMation // .ith #tatic con#tructor c a## Cup ; interna Cup0int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&Cup0& R !ar%er R &1&13 < interna *oid H0int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&f0& R !ar%er R &1&13 < < c a## Cup# ; interna #tatic Cup c"3 #tatic Cup c23 #tatic Cup#01; Sy#te!.Con#o e.VriteLine0&5n#ide #tatic Cup#01 con#tructor&13 c" 9 ne. Cup0"13 c2 9 ne. Cup0213 < Cup#01 ; Sy#te!.Con#o e.VriteLine0&Cup#01&13 < < pu$ ic c a## +xp icitStatic ; pu$ ic #tatic *oid Gain01 ; Sy#te!.Con#o e.VriteLine0&5n#ide Gain01&13 Cup#.c".H0>>13 // 0"1 < // #tatic Cup# x 9 ne. Cup#013 // 021 // #tatic Cup# y 9 ne. Cup#013 // 021 < ///:8
1'4
Thinking in C
www.ThinkingIn.!et
The static c*n#truct*r 9*r Cups run !hen either the acce## *9 the static *34ect c7 *ccur# *n the line +arked G0H, *r i9 line G0H i# c*++ented *ut and the line# +arked G2H are unc*++ented) -9 3*th G0H and G2H are c*++ented *ut, the static c*n#truct*r 9*r Cups never *ccur#) =l#*, it d*e#nt +atter i9 *ne *r 3*th *9 the line# +arked G2H are unc*++entedQ the #tatic initiali7ati*n *nly *ccur# *nce)
)rra5 initiali:ation
-nitiali7ing array# in C i# err*rEpr*ne and tedi*u#) C@@ u#e# aggregate initiali;ation t* +ake it +uch #a9er&) C# ha# n* Iaggregate#J like C@@, #ince everything i# an *34ect in "ava) -t d*e# have array#, and the#e are #upp*rted !ith array initiali7ati*n) =n array i# #i+ply a #eDuence *9 either *34ect# *r pri+itive#, all the #a+e type and packaged t*gether under *ne identi9ier na+e) =rray# are de9ined and u#ed !ith the #DuareE3racket# inde%ing o"erator < >) T* de9ine an array y*u #i+ply 9*ll*! y*ur type na+e !ith e+pty #Duare 3racket#1 intJK a"3 :*u can al#* put the #Duare 3racket# a9ter the identi9ier t* pr*duce e;actly the #a+e +eaning1 int a"JK3 Thi# c*n9*r+# t* e;pectati*n# 9r*+ C and C@@ pr*gra++er#) The 9*r+er #tyle, h*!ever, i# pr*3a3ly a +*re #en#i3le #ynta;, #ince it #ay# that the type i# Ian int array)J That #tyle !ill 3e u#ed in thi# 3**k) The c*+piler d*e#nt all*! y*u t* tell it h*! 3ig the array i#) Thi# 3ring# u# 3ack t* that i##ue *9 Ire9erence#)J =ll that y*u have at thi# p*int i# a re9erence t* an array, and there# 3een n* #pace all*cated 9*r the array) T* create #t*rage 9*r the array y*u +u#t !rite an initiali7ati*n e;pre##i*n) 5*r array#, initiali7ati*n can appear any!here in y*ur c*de, 3ut y*u can al#* u#e a #pecial kind *9 initiali7ati*n e;pre##i*n that +u#t *ccur at the p*int !here the array i# created) Thi# #pecial initiali7ati*n i# a #et *9 value# #urr*unded 3y curly 3race#) The #t*rage all*cati*n Gthe eDuivalent
& See Thinking in C++6 )nd edition 9*r a c*+plete de#cripti*n *9 C@@ aggregate
initiali7ati*n)
1'5
*9 u#ing newH i# taken care *9 3y the c*+piler in thi# ca#e) 5*r e;a+ple1 intJK a" 9 ; "2 22 T2 E2 P <3 S* !hy !*uld y*u ever de9ine an array re9erence !ith*ut an arrayF intJK a23 ,ell, it# p*##i3le t* a##ign *ne array t* an*ther in C#, #* y*u can #ay1 a2 9 a"3 ,hat y*ure really d*ing i# c*pying a re9erence, a# de+*n#trated here1 //:c0E:)rray#.c# // )rray# of pri!iti*e#. pu$ ic c a## )rray# ; pu$ ic #tatic *oid Gain01 ; intJK a" 9 ; "2 22 T2 E2 P <3 intJK a23 a2 9 a"3 for0int i 9 03 i W a2.Length3 iRR1 a2JiKRR3 for0int i 9 03 i W a".Length3 iRR1 Sy#te!.Con#o e.VriteLine0 &a"J& R i R &K 9 & R a"JiK13 < < ///:8
<
:*u can #ee that a7 i# given an initiali7ati*n value !hile a8 i# n*tQ a8 i# a##igned laterRin thi# ca#e, t* an*ther array) There# #*+ething ne! here1 all array# have a pr*perty G!hether theyre array# *9 *34ect# *r array# *9 pri+itive#H that y*u can DueryR3ut n*t changeRt* tell y*u h*! +any ele+ent# there are in the array) Thi# +e+3er i# Length) Since array# in C#, a# in "ava and C, #tart c*unting 9r*+ ele+ent 7er*, the large#t ele+ent y*u can inde; i# Length - 7) -9 y*u g* *ut *9 3*und#, C and C@@ Duietly accept thi# and all*! y*u t* #t*+p all *ver y*ur +e+*ry, !hich i# the #*urce *9 +any in9a+*u# 3ug#) H*!ever, C# pr*tect# y*u again#t #uch pr*3le+# 3y cau#ing a runEti+e err*r Gan e%ce"tion, the #u34ect *9 Chapter 0$H i9 y*u #tep *ut *9 3*und#) O9 c*ur#e,
1'6
Thinking in C
www.ThinkingIn.!et
checking every array acce## c*#t# ti+e and c*de, !hich +ean# that array acce##e# +ight 3e a #*urce *9 ine99iciency in y*ur pr*gra+ i9 they *ccur at a critical 4uncture) S*+eti+e# the "-T can IprecheckJ t* en#ure that all inde; value# in a l**p !ill never e;ceed the array 3*und#, 3ut in general, array acce## pay# a #+all per9*r+ance price) By e;plicitly +*ving t* Iun#a9eJ c*de Gdi#cu##ed in #un#a9e c*de#H, 3*und# checking can 3e turned *99) ,hat i9 y*u d*nt kn*! h*! +any ele+ent# y*ure g*ing t* need in y*ur array !hile y*ure !riting the pr*gra+F :*u #i+ply u#e new t* create the ele+ent# in the array) Here, new !*rk# even th*ugh it# creating an array *9 pri+itive# Gnew !*nt create a n*narray pri+itiveH1 //:c0E:)rrayCe..c# // Creating array# .ith ne.. u#ing Sy#te!3 pu$ ic c a## )rrayCe. ; #tatic Rando! rand 9 ne. Rando!013 pu$ ic #tatic *oid Gain01 ; intJK a3 a 9 ne. intJrand.Cext0201 R "K3 Sy#te!.Con#o e.VriteLine0 & ength of a 9 & R a.Length13 for0int i 9 03 i W a.Length3 iRR1 Sy#te!.Con#o e.VriteLine0 &aJ& R i R &K 9 & R aJiK13 < < ///:8 Since the #i7e *9 the array i# ch*#en at rand*+, it# clear that array creati*n i# actually happening at runEti+e) -n additi*n, y*ull #ee 9r*+ the *utput *9 thi# pr*gra+ that array ele+ent# *9 pri+itive type# are aut*+atically initiali7ed t* Ie+ptyJ value#) G5*r nu+eric# and char, thi# i# 7er*, and 9*r boolean, it# false)H -9 y*ure dealing !ith an array *9 n*npri+itive *34ect#, y*u +u#t al!ay# u#e new) Here, the re9erence i##ue c*+e# up again 3ecau#e !hat y*u
1'#
create i# an array *9 re9erence#) C*n#ider the !rapper type Bnt"older, !hich i# a cla## and n*t a pri+itive1 //:c0E:)rrayC a##O$D.c# // Creating an array of nonpri!iti*e o$Dect#. u#ing Sy#te!3 c a## 5ntUo der; int i3 interna 5ntUo der0int i1; thi#.i 9 i3 < pu$ ic o*erride #tring 'oString01; return i.'oString013 < < pu$ ic c a## )rrayC a##O$D ; #tatic Rando! rand 9 ne. Rando!013 pu$ ic #tatic *oid Gain01 ; 5ntUo derJK a 9 ne. 5ntUo derJrand.Cext0201 R "K3 Sy#te!.Con#o e.VriteLine0 & ength of a 9 & R a.Length13 for0int i 9 03 i W a.Length3 iRR1 ; aJiK 9 ne. 5ntUo der0rand.Cext0P00113 Sy#te!.Con#o e.VriteLine0 &aJ& R i R &K 9 & R aJiK13 < < < ///:8 Here, even a9ter new i# called t* create the array1 5ntUo derJK a 9 ne. 5ntUo derJrand.Cext0201 R "K3 it# *nly an array *9 re9erence#, and n*t until the re9erence it#el9 i# initiali7ed 3y creating a ne! Bnteger *34ect i# the initiali7ati*n c*+plete1 aJiK 9 ne. 5ntUo der0rand.Cext0P00113
1'&
Thinking in C
www.ThinkingIn.!et
-9 y*u 9*rget t* create the *34ect, h*!ever, y*ull get an e;cepti*n at runE ti+e !hen y*u try t* read the e+pty array l*cati*n) -t# al#* p*##i3le t* initiali7e array# *9 *34ect# u#ing the curlyE3raceE encl*#ed li#t) There are t!* 9*r+#1 //:c0E:)rray5nit.c# // )rray initia iMation. c a## 5ntUo der; int i3 interna 5ntUo der0int i1; thi#.i 9 i3 < pu$ ic o*erride #tring 'oString01; return i.'oString013 < < pu$ ic c a## )rray5nit ; pu$ ic #tatic *oid Gain01 ; 5ntUo derJK a 9 ; ne. 5ntUo der0"12 ne. 5ntUo der0212 ne. 5ntUo der0T12 <3 5ntUo ne. ne. ne. <3 < < ///:8 Thi# i# u#e9ul at ti+e#, 3ut it# +*re li+ited #ince the #i7e *9 the array i# deter+ined at c*+pileEti+e) The 9inal c*++a in the li#t *9 initiali7er# i# *pti*nal) GThi# 9eature +ake# 9*r ea#ier +aintenance *9 l*ng li#t#)H derJK 5ntUo 5ntUo 5ntUo $ 9 ne. 5ntUo derJK ; der0"12 der0212 der0T12
1''
@ultidi#ensional arra5s
C# all*!# y*u t* ea#ily create +ultidi+en#i*nal array#1 //:c0E:Gu ti:i!)rray.c# // Creating !u tidi!en#iona u#ing Sy#te!3 array#.
c a## 5ntUo der ; int i3 interna 5ntUo der0int i1 ; thi#.i 9 i3 < pu$ ic o*erride #tring 'oString01 ; return i.'oString013 < < pu$ ic c a## Gu ti:i!)rray ; #tatic Rando! rand 9 ne. Rando!013 #tatic *oid -rt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 < pu$ ic #tatic *oid Gain01 ; intJ2K a" 9 ; ; "2 22 T2<2 ; E2 P2 ?2<2 <3 -rt0&a".Length 9 & R a".Length13 -rt0& 99 & R a"._etLength001 R & = & R a"._etLength0"113 for 0int i 9 03 i W a"._etLength0013 iRR1 for 0int D 9 03 D W a"._etLength0"13 DRR1 -rt0&a"J& R i R &2& R D R &K 9 & R a"Ji2 DK13 // T6: rectangu ar array: intJ22K a2 9 ne. intJ22 22 EK3 for 0int i 9 03 i W a2._etLength0013 iRR1 for 0int D 9 03 D W a2._etLength0"13 DRR1
)((
Thinking in C
www.ThinkingIn.!et
for 0int % 9 03 % W a2._etLength0213 %RR1 -rt0&a2J& R i R &2& R D R &2& R % R &K 9 & R a2Ji2D2%K13 // `agged array .ith *aried6Length *ector#: intJKJKJK aT 9 ne. intJrand.Cext0F1 R "KJKJK3 for 0int i 9 03 i W aT.Length3 iRR1 ; aTJiK 9 ne. intJrand.Cext0P1 R "KJK3 for 0int D 9 03 D W aTJiK.Length3 DRR1 aTJiKJDK 9 ne. intJrand.Cext0P1 R "K3 < for 0int i 9 03 i W aT.Length3 iRR1 for 0int D 9 03 D W aTJiK.Length3 DRR1 for 0int % 9 03 % W aTJiKJDK.Length3 %RR1 -rt0&aTJ& R i R &KJ& R D R &KJ& R % R &K 9 & R aTJiKJDKJ%K13 // )rray of nonpri!iti*e o$Dect#: 5ntUo derJ2K aE 9 ; ; ne. 5ntUo der0"12 ne. 5ntUo der021<2 ; ne. 5ntUo der0T12 ne. 5ntUo der0E1<2 ; ne. 5ntUo der0P12 ne. 5ntUo der0?1<2 <3 for 0int i 9 03 i W aE._etLength0013 iRR1 for 0int D 9 03 D W aE._etLength0"13 DRR1 -rt0&aEJ& R i R &2& R D R &K 9 & R aEJi2DK13 5ntUo derJKJK aP3 aP 9 ne. 5ntUo derJTKJK3 for 0int i 9 03 i W aP.Length3 iRR1 ; aPJiK 9 ne. 5ntUo derJTK3 for 0int D 9 03 D W aPJiK.Length3 DRR1; aPJiKJDK 9 ne. 5ntUo der0i=D13 < < for 0int i 9 03 i W aP._etLength0013 iRR1; for 0int D 9 03 D W aPJiK.Length3 DRR1; -rt0&aPJ& R i R &KJ& R D R &K 9 & R aPJiKJDK13
)(1
< < < < ///:8 //\todo: Hix Gu ti:i!)rray to dea .ith rectangu ar and Dagged array#. :i#cu## perfor!ance ra!ification# The c*de u#ed 9*r printing u#e# Length #* that it d*e#nt depend *n 9i;ed array #i7e#) The 9ir#t e;a+ple #h*!# a +ultidi+en#i*nal array *9 pri+itive#) :*u deli+it each vect*r in the array !ith curly 3race#1 intJKJK a" 9 ; ; "2 22 T2 <2 ; E2 P2 ?2 <2 <3 Each #et *9 #Duare 3racket# +*ve# y*u int* the ne;t level *9 the array) The #ec*nd e;a+ple #h*!# a threeEdi+en#i*nal array all*cated !ith new) Here, the !h*le array i# all*cated at *nce1 intJKJKJK a2 9 ne. intJ2KJ2KJEK3 But the third e;a+ple #h*!# that each vect*r in the array# that +ake up the +atri; can 3e *9 any length1 intJKJKJK aT 9 ne. intJpRand0F1KJKJK3 for0int i 9 03 i W aT. ength3 iRR1 ; aTJiK 9 ne. intJpRand0P1KJK3 for0int D 9 03 D W aTJiK. ength3 DRR1 aTJiKJDK 9 ne. intJpRand0P1K3 < The 9ir#t new create# an array !ith a rand*+Elength 9ir#t ele+ent and the re#t undeter+ined) The #ec*nd new in#ide the for l**p 9ill# *ut the ele+ent# 3ut leave# the third inde; undeter+ined until y*u hit the third new) :*u !ill #ee 9r*+ the *utput that array value# are aut*+atically initiali7ed t* 7er* i9 y*u d*nt give the+ an e;plicit initiali7ati*n value)
)()
Thinking in C
www.ThinkingIn.!et
:*u can deal !ith array# *9 n*npri+itive *34ect# in a #i+ilar 9a#hi*n, !hich i# #h*!n in the 9*urth e;a+ple, de+*n#trating the a3ility t* c*llect +any new e;pre##i*n# !ith curly 3race#1 5ntegerJKJK aE 9 ; ; ne. 5nteger0"12 ne. 5nteger021<2 ; ne. 5nteger0T12 ne. 5nteger0E1<2 ; ne. 5nteger0P12 ne. 5nteger0?1<2 <3 The 9i9th e;a+ple #h*!# h*! an array *9 n*npri+itive *34ect# can 3e 3uilt up piece 3y piece1 5ntegerJKJK aP3 aP 9 ne. 5ntegerJTKJK3 for0int i 9 03 i W aP. ength3 iRR1 ; aPJiK 9 ne. 5ntegerJTK3 for0int D 9 03 D W aPJiK. ength3 DRR1 aPJiKJDK 9 ne. 5nteger0i=D13 < The i;) i# 4u#t t* put an intere#ting value int* the Bnteger)
)(3
= rectangular array, *n the *ther hand, i# a c*ntigu*u# 3l*ck1 dou$ e !y)rrayJP2EK 9 ne. dou$ eJP2EK3
Several *pti+i7ing techniDue# are harder t* d* !ith 4agged array# than !ith rectangular) ,hen re#earcher# at -BA added rectangular array# t* "ava, they #peeded up #*+e nu+erical 3ench+ark# 3y 9act*r# cl*#e t* '$K GIThe in4a Pr*4ect,J A*reira et al), C=CA, Oct 2$$0H S* 9ar, the C# *pti+i7er d*e#nt #ee+ t* 3e taking advantage *9 #uch p*##i3ilitie#, alth*ugh it d*e# run #*+e!hat 9a#ter than "ava *n Ch*le#ky +ultiplicati*n, *ne *9 the 3ench+ark# u#ed 3y the re#earcher#, p*rted here t* C#1 //:c0E:Cho e#%y.c# /= :e!on#tration progra! #ho.ing u#e of the )rray pac%age =/ /= =/ /= CUOL+Sa/: 'hi# progra! co!pute# the Cho e#%y factor O of a =/ /= #y!!etric po#iti*e definite !atrix ) #uch that ) 9 O'O .here =/
)(4
Thinking in C
www.ThinkingIn.!et
/= O' i# the tran#po#e of O. O i# an upper triangu ar !atrix. =/ u#ing Sy#te!3 pu$ ic c a## Cho e#%y ; pu$ ic #tatic *oid Gain01 ; int n 9 "0003 // pro$ e! #iMe dou$ eJ2K ) 9 ne. dou$ eJn2nK3 // n x n 26 di!en#iona array dou$ e op#3 dou$ e !f op#3 /= = Co!pute Cho e#%y factor u#ing an opti!iMed code. =/ initia iMe0)2n13 //)ccurate ./i "0!# on C'/2a/,-2 ./i PP!# on Vin>P/>I :ate'i!e t" 9 :ate'i!e.Co.3 unro 0)2n13 :ate'i!e t2 9 :ate'i!e.Co.3 'i!eSpan ti!e 9 0t2 6 t"13 op# 9 0000".0 = n1 = n1 = n1 / T.013 !f op# 9 00".0e6? = op#1 / ti!e.'ota Second#13 Sy#te!.Con#o e.Vrite0&Opti!iMed code2 'i!e: &Rti!eR& Gf op#:&R!f op#R& &13 *a idate0)2n13 /= = Co!pute Cho e#%y factor u#ing a #traightfor.ard code. =/ initia iMe0)2n13 t" 9 :ate'i!e.Co.3 p ain0)2n13 t2 9 :ate'i!e.Co.3 ti!e 9 0t2 6 t"13 op# 9 0000".0 = n1 = n1 = n1 / T.013 !f op# 9 00".0e6? = op#1 / ti!e.'ota Second#13
)(5
Sy#te!.Con#o e.Vrite0&Si!p e code2 'i!e: &Rti!eR& Gf op#:&R!f op#R& &13 *a idate0)2n13 < pu$ ic #tatic *oid initia iMe0dou$ eJ2K )2int n1 ; int i3 int D3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; for0 i 9 03 i W9 0n 6 "13 iRR1 ; )JD2 iK 9 03 <3 <3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; for0 i 9 D3 i W9 0n 6 "13 iRR1 ; )Ji2 DK 9 D R "3 <3 <3 < pu$ ic #tatic *oid *a idate0dou$ eJ2K )2int n1 ; int i3 int D3 int re#u t3 dou$ e ep#3 re#u t 9 "3 ep# 9 ".0e6"03 for0 i 9 03 i W9 0n 6 "13 iRR1 ; for0 D 9 i3 D W9 0n 6 "13 DRR1 ; if 000Gath.)$#00)JD2 iK 6 ".0111 Z ep#11 ; Sy#te!.Con#o e.VriteLine0Gath.)$#00)JD2 iK 6 ".01113 re#u t 9 03 <3 <3 <3 if 0re#u t 99 "1 ; Sy#te!.Con#o e.VriteLine0&Re#u t i# correct!&13 < e #e ; Sy#te!.Con#o e.VriteLine0&Re#u t i# incorrect!&13
)(6
Thinking in C
www.ThinkingIn.!et
< < pu$ ic #tatic *oid p ain0dou$ eJ2K )2int n1 ; int i3 int D3 int %3 dou$ e #3 dou$ e d3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; d 9 0.03 for0 % 9 03 % W9 0D 6 "13 %RR1 ; # 9 0.03 for0 i 9 03 i W9 0% 6 "13 iRR1 ; # 9 0# R 0)J%2iK = )JD2iK113 <3 # 9 00)JD2%K 6 #1 / )J%2%K13 )JD2%K 9 #3 d 9 0d R 0# = #113 <3 d 9 0)JD2DK 6 d13 )JD2DK 9 Gath.S7rt0d13 <3 < pu$ ic #tatic *oid unro 0dou$ eJ2K )2int n1 ; int i3 int D3 int %3 dou$ e #3 dou$ e d3 dou$ e #03 dou$ e #"3 dou$ e #23 dou$ e #T3 dou$ e aiD3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; d 9 0.03 for0 % 9 03 % W9 0D 6 E13 % R9 E1 ; #0 9 0.03 #" 9 0.03
)(#
#2 9 0.03 #T 9 0.03 for0 i 9 03 i W9 0% 6 "13 iRR1 ; aiD 9 )JD2iK3 #0 9 0#0 R 0)J0% R 012iK = aiD113 #" 9 0#" R 0)J0% R "12iK = aiD113 #2 9 0#2 R 0)J0% R 212iK = aiD113 #T 9 0#T R 0)J0% R T12iK = aiD113 <3 #0 9 00)JD20% R 01K 6 #01 / )J0% R 0120% R 01K13 )JD20% R 01K 9 #03 #" 9 0#" R 0)J0% R "12%K = )JD2%K113 #" 9 00)JD20% R "1K 6 #"1 / )J0% R "120% R "1K13 )JD2 % R "K 9 #"3 #2 9 00#2 R 0)J0% R 212%K = )JD2%K11 R 0)J0% R 2120% R "1K = )JD20% R "1K113 #2 9 00)JD20% R 21K 6 #21 / )J0% R 2120% R 21K13 )JD20% R 21K 9 #23 #T 9 000#T R 0)J0% R T12%K = )JD2%K11 R 0)J0% R T120% R "1K = )JD20% R "1K11 R 0)J0% R T120% R 21K = )JD20% R 21K113 #T 9 00)JD20% R T1K 6 #T1 / )J0% R T120% R T1K13 )JD20% R T1K 9 #T3 d 9 0000d R 0#0 = #011 R 0#" = #"11 R 0#2 = #211 R 0#T = #T113 <3 for0 % 9 00D / E1 = E13 % W9 0D 6 "13 %RR1 ; # 9 0.03 for0 i 9 03 i W9 0% 6 "13 iRR1 ; # 9 0# R 0)J%2iK = )JD2iK113 <3 # 9 00)JD2%K 6 #1 / )J%2%K13 )JD2%K 9 #3 d 9 0d R 0# = #113 <3 d 9 0)JD2DK 6 d13 )JD2DK 9 0Gath.S7rt0d113
)(&
Thinking in C
www.ThinkingIn.!et
<3 < < ///:8 5*r c*+pari#*n, here# an eDuivalent pr*gra+ in "ava, u#ing 4agged array#1 //:c0E:Cho e#%y.Da*a /= :e!on#tration progra! #ho.ing u#e of the )rray pac%age =/ /= =/ /= CUOL+Sa/: 'hi# progra! co!pute# the Cho e#%y factor O of a =/ /= #y!!etric po#iti*e definite !atrix ) #uch that ) 9 O'O .here =/ /= O' i# the tran#po#e of O. O i# an upper triangu ar !atrix. =/ i!port Da*a.!ath.=3 pu$ ic c a## Cho e#%yXnati*eXarray ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; int n 9 "0003 // pro$ e! #iMe dou$ eJKJK ) 9 ne. dou$ eJnKJnK3 // n x n 26 di!en#iona array dou$ e op#3 dou$ e !f op#3 /= = Co!pute Cho e#%y factor u#ing an opti!iMed code. =/ initia iMe0)2n13 //)ccurate ./i "0!# on C'/2a/,-2 ./i PP!# on Vin>P/>I dou$ e t" 9 0"e6T=Sy#te!.current'i!eGi i#0113 unro 0)2n13 dou$ e t2 9 0"e6T=Sy#te!.current'i!eGi i#0113 dou$ e ti!e 9 0t2 6 t"13
)('
op# 9 0000".0 = n1 = n1 = n1 / T.013 !f op# 9 00".0e6? = op#1 / ti!e13 Sy#te!.out.print0&Opti!iMed code2 'i!e: &Rti!eR& Gf op#:&R!f op#R& &13 *a idate0)2n13 /= = Co!pute Cho e#%y factor u#ing a #traightfor.ard code. =/ initia iMe0)2n13 t" 9 0"e6T=Sy#te!.current'i!eGi i#0113 p ain0)2n13 t2 9 0"e6T=Sy#te!.current'i!eGi i#0113 ti!e 9 0t2 6 t"13 op# 9 0000".0 = n1 = n1 = n1 / T.013 !f op# 9 00".0e6? = op#1 / ti!e13 Sy#te!.out.print0&Si!p e code2 'i!e: &Rti!eR& Gf op#:&R!f op#R& &13 *a idate0)2n13 < pu$ ic #tatic *oid initia iMe0dou$ eJKJK )2int n1 ; int i3 int D3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; for0 i 9 03 i W9 0n 6 "13 iRR1 ; )JDKJiK 9 03 <3 <3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; for0 i 9 D3 i W9 0n 6 "13 iRR1 ; )JiKJDK 9 D R "3 <3 <3 < pu$ ic #tatic *oid *a idate0dou$ eJKJK )2int n1 ; int i3 int D3 int re#u t3
)1(
Thinking in C
www.ThinkingIn.!et
dou$ e ep#3 re#u t 9 "3 ep# 9 ".0e6"03 for0 i 9 03 i W9 0n 6 "13 iRR1 ; for0 D 9 i3 D W9 0n 6 "13 DRR1 ; if 000Gath.a$#00)JDKJiK 6 ".0111 Z ep#11 ; re#u t 9 03 <3 <3 <3 if 0re#u t 99 "1 ; Sy#te!.out.print n0&Re#u t i# correct!&13 < e #e ; Sy#te!.out.print n0&Re#u t i# incorrect!&13 < < pu$ ic #tatic *oid p ain0dou$ eJKJK )2int n1 ; int i3 int D3 int %3 dou$ e #3 dou$ e d3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; d 9 0.03 for0 % 9 03 % W9 0D 6 "13 %RR1 ; # 9 0.03 for0 i 9 03 i W9 0% 6 "13 iRR1 ; # 9 0# R 0)J%KJiK = )JDKJiK113 <3 # 9 00)JDKJ%K 6 #1 / )J%KJ%K13 )JDKJ%K 9 #3 d 9 0d R 0# = #113 <3 d 9 0)JDKJDK 6 d13 )JDKJDK 9 Gath.#7rt0d13 <3 < pu$ ic #tatic *oid unro int i3 0dou$ eJKJK )2int n1 ;
)11
int D3 int %3 dou$ e #3 dou$ e d3 dou$ e #03 dou$ e #"3 dou$ e #23 dou$ e #T3 dou$ e aiD3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; d 9 0.03 for0 % 9 03 % W9 0D 6 E13 % R9 E1 ; #0 9 0.03 #" 9 0.03 #2 9 0.03 #T 9 0.03 for0 i 9 03 i W9 0% 6 "13 iRR1 ; aiD 9 )JDKJiK3 #0 9 0#0 R 0)J0% R 01KJiK = aiD113 #" 9 0#" R 0)J0% R "1KJiK = aiD113 #2 9 0#2 R 0)J0% R 21KJiK = aiD113 #T 9 0#T R 0)J0% R T1KJiK = aiD113 <3 #0 9 00)JDKJ0% R 01K 6 #01 / )J0% R 01KJ0% R 01K13 )JDKJ0% R 01K 9 #03 #" 9 0#" R 0)J0% R "1KJ%K = )JDKJ%K113 #" 9 00)JDKJ0% R "1K 6 #"1 / )J0% R "1KJ0% R "1K13 )JDKJ% R "K 9 #"3 #2 9 00#2 R 0)J0% R 21KJ%K = )JDKJ%K11 R 0)J0% R 21KJ0% R "1K = )JDKJ0% R "1K113 #2 9 00)JDKJ0% R 21K 6 #21 / )J0% R 21KJ0% R 21K13 )JDKJ0% R 21K 9 #23 #T 9 000#T R 0)J0% R T1KJ%K = )JDKJ%K11 R 0)J0% R T1KJ0% R "1K = )JDKJ0% R "1K11 R 0)J0% R T1K J0% R 21K = )JDKJ0% R 21K113 #T 9 00)JDKJ0% R T1K 6 #T1 / )J0% R T1KJ0% R T1K13 )JDKJ0% R T1K 9 #T3
)1)
Thinking in C
www.ThinkingIn.!et
d 9 0000d R 0#0 = #011 R 0#" = #"11 R 0#2 = #211 R 0#T = #T113 <3 for0 % 9 00D / E1 = E13 % W9 0D 6 "13 %RR1 ; # 9 0.03 for0 i 9 03 i W9 0% 6 "13 iRR1 ; # 9 0# R 0)J%KJiK = )JDKJiK113 <3 # 9 00)JDKJ%K 6 #1 / )J%KJ%K13 )JDKJ%K 9 #3 d 9 0d R 0# = #113 <3 d 9 0)JDKJDK 6 d13 )JDKJDK 9 0Gath.#7rt0d113 <3 < <///:8 ,hen the t!* pr*gra+# are run *n +y P/E'$$, the#e are the re#ult#1 Ch*le#ky)e;e1 4ava Ch*le#ky`native`array1
'u##ar5
Thi# #ee+ingly ela3*rate +echani#+ 9*r initiali7ati*n, the c*n#truct*r, #h*uld give y*u a #tr*ng hint a3*ut the critical i+p*rtance placed *n initiali7ati*n in the language) =# Str*u#trup !a# de#igning C@@, *ne *9 the 9ir#t *3#ervati*n# he +ade a3*ut pr*ductivity in C !a# that i+pr*per initiali7ati*n *9 varia3le# cau#e# a #igni9icant p*rti*n *9 pr*gra++ing pr*3le+#) The#e kind# *9 3ug# are hard t* 9ind, and #i+ilar i##ue# apply t* i+pr*per cleanup) Becau#e c*n#truct*r# all*! y*u t* guarantee pr*per initiali7ati*n and cleanup Gthe c*+piler !ill n*t all*! an *34ect t* 3e created !ith*ut the pr*per c*n#truct*r call#H, y*u get c*+plete c*ntr*l and #a9ety) -n C@@, de#tructi*n i# Duite i+p*rtant 3ecau#e *34ect# created !ith new +u#t 3e e;plicitly de#tr*yed) -n C#, the gar3age c*llect*r aut*+atically relea#e# the +e+*ry 9*r all *34ect#, #* the eDuivalent cleanup +eth*d in
)13
C# i#nt nece##ary +uch *9 the ti+e) -n ca#e# !here y*u d*nt need de#truct*rElike 3ehavi*r, C## gar3age c*llect*r greatly #i+pli9ie# pr*gra++ing, and add# +uchEneeded #a9ety in +anaging +e+*ry) H*!ever, the gar3age c*llect*r d*e# add a runEti+e c*#t, the e;pen#e *9 !hich i# di99icult t* put int* per#pective 3ecau#e *9 the *ther per9*r+ance ra+i9icati*n# *9 the -L and CRL appr*ach t* 3inary 9ile#) Becau#e *9 the guarantee that all *34ect# !ill 3e c*n#tructed, there# actually +*re t* the c*n#truct*r than !hat i# #h*!n here) -n particular, !hen y*u create ne! cla##e# u#ing either com"osition *r inheritance the guarantee *9 c*n#tructi*n al#* h*ld#, and #*+e additi*nal #ynta; i# nece##ary t* #upp*rt thi#) :*ull learn a3*ut c*+p*#iti*n, inheritance, and h*! they a99ect c*n#truct*r# in 9uture chapter#)
%&ercises
)14
Thinking in C
www.ThinkingIn.!et
)15
?ata encap#ulati*n, inheritance, and p*ly+*rphi#+ are the c*rner#t*ne capa3ilitie# *9 *34ect *rientati*n, 3ut their u#e d*e# n*t aut*+atically create g**d *r even pa##a3le de#ign) >**d #*9t!are de#ign ari#e# 9r*+ dividing a pr*3le+ int* c*herent part# and tackling th*#e part# independently, in a +anner that# ea#y t* te#t and change) O34ect *rientati*n 9acilitate# 4u#t #uch partiti*ning *9 c*ncern#, 3ut reDuire# y*u t* under#tand the 9*rce# that +ake #*+e #*9t!are de#ign# 3etter than *ther#) The#e 9*rce#, c*upling and c*he#i*n, are univer#al t* all #*9t!are #y#te+# and pr*vide a 3a#i# 9*r c*+paring #*9t!are architecture# and de#ign#)
,hen !e #peak *9 IarchitectureJ and Ide#ignJ in #*9t!are #y#te+#, !e can 3e #peaking *9 +any di99erent thing# P the phy#ical #tructure *9 the net!*rk, the #et *9 *perating #y#te+ and #erver pr*vider# ch*#en, the graphic de#ign *9 the entire clientE 9acing ,e3#ite, the u#erEinter9ace de#ign *9 applicati*n# !e !rite, *r the internal #tructure *9 the pr*gra+# 3eing !ritten) =ll *9 the#e 9act*r# are i+p*rtant and it# a #ha+e that !e have n*t yet devel*ped a c*++*n v*ca3ulary 9*r giving each *9 the+ their 4u#t attenti*n) 5*r the purp*#e# *9 thi# chapter, !e are #*lely c*ncerned !ith the internal #tructure *9 pr*gra+# P deci#i*n# that !ill 3e +ade and e+3*died in the C# #*urce c*de y*u !rite)
)1#
year# later, the pendulu+ predicta3ly #!ing# the *ther !ay) Thi# vie! *9 #*9t!are h*ld# that, like it *r n*t, c*de de9ine# the #*9t!are# 3ehavi*r and that diagra+# and #peci9icati*n# d* n*t generally capture the real i##ue# at hand !hen de#igning pr*gra+#) Pr*p*nent# *9 thi# vie! argue that the #*9t!are as architecture vie! i# pri+arily pu#hed 3y c*n#ultant# and vend*r# #elling e;pen#ive t**l# that generate a l*t *9 paper 3ut little pr*duct) Until recently, the e#calati*n *9 de9ect c*#t# *ver ti+e !a# the tru+p card 9*r the #*9t!are as architecture adv*cate#) -n 06(%, Barry B*eh+ pu3li#hed a paper in !hich he e#ta3li#hed that a de9ect c*rrected 9*r U0 in the reDuire+ent# pha#e c*uld c*#t U0$$ t* 9i; *nce depl*yed0) ,ith th*#e ec*n*+ic#, 3ig upE9r*nt e99*rt# !ere *3vi*u#ly !*rth!hile) -t# d*u3t9ul that #uch nu+3er# have +uch +eaning t*dayQ B*eh+ hi+#el9 c*ncluded in 2$$0 that 9*r I#+aller, n*ncritical #*9t!are #y#te+#J the c*#t e#calati*n !a# I+*re like '10 than 0$$10)J The e;pl*#ively p*pular #et *9 practice# called E;tre+e Pr*gra++ing i# 3a#ed *n Ithe technical pre+i#e Zthat\ the c*#t *9 change Zcan ri#e\ +uch +*re #l*!ly, eventually reaching an a#y+pt*te)J 2 S* #h*uld y*u vie! #*9t!are devel*p+ent a# an undertaking akin t* 3uilding a 3ridge *r a# *ne akin t* gr*!ing a gardenF ,ell, there are a 9e! thing# !e can #ay 9*r #ure a3*ut #*9t!are devel*p+ent1 Pr*gra++er# al!ay# *vere#ti+ate their l*ngEter+ pr*ductivity) A*#t large #*9t!are pr*4ect# #till c*#t +*re than e;pected) A*#t pr*4ect# #till take l*nger t* 9ini#h than e;pected) Aany are cancelled pri*r t* c*+pleti*n and +any, *nce depl*yed, 9ail t* achieve the 3u#ine## g*al# they !ere intended t* #erve) Bey*nd the#e generally pe##i+i#tic #tate+ent#, the variance# 3et!een individual#, tea+#, c*+panie#, and indu#try #ect*r# #!a+p the #tati#tic#) U#e9ul #*9t!are #y#te+# range 9r*+ pr*gra+# that are a 9e! hundred line# l*ng Gthe #*urce c*de t* ping i# #h*rter than #*+e *9 the #a+ple# in thi# 3**kKH t* pr*gra+# in e;ce## *9 a +illi*n line# *9 c*de) Tea+# can range 9r*+ individual# t* hundred#) = #ucce##9ul pr*gra+ +ay 3e a 9uncti*nE*pti+i7er that, *n a #ingle run *ut *9 a th*u#and, pr*duce# a +eaning9ul re#ult *r a li9e #upp*rt #y#te+ that, literally, never 9ail# Gye#, pr*va3ly c*rrect #*9t!are i# p*##i3leH) S* !hen pe*ple #tart #p*uting #tati#tic# *r pr*n*unce+ent# a3*ut I3e#t practice#,J at 3e#t theyre *verEgenerali7ing and at !*r#t theyre trying t* #care y*u int* 3uying !hatever it i# theyre #elling /) ,e d* kn*! that there# at lea#t *ne +a4*r 9la! in the #*9t!are a# architecture +etaph*r, and that i# that unlike a 3uilding that re+ain# under c*n#tructi*n until a de#ignated Igrand *pening,J #*9t!are #h*uld 3e 3uilt and depl*yed incre+entally P i9 n*t *ne Ir**+ at a ti+eJ then at lea#t I*ne 9l**r at a ti+e)J Thi# i#, *9 c*ur#e, ea#ier in #*+e #ituati*n# than in *ther#, 3ut *ne *9 the great trui#+# *9 #*9t!are
0 B) B*eh+ and C) Ba#ili, YS*9t!are ?e9ect Reducti*n T*p 0$ Li#t,Y -EEE C*+puter, -EEE C*+puter
2 E;tre+e Pr*gra++ing E;plained, pg) 2/ / Be e#pecially du3i*u# i9 y*u hear I%$^ 9ailure rate)J Thi#, like the U/$$B that :2N 9ailure# !ere g*ing
t* c*#t, i# a nu+3er that *riginated in a #ingle pr*9itE+*tivated #tudy 3ut !hich ha# 3een repeated #* +any ti+e# that it# taken *n a li9e *9 it# *!n)
)1&
Thinking in C
www.ThinkingIn.!et
devel*p+ent +anage+ent i# that 9r*+ the 9ir#t !eek# *9 the pr*4ect, y*u #h*uld 3e a3le t* at lea#t p*tentially #hip y*ur late#t 3uild)
)1'
))(
Thinking in C
www.ThinkingIn.!et
Thi# de#ign 9rag+ent i# typical *9 the type# *9 #tructure# *ne #ee# in 3u#ine##Etier architecture#1 u#eEca#e# are rei9ied Ga 9ancy !*rd 9*r Iin#tantiated a# *34ect#JH, there i# e;ten#ive u#e *9 the Strategy pattern, and there are l*t# *9 cla##e# !hich d* n*t +ap t* tangi3le *34ect# in the real !*rld) The 3u#ine## rule I,hen a pr*duct i# di#c*ntinued 3y it# +anu9acturer, place it *n #ale until !e have le## than a d*7en in invent*ry, then price it 9*r clearance,J +ight l**k like thi# in c*de1 c a## C ear:i#continued5te!#; #tatic readon y int G5CXB+HOR+XCL+)R)CC+ 9 "23 :i#continued0Stoc%aeepingOnitJK ine1; foreach0Stoc%aeepingOnit #%u in ine1; int count 9 #tore5n*entory.Count0 ine13 if0count W G5CXB+HOR+XCL+)R)CC+1; #%u.-ricingStrategy 9 ne. C earance-rice013 <e #e; #%u.-ricingStrategy 9 ne. Sa e-rice013 < < < < -n a Si+ulati*n architecture, a #toc(EeepingVnit !*uld price it#el9 !hen di#c*ntinued1 c a## Stoc%aeepingOnit; //... #tatic int nu!$er5nStoc%3 #tatic readon y int G5CXB+HOR+XCL+)R)CC+ 9 "23
))1
:i#continue01; if0nu!$er5nStoc% W G5CXB+HOR+XCL+)R)CC+1; thi#.-ricingStrategy 9 ne. C earance-rice013 <e #e; thi#.-ricingStrategy 9 ne. Sa e-rice013 < < < =# can 3e #een in thi# de#ign 9rag+ent, 3u#ine##Etier architecture# tend t* l**k le## c*he#ive than #i+ulati*n architecture# 9*r #+all pr*3le+#) -n realE!*rld applicati*n#, th*ugh, there are typically d*7en# *r hundred# *9 u#eEca#e#, each *9 !hich +ay have #everal 3u#ine## rule# a##*ciated !ith it) Bu#ine## rule# tend t* inv*lve a l*t *9 di99erent 9act*r# and yet are the natural unit *9 th*ught 9*r the d*+ain e;pert#, #* 3u#ine##Etier architecture# tend t* re#ult in clearer line# *9 c*++unicati*n 3et!een devel*p+ent tea+# and d*+ain e;pert#) I,e need t* a#k a Due#ti*n a3*ut the Tprice di#c*ntinued ite+# 3u#ine## rule#J i# +uch clearer t* d*+ain e;pert# than I,e need t* a#k a Due#ti*n a3*ut h*! an SNU price# it#el9 !hen it# di#c*ntinued)J
La5ered )rchitectures
Once up*n a ti+e, c*+puter# !ere pri+arily u#ed t* aut*+ate repetitive calculati*n#1 tide chart#, gunnery ta3le#, cen#u# #tati#tic#) *!aday#, CPUEinten#ive +ath i# *ne *9 the lea#t 9reDuent ta#k# a#ked *9 a c*+puter) - i+agine there are +any y*unger pe*ple !h* d*nt kn*! that, e##entially, c*+puter# are n*thing 3ut 3inary calculat*r#) Thi# i# 3ecau#e layer a9ter layer *9 increa#ing a3#tracti*n ha# 3een placed 3et!een the endEu#er and the underlying hard!are) -+ n*t #ure thi# i# entirely 3ene9icial !hen it c*+e# t* pr*gra++ing, 3ut - certainly d*nt !ant t* g* 3ack t* the day# !hen the 3ig trick in graphic# pr*gra++ing !a# d*ing y*ur !*rk !hen the #creen !a# d*ing a vertical retrace) Layer# *9 a3#tracti*n are a+*ng the +*#t p*!er9ul architecture# *ver the l*ng ter+, re+*ving entire area# 9r*+ the c*ncern# *9 later pr*gra++er#) Layered architecture# are c*++*nly u#ed !hen i+ple+enting pr*t*c*l#, #ince pr*t*c*l# the+#elve# have a tendency t* 3e layered *n t*p *9 *ther pr*t*c*l#) Layer# are al#* u3iDuit*u# !hen !*rking !ith device driver# *r e+3edded #y#te+# Gn*t likely #cenari*# 9*r C# t*day, 3ut !h* kn*!# !hat t*+*rr*! h*ld#FH) The three place# !here - can anticipate a C# tea+ l**king t*!ard# layered architecture# are in the area# *9 *34ectErelati*nal +apping, c*ncurrent li3rarie#, and net!*rk c*++unicati*n#) The 9ir#t t!* are area# !here the ) ET 9ra+e!*rk d*e# n*t pr*vide #u99icient a3#tracti*n and the la#t i# a 9a#tE+*ving area !here C# ha# the p*tential t* really #hine) Layered architecture# al!ay# #ee+ t* 3e di99icult t* get right) -n a layered architecture, all cla##e# in a layer #h*uld #hare the #a+e a3#tracti*n layer, and each layer #h*uld 3e a3le t* per9*r+ all it# 9uncti*n# 3y *nly relying *n it# *!n cla##e# and
)))
Thinking in C
www.ThinkingIn.!et
th*#e *9 the layer i++ediately I3el*!J it) Pulling thi# *99 reDuire# a +*re c*+plete under#tanding *9 the pr*3le+ d*+ain than i# typically availa3le in the early #tage# *9 #y#te+ devel*p+ent, !hen architecture i# decided) S* u#ually !ith a layered architecture, y*u 9ace t!* p*##i3ilitie#1 a l*t *9 up9r*nt e99*rt *r 3eing very c*n#cienti*u# a3*ut +*ving *34ect# and re9act*ring 3a#ed *n a3#tracti*n level) The great 3ene9it# *9 a layered architecture c*+e d*!n the line !hen an under#tanding *9 the !*rking *9 the l*!er level# i# rarely *r never needed) Thi# i# the #ituati*n t*day !ith, #ay, graphic#, !here n* *ne 3ut ga+e pr*gra++er# need c*ncern the+#elve# !ith the c*+ple; detail# *9 #creen +*de#, pi;el a#pect#, and di#play page# Gand !ith +*dern ga+e engine# 3uilt *n ?irectB and the prevalence *9 graphic# accelerat*r card#, apparently even ga+e pr*gra++er# are +*ving a!ay 9r*+ thi# level *9 detailH)
Pro+le#;'olving )rchitectures
-t# increa#ingly rare t* devel*p a #y#te+ that #*lve# a pr*3le+ that i# *ther!i#e intracta3le) Thi# i# t** 3ad, 3ecau#e there are 9e! thrill# greater than devel*ping a t**l and !atching that t**l acc*+pli#h #*+ething 3ey*nd y*ur capa3ilitie#) Such #y#te+# *9ten reDuire the devel*p+ent *9 #peciali7ed pr*3le+E#*lving architecture# EE 3lack3*ard #y#te+#, 9uncti*n *pti+i7er#, 9u77y l*gic engine#, #upp*rtEvect*r +achine#, and #* 9*rth) The#e pr*3le+ #*lver# +ay the+#elve# 3e architected in any nu+3er *9 !ay#, #* in a #en#e y*u c*uld #ay that thi# i# a variati*n *9 the layered architecture, !here the pr*3le+E#*lver i# a 9*undati*n *n !hich the input# and +etaE3ehavi*r rely) But t* #*lve a pr*3le+ u#ing, #ay, a genetic *pti+i7er *r e;pert #y#te+ reDuire# an under#tanding *9 the characteri#tic# *9 the pr*3le+E#*lver, n*t #* +uch an under#tanding *9 the !ay that the pr*3le+E#*lver i# i+ple+ented) S* i9 y*ure 9*rtunate en*ugh t* 3e !*rking in #uch a d*+ain, y*u #h*uld c*ncentrate *n under#tanding the c*re alg*rith+# and #eeing i9 there# a di#c*nnect 3et!een the acade+ic !*rk *n the pr*3le+E#*lver and the ta#k at handQ +any #uch pr*4ect# 9ail 3ecau#e the pr*3le+E#*lver reDuire# that the input *r +etaEdata have a certain +athe+atical characteri#tic) =# an *34ect le##*n, re#earch *n arti9icial neural net!*rk# langui#hed 9*r +*re than a decade 3ecau#e the *riginal !*rk u#ed a di#c*ntinu*u# Iactivati*n 9uncti*n)J Once #*+e*ne reali7ed the +athe+atical pr*3le+ !ith that, a 9a+*u# Ipr**9J *9 their li+itati*n# 9ell 3y the !ay#ide and neural net# 3eca+e *ne *9 the h*tte#t re#earch t*pic# in +achine learningK
4is$atching )rchitectures
=n a+a7ingly large a+*unt *9 value can 3e derived 9r*+ #y#te+# that +anage the 9l*! *9 in9*r+ati*n !ith*ut a great deal *9 interacti*n !ith the underlying data) The#e #y#te+# typically deal !ith the general pr*3le+ *9 e99iciently +anaging the 9l*! 9r*+ +ultiple, unkn*!nEatEc*+pilati*nEti+e #*urce# *9 data !ith +ultiple, unkn$!nEatEc*+pilati*nEti+e #ink# 9*r data) IE99icientlyJ i# #*+eti+e# +ea#ured in ter+# *9 #peed, #*+eti+e# in ter+# *9 re#*urce#, and #*+eti+e# in ter+# *9
))3
relia3ility) S*+eti+e# the c*nnecti*n# are tran#ient, in !hich ca#e the architecture# are u#ually called Ievent drivenJ and #*+eti+e# the c*nnecti*n# are l*ngerEla#ting, in !hich ca#e +ultiple;ing and de+ultiple;ing architecture# are c*++*nly u#ed) ?i#patching #*luti*n# tend t* 3e relatively #+all and can #*+eti+e# 3e #een a# de#ign ele+ent#, n*t the architectural *rgani7ing principle 9*r an entire #y#te+ *r #u3#y#te+) But they *9ten play #uch a crucial r*le in delivering value that they de#erve the greate#t e+pha#i# in a #y#te+# devel*p+ent)
))4
Thinking in C
www.ThinkingIn.!et
S* there# really nothing that +atter# a3*ut de#ign e;cept h*! ea#y it i# t* change *r e;tend P the thing# that y*u have t* d* !hen y*u di#c*ver that y*ur e;i#ting c*de 9all# #h*rt in #*+e +anner) S* h*! d* y*u de#ign 9*r changeF
7irst. 4o (o 9ar#
-t# accepta3le 9*r y*u t* decide n*t t* +ake a change) -t# accepta3le 9*r y*ur change t* turn *ut t* 3e le## help9ul t* the u#er than the *riginal) -t# accepta3le 9*r y*ur change t* 3e dead !r*ng, either 3ecau#e *9 +i#c*++unicati*n *r 3ecau#e y*ur 9inger# #lipped *n the key# and typed a plu# in#tead *9 a +inu#) ,hat i# unaccepta3le i# 9*r y*u t* c*++it a change that 3reak# #*+ething el#e in y*ur c*de) =nd it i# unaccepta3le 9*r y*u t* n*t kn*! i9 y*ur change 3reak# #*+ething el#e in the c*de) :et #uch a path*l*gical #tate, !here the *nly thing that devel*per# can #ay a3*ut their c*de i# a pathetic I,ell, it shouldn:t cau#e anything el#e t* change,J i# very c*++*n) =l+*#t a# c*++*n are #ituati*n# !here change# d*, in 9act, #ee+ t* rand*+ly a99ect the 3ehavi*r *9 the #y#te+ a# a !h*le) -t i# c*unterintuitive, 3ut the nu+3er *ne thing y*u can d* t* #peed up y*ur devel*p+ent #chedule i# t* !rite a l*t *9 te#t#) -t d*e#nt pay *99 in the 9ir#t day#, 3ut it pay# *99 in 4u#t a 9e! !eek#) By the ti+e y*u get #everal +*nth# int* a pr*4ect, y*u !ill 3e +adly in l*ve !ith y*ur te#ting #uite) Once y*u devel*p a #y#te+ !ith a pr*per #uite *9 te#t#, y*u !ill c*n#ider it inc*+petent 9**li#hne## t* devel*p !ith*ut *ne) ,ith +*dern language# that #upp*rt re9lecti*n, it ha# 3ec*+e p*##i3le t* !rite te#t in9ra#tructure #y#te+# that di#c*ver at runti+e !hat +eth*d# are te#t# G3y c*nventi*n, +eth*d# that 3egin !ith the #tring Ite#tJH and running the+ and rep*rting the re#ult#) The pred*+inant #uch #y#te+ i# "Unit, created 3y Nent Beck and Erich >a++a) Several p*rt# and re9act*ring# *9 "Unit 9*r ) ET language# are availa3le, the +*#t p*pular *9 !hich i# Philip Craig# Unit) :*u can d*!nl*ad Unit 9r*+ http1<<nunit)#*urce9*rge)net) Unit i# a #traight9*r!ard p*rt *9 "Unit and d*e# n*t e;pl*it C# *r ) ET 9eature# #uch a# attri3ute#, !hich +ight 3e u#ed t* create ne! 9eature# G#uch a# 9iner c*ntr*l *9 !hich te#t# are applied t* a +eth*d *r cla##H)
S*9t!are #y#te+# are a+*ng the +*#t c*+ple; #tructure# 3uilt 3y hu+an#, and unintended c*n#eDuence# are an inevita3le part *9 +anipulating th*#e #y#te+#) The #peed !ith !hich y*u can change a #*9t!are #y#te+ i# dependent *n +any thing#, 3ut *n n*thing #* +uch a# y*ur a3ility t* i#*late a change in 3*th )
))5
))6
Thinking in C
www.ThinkingIn.!et
//W/+xa!p eZ There# n*thing !r*ng !ith thi# c*de a# it #tand#, "ouse6Hacation!rep() i# c*he#ive and n*t c*+ple;) But y*ur u#er c*+e# t* y*u and #ay# IOh, gee, !e *nly !ant t* deactivate the +ail i9 the vacati*n i# g*ing t* 3e l*nger than / day#)J ,hat d* y*u d*F The Duicke#t thing t* d* i# change H*u#e)Cacati*nPrepGH t*1 pu$ ic *oid Nacation-rep0int ength1 ; Sy#te!.Con#o e.VriteLine0&-reparing the hou#e for *acation&13 if0 ength Z T1; Sy#te!.Con#o e.VriteLine0&Stopping the !ai &13 !yGai .)cti*e 9 fa #e3 < Sy#te!.Con#o e.VriteLine0&Setting the auto!atic #prin%er&13 !y_arden.Sprin% erSet 9 true3 Sy#te!.Con#o e.VriteLine0&Uou#e i# prepared&13 < But a# #**n a# y*u type that, y*u !*rry a3*ut the I+agic nu+3erJ / in the c*de) Aagic nu+3er# are anathe+a t* +any pr*gra++er#, #* +uch #* that I?=:S`- ` ,EENJ i# +*re c*++*n than I%JK 5anatici#+ a#ide, +agic nu+3er# are a c*de #+ell that indicate# #*+e re9act*ring +ight 3e called 9*r) S* in#tead *9 I/J y*u +ight !ant !rite the c*de a# if0 ength Z !in:ay#HorGai Stoppage1 3ut that in#tantly rai#e# the Due#ti*n *9 !here t* de9ine that varia3le) :*u +ight de9ine it at the t*p *9 the Hacation!rep() +eth*d, 3ut that hardly acc*+pli#he# anything) = p**r pr*gra++er +ight +ake it a read*nly varia3le in#ide H*u#e, 3ut +*#t !*uld place it in#ide .ail, thu#1 pu$ ic *oid Nacation-rep0int ength1 ; if0 ength Z Gai .!in:ay#HorGai Stoppage ; Sy#te!.Con#o e.VriteLine0&Stopping the !ai &13 !yGai .)cti*e 9 fa #e3 < LetcL and c a## Gai ; #tatic readon y int G5CX:)/SXHORXS'O- 9 T3 pu$ ic int !in:ay#HorStoppage; get ; return G5CX:)/SXHORXS'O-3 < < LetcL "ouse6Hacation!rep() i# #till accepta3ly c*he#ive, alth*ugh it# increa#ed in c*+ple;ity) S* n*! y*ur u#er c*+e# t* y*u and #ay# I,ell, !e *nly !ant t* turn *n the #prinkler i9 the vacati*n i# during the gr*!ing #ea#*n) =nd i9 it# during the !inter, !e need t*
))#
3ring the plant# in#ide, in ca#e there# a 9r*#t)J -9 pr*gra++ing !ere a linear pr*ce##, y*ud 9*ll*! the #a+e pattern y*u did 9*r the +ail #t*ppage rule and y*u +ight end up !ith1 //W+xa!p eZ //WC a##ZNacationT.c#W/C a##Z u#ing Sy#te!3 na!e#pace Nacation"; c a## Uou#e ; Gai !yGai 9 ne. Gai 013 _arden !y_arden 9 ne. _arden013 pu$ ic *oid Nacation-rep0:ate'i!e #tart:ate2 int ength1 ; Sy#te!.Con#o e.VriteLine0&-reparing the hou#e for *acation&13 if0 ength Z Gai .!in:ay#BeforeStoppage1; Sy#te!.Con#o e.VriteLine0&Stopping the !ai &13 !yGai .)cti*e 9 fa #e3 < int !onth 9 #tart:ate.Gonth3 Sea#on #ea#on 9 _arden.Sea#onHor0!onth13 #.itch0#ea#on1; ca#e Sea#on._ro.ingSea#on : Sy#te!.Con#o e.VriteLine0&Setting the auto!atic #prin%er&13 !y_arden.Sprin% erSet 9 true3 $rea%3 ca#e Sea#on.Vinter : Sy#te!.Con#o e.VriteLine0&Bringing the p ant# in#ide&13 foreach0- ant p in !y_arden.- ant#1; if0p.Out#ide1; p.Bring5n#ide013 < < $rea%3 defau t: Sy#te!.Con#o e.VriteLine0&Lea*ing the garden a one&13 $rea%3 < Sy#te!.Con#o e.VriteLine0&Uou#e i# prepared&13 < pu$ ic #tatic *oid Gain01 ; Uou#e !yUou#e 9 ne. Uou#e013 !yUou#e.Nacation-rep0:ate'i!e.Co.2 E13
))&
Thinking in C
www.ThinkingIn.!et
< < c a## Gai ; #tatic readon y int G5CX:)/SXB+HOR+XS'O--)_+ 9 T3 pu$ ic #tatic int !in:ay#BeforeStoppage; get ; return G5CX:)/SXB+HOR+XS'O--)_+3 < < $oo acti*e3 pu$ ic $oo )cti*e; get ; return acti*e3< #et ; acti*e 9 *a ue3< < < c a## _arden ; $oo #prin% erOn3 pu$ ic $oo Sprin% erSet; get ; return #prin% erOn3< #et ; #prin% erOn 9 *a ue3< < - antJK p ant# 9 ne. - antJK; ne. _eraniu!012 ne. Hicu#01 <3 pu$ ic - antJK - ant#; get ; return p ant#3 < < pu$ ic #tatic Sea#on Sea#onHor0int !onth1; if0!onth Z9 T @@ !onth W9 "01 return Sea#on._ro.ingSea#on3 if0!onth 99 "01 return Sea#on.:or!ant3 return Sea#on.Vinter3 < < enu! Sea#on; _ro.ingSea#on2 :or!ant2 Vinter < c a## - ant; protected $oo i#Out#ide 9 true3
pu$ ic $oo Out#ide; get ; return i#Out#ide3 < #et ; i#Out#ide 9 *a ue3 < <
))'
pu$ ic *oid Bring5n#ide01; Sy#te!.Con#o e.VriteLine0&Bringing a p ant in#ide&13 thi#.Out#ide 9 fa #e3 < < c a## _eraniu! : - ant; < c a## Hicu# : - ant; pu$ ic Hicu#01; thi#.Out#ide 9 fa #e3 < < < *!, "ouse6Hacation!rep() i# pa##ed 3*th a length and a #tarting date) -t deter+ine# the +*nth *9 the vacati*n, u#e# arden6#eason:or(int month) t* deter+ine in !hat Sea#*n the vacati*n !ill happen, and take# the nece##ary #tep# depending *n that) =# a pr*cedural +eth*d, Hacation!rep() !*uld #till 3e c*n#idered 9airly c*he#ive) Everything it d*e# ha# #*+ething t* d* !ith preparing the h*u#e 9*r vacati*n, it# 4u#t turning *ut t* 3e a +*re c*+ple; ta#k than it !a# *n *ur 9ir#t iterati*n) But 9r*+ an *34ect #tandp*int, #*+ething# g*ne a!ry) The +*#t egregi*u# pr*3le+ i# clearly the call in#ide the c*nditi*nal in#ide the l**p in#ide the #!itch) Oh, - need t* e;plain !here that i#F That# part *9 the pr*3le+ P deeply ne#ted c*ntr*l #tructure# are inherently c*+ple;) -+ re9erring t* the#e line#1 if0p.Out#ide1; p.Bring5n#ide013 < The e;ecuti*n *9 thi# 3l*ck i# 3a#ed *n the #tate *9 a re9erenced *34ect Gthe !lant pH, 3ut the 3l*ck *nly c*ntain# call# t* that #a+e *34ect) -n *ther !*rd#, 3*th the Iguard c*nditi*nJ and the c*n#eDuence are !*rking *n e;ternal *34ect#) =lth*ugh *ne c*uld argue that "ouse6Hacation!rep() i# #till 9airly c*he#ive, thi# 3l*ck indicate# that !lant6BringBnside() i# n*t c*he#ive, 3ecau#e it d*e# n*t c*ntain the l*gically nece##ary check t* +ake #ure that *nly plant# that are currently *ut#ide are 3r*ught in#ide) Thu#, !ell change !lant6BringBnside() t*1 pu$ ic *oid Bring5n#ide5fCece##ary01; if0thi#.Out#ide1; Sy#te!.Con#o e.VriteLine0&Bringing a p ant in#ide&13 thi#.Out#ide 9 fa #e3 < < S*+ething# !r*ng !ith thi#) = #ingle +eth*d !hich d*e# +*re than *ne thing i# *ne type *9 c*he#i*n +i#take, t!* +eth*d# that d* e##entially the #a+e thing i# an*ther) The pu3lic 1utside pr*perty *9 !lant ha# a set +eth*d) Our ne!ly !ritten BringBnsideBf,ecessary() d*e# n*thing that i#nt l*gically d*ne in#ide that set )3( Thinking in C www.ThinkingIn.!et
+eth*d, !ith the e;cepti*n *9 printing #*+ething t* the C*n#*le) -9 the di#tincti*n 3et!een printing t* the c*n#*le *r n*t i# i+p*rtant, then +ay3e !e c*uld u#e a para+eter The #a+e pe*ple !h* +i#takenly 3elieve that Si+ulati*n architecture# are the *nly ItrueJ *34ectE*riented architecture# !ill #ay that thi# c*de i# already !r*ng) They !ill, very predicta3ly, dra! thi# diagra+1
and !rite thi# c*de1 //W+xa!p eZ //WC a##ZNacation2.c#W/C a##Z na!e#pace Nacation2; interface 5-repara$ e; *oid Nacation-rep013 < c a## Uou#e : 5-repara$ e; 5-repara$ eJK !y-repara$ e# 9 ; ne. Gai 012 ne. _arden01 <3 pu$ ic *oid Nacation-rep01 ; Sy#te!.Con#o e.VriteLine0&-reparing the hou#e for *acation&13 foreach05-repara$ e p in !y-repara$ e#1; p.Nacation-rep013 < Sy#te!.Con#o e.VriteLine0&Uou#e i# prepared&13 < pu$ ic #tatic *oid Gain01 ; Uou#e !yUou#e 9 ne. Uou#e013 !yUou#e.Nacation-rep013 Cha"ter 5* >iding the Im"lementation )31
< < c a## Gai : 5-repara$ e; $oo acti*e3 pu$ ic $oo )cti*e; get ; return acti*e3< #et ; acti*e 9 *a ue3< < pu$ ic *oid Nacation-rep01; Sy#te!.Con#o e.VriteLine0&Gai it#e f&13 thi#.acti*e 9 fa #e3 < < c a## _arden : 5-repara$ e ; $oo #prin% erOn3 pu$ ic $oo Sprin% erSet; get ; return #prin% erOn3< #et ; #prin% erOn 9 *a ue3< < pu$ ic *oid Nacation-rep01; Sy#te!.Con#o e.VriteLine0&_arden turning on the #prin% er&13 #prin% erOn 9 true3 < < < //W/+xa!p eZ There# n*thing !r*ng !ith the c*de in "ouse6Hacation!rep() P it# c*he#ive and it# n*t c*+ple;) There# n* rea#*n, at thi# p*int, t* deacti*ating
S*+eti+e in y*ur career, y*ure g*ing t* !*rk *n a pr*4ect !here every ti+e y*u +ake a change, it cau#e# #*+ething el#e t* 3reak) -t !ill 3e a +i#era3le, #*ulE deadening and inter+ina3le peri*d) -t !ill eventually end, 3ut *nly 3ecau#e the c*+pany cancel# the pr*4ect *r g*e# 3ankrupt) The#e terri3le e;perience# *ccur 3ecau#e it i# i+p*##i3le t* i#*late a change) There i# *nly *ne p*##i3le cau#e 9*r thi#1 the area y*u are atte+pting t* change i# cou"led !ith an*ther area *9 the pr*gra+) Okay, there# a #+allE3utE9inite p*##i3ility that the pr*3le+ i# cau#ed 3y an underlying *perating #y#te+ *r hard!are 9la! that# triggered 3y #*+e n*nEpr*gra++atic a#pect *9 the !*rk y*ure d*ing G#uch 9la!# are
)3)
Thinking in C
www.ThinkingIn.!et
pr*perly called I3ug#J and +*#t pr*gra++er# enc*unter the+ a c*uple *9 ti+e# per decade) Pr*gra++atic +i#take# are called Ide9ect#J and happen, *h, a3*ut t!enty ti+e# per dayH) C*upling, *r dependence, i# the degree t* !hich a +eth*d *r cla## relie# *n *ther +eth*d# *r cla##e# t* acc*+pli#h it# ta#k) C*upling l*!er# +eth*d c*+ple;ity G3y relying *n #*+ething el#e t* d* a calculati*nH, 3ut increa#e# de#ign c*+ple;ity) C*upling ha# a c*+ple; relati*n#hip !ith c*he#i*n) = c*he#ive +eth*d d*e# *ne and *nly *ne pr*ce##, a c*he#ive cla## encap#ulate# l*gically related 3ehavi*r and data) 5*r all 3ut the rare#t cla##e#, the Iand *nly *neJ and Il*gically relatedJ c*n#traint# reDuire the u#e *9 *ther cla##e#) S* #plitting a #ingle ta#k int* t!* +ay increa#e 3*th c*herence and c*upling and 3e *9 unargua3le 3ene9it) H*!ever, #plitting and reE #plitting Gand reEreE#plittingH a ta#k !ill *9ten 3ack9ire due t* c*nte;t de+and#)
he #eri*u# pr*3le+ !ith +uch #*9t!are i# the prevalence *9 large +eth*d# that rely *n deeply ne#ted l**p# and c*nditi*nal# 9*r 9l*! c*ntr*l) >**d +eth*d# #h*uld 3e #* #traight9*r!ard that they reDuire n* internal c*++ent#) 5*r in#tance1 Co#t tota -rice0-roductJK product#1; Co#t #u! 9 ne. Co#t013 foreach0-roduct p in product#1; #u! R9 p.Co#t3 < return #u!3 < Thi# +eth*d #till need# +eth*d d*cu+entati*n P that it d*e#nt apply ta;e#, that it +ay return a C*#t !h*#e value i# $ Ga##u+ing that# h*! the C*#tGH c*n#truct*r initiali7e#H i9 the pr*duct# para+eter i# e+pty, perhap# even that it reDuire# pr*duct# t* 3e n*nEnull Galth*ugh it# 3etter t* a##u+e that all +eth*d# thr*! a ullRe9erenceE;cepti*n !hen pa##ed any null para+eter# and d*cu+ent !hen that isn:t the ca#eH) But it d*e#nt need internal c*++ent# GI-nitiali7e a C*#t *34ect called T#u+ that !ill h*ld the re#ult#JF Plea#eKH) -nternal c*++ent# are *nly needed !hen y*ur c*de i# c*+ple;) ?*nt !rite c*+ple; c*de) ,rite 3*ring c*de that #*lve# intere#ting pr*3le+#) Cycl*+atic c*+ple;ity, the +ea#ure *9 c*de c*+ple;ity, !a# intr*duced in chapter #/F#) One *9 the characteri#tic# *9 g**d *34ectE*riented pr*gra+# i# that their +eth*d# have le## cycl*+atic c*+ple;ity than pr*cedural pr*gra+#) H*! can thi# 3e #*, i9 the t!* pr*gra+# #*lve the #a+e pr*3le+F S*+e #a+ple c*de +ight e;plain the di99erence)
)33
)34
Thinking in C
www.ThinkingIn.!et
chapter, y*ull learn h*! li3rary c*+p*nent# are placed int* package#) Then y*ull 3e a3le t* under#tand the c*+plete +eaning *9 the acce## #peci9ier#)
)35
LtkL u#ing thin%inginc#harp3 na!e#pace u#e#another; c a## O#e#Specia iMed; pu$ ic #tatic *oid Gain01; )rrayLi#t a 9 ne. )rrayLi#t013 //Can #ti exp icit y reference other Sy#te!.Co ection#.)rrayLi#t rea Li#t 9 ne. Sy#te!.Co ection#.)rrayLi#t013 rea Li#t.)dd0&Oh! 5t'# a rea co ection c a##!&13 < <
]
LtkL
Collisions
,hat happen# i9 t!* li3rarie# are i+p*rted via b and they include the #a+e na+e#F 5*r e;a+ple, #upp*#e a pr*gra+ d*e# thi#1 u#ing Cet.'hin%ing5n.Oti 3 u#ing Sy#te!.Co ection#3 tk d:^tic^chapP^thin%ingZc#c /t:!odu e V.c# Gicro#oft 0R1 Ni#ua C( Co!pi er Ner#ion F.00.>2PE JCLR *er#ion *".0.2>"EK Copyright 0C1 Gicro#oft Corp 20006200". ) right# re#er*ed. ::^tic^chapP^thin%ingZdir No u!e in dri*e : i# GON5+S
)36
Thinking in C
www.ThinkingIn.!et
No u!e Seria
Cu!$er i# 2BTF6">0F
:irectory of ::^tic^chapP^thin%ing "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" 0I:TF )G W:5RZ . 0I:TF )G W:5RZ .. 0I:TP )G 2IP V.c# 0I:TI )G 220EI V.net!odu e 2 Hi e0#1 22TTT $yte# 2 :ir0#1 "02?"T2P?T2T>2 $yte# free
::^tic^chapP^thin%ingZ#n 6% %ey.#n% Gicro#oft 0R1 .C+' Hra!e.or% Strong Ca!e Oti ity Ner#ion ".0.2>"E."? Copyright 0C1 Gicro#oft Corp. ">>I6200". ) right# re#er*ed. aey pair .ritten to %ey.#n% ::^tic^chapP^thin%ingZdir No u!e in dri*e : i# GON5+S No u!e Seria Cu!$er i# 2BTF6">0F :irectory of ::^tic^chapP^thin%ing "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" 0I:TF )G W:5RZ . 0I:TF )G W:5RZ .. 0I:TP )G 2IP V.c# 0I:TI )G 220EI V.net!odu e 0I:T> )G P>? %ey.#n% E Hi e0#1 ?200" $yte# 2 :ir0#1 "02?"T2PEF200I $yte# free
::^tic^chapP^thin%ingZa /out:thin%ing.d /%eyfi e:%ey.#n% V.net!odu e Gicro#oft 0R1 )##e!$ y Lin%er Ner#ion F.00.>2PE JCLR *er#ion *".0.2>"EK Copyright 0C1 Gicro#oft Corp 20006200". ) right# re#er*ed.
)3#
::^tic^chapP^thin%ingZdir No u!e in dri*e : i# GON5+S No u!e Seria Cu!$er i# 2BTF6">0F :irectory of ::^tic^chapP^thin%ing "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" 0I:TF )G W:5RZ . 0I:TF )G W:5RZ .. 0I:TP )G 2IP V.c# 0I:TI )G 220EI V.net!odu e 0I:T> )G T20F2 V.d 0I:T> )G P>? %ey.#n% 0I:E2 )G T2PIE thin%ing.d P Hi e0#1 >2PIP $yte# 2 :ir0#1 "02?"T22F?2?F2 $yte# free /i thin%ing.d
::^tic^chapP^thin%ingZgacuti
Gicro#oft 0R1 .C+' _ o$a )##e!$ y Cache Oti ity. Ner#ion ".0.2>"E."? Copyright 0C1 Gicro#oft Corp. ">>I6200". ) right# re#er*ed. )##e!$ y #ucce##fu y added to the cache
::^tic^chapP^thin%ingZ#tart c:^.indo.#^a##e!$ y
Ot*d*1 5igure *ut h*! t* re9erence it in *ther# G- kn*! - can d* it 9r*+ the c*++and line c*+pile, 3ut - cant 9igure *ut h*! t* d* it tran#parentlyH :*u can u#e thi# #h*rthand t* print a string either !ith a ne!line G!6rintln( )H *r !ith*ut a ne!line G!6rint( )H)
)3&
Thinking in C
www.ThinkingIn.!et
'rue0$oo Ha #e0$oo
exp1; exp1
'rue0$oo
exp2
Ha #e0$oo
exp2
)3'
G7riendl5H
,hat i9 y*u give n* acce## #peci9ier at all, a# in all the e;a+ple# 3e9*re thi# chapterF The de9ault acce## ha# n* key!*rd, 3ut it i# c*++*nly re9erred t* a# I9riendly)J -t +ean# that all the *ther cla##e# in the current package have acce## t* the 9riendly +e+3er, 3ut t* all the cla##e# *ut#ide *9 thi# package the +e+3er appear# t* 3e private) Since a c*+pilati*n unitRa 9ileRcan 3el*ng *nly t* a #ingle package, all the cla##e# !ithin a #ingle c*+pilati*n unit are aut*+atically 9riendly !ith each *ther) Thu#, 9riendly ele+ent# are al#* #aid t* have "ackage access) 5riendly acce## all*!# y*u t* gr*up related cla##e# t*gether in a package #* that they can ea#ily interact !ith each *ther) ,hen y*u put cla##e# t*gether in a package Gthu# granting +utual acce## t* their 9riendly +e+3er#Q i)e), +aking the+ I9riend#JH y*u I*!nJ the c*de in that package) -t +ake# #en#e that *nly c*de y*u *!n #h*uld have 9riendly acce## t* *ther c*de y*u *!n) :*u c*uld #ay that 9riendly acce## give# a +eaning *r a rea#*n 9*r gr*uping cla##e# t*gether in a package) -n +any language# the !ay y*u *rgani7e y*ur de9initi*n# in 9ile# can 3e !illyEnilly, 3ut in "ava y*ure c*+pelled t* *rgani7e the+ in a #en#i3le 9a#hi*n) -n additi*n, y*ull pr*3a3ly !ant t* e;clude cla##e# that #h*uldnt have acce## t* the cla##e# 3eing de9ined in the current package) The cla## c*ntr*l# !hich c*de ha# acce## t* it# +e+3er#) There# n* +agic !ay t* I3reak in)J C*de 9r*+ an*ther package cant #h*! up and #ay, IHi, -+ a 9riend *9 Bob#KJ and e;pect t* #ee the protected, 9riendly, and private +e+3er# *9 Bob) The *nly !ay t* grant acce## t* a +e+3er i# t*1 1. 2. Aake the +e+3er public) Then every3*dy, every!here, can acce## it) Aake the +e+3er 9riendly 3y leaving *99 any acce## #peci9ier, and put the *ther cla##e# in the #a+e package) Then the *ther cla##e# can acce## the +e+3er) =# y*ull #ee in Chapter ., !hen inheritance i# intr*duced, an inherited cla## can acce## a protected +e+3er a# !ell a# a public +e+3er G3ut n*t private +e+3er#H) -t can acce## 9riendly +e+3er# *nly i9 the t!* cla##e# are in the #a+e package) But d*nt !*rry a3*ut that n*!) Thinking in C www.ThinkingIn.!et
3.
)4(
Pr*vide Iacce##*r<+utat*rJ +eth*d# Gal#* kn*!n a# Iget<#etJ +eth*d#H that read and change the value) Thi# i# the +*#t civili7ed appr*ach in ter+# *9 OOP, and it i# 9unda+ental t* "avaBean#, a# y*ull #ee in Chapter 0/)
)41
H*!ever, it turn# *ut that the c*n#i#tent u#e *9 private i# very i+p*rtant, e#pecially !here +ultithreading i# c*ncerned) G=# y*ull #ee in Chapter 0&)H Here# an e;a+ple *9 the u#e *9 private1 //: c0P:5ceCrea!.Da*a // :e!on#trate# &pri*ate& %ey.ord. c a## Sundae ; pri*ate Sundae01 ;< #tatic Sundae !a%e)Sundae01 ; return ne. Sundae013 < < pu$ ic c a## 5ceCrea! ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; //! Sundae x 9 ne. Sundae013 Sundae x 9 Sundae.!a%e)Sundae013 < < ///:8 Thi# #h*!# an e;a+ple in !hich private c*+e# in handy1 y*u +ight !ant t* c*ntr*l h*! an *34ect i# created and prevent #*+e*ne 9r*+ directly acce##ing a particular c*n#truct*r G*r all *9 the+H) -n the e;a+ple a3*ve, y*u cann*t create a #undae *34ect via it# c*n#truct*rQ in#tead y*u +u#t call the ma(e'#undae( ) +eth*d t* d* it 9*r y*u0) =ny +eth*d that y*ure certain i# *nly a IhelperJ +eth*d 9*r that cla## can 3e +ade private, t* en#ure that y*u d*nt accidentally u#e it el#e!here in the package and thu# pr*hi3it y*ur#el9 9r*+ changing *r re+*ving the +eth*d) Aaking a +eth*d private guarantee# that y*u retain thi# *pti*n) The #a+e i# true 9*r a private 9ield in#ide a cla##) Unle## y*u +u#t e;p*#e the underlying i+ple+entati*n G!hich i# a +uch rarer #ituati*n than y*u +ight thinkH, y*u #h*uld +ake all 9ield# private) H*!ever, 4u#t 3ecau#e a re9erence t* an *34ect i# private in#ide a cla## d*e#nSt +ean that #*+e *ther *34ect canSt have a public re9erence t* the #a+e *34ect) GSee =ppendi; = 9*r i##ue# a3*ut alia#ing)H
0 There# an*ther e99ect in thi# ca#e1 Since the de9ault c*n#truct*r i# the *nly *ne de9ined, and it#
private, it !ill prevent inheritance *9 thi# cla##) G= #u34ect that !ill 3e intr*duced in Chapter .)H
)43
The protected key!*rd deal# !ith a c*ncept called inheritance, !hich take# an e;i#ting cla## and add# ne! +e+3er# t* that cla## !ith*ut t*uching the e;i#ting cla##, !hich !e re9er t* a# the 2ase class) :*u can al#* change the 3ehavi*r *9 e;i#ting +e+3er# *9 the cla##) T* inherit 9r*+ an e;i#ting cla##, y*u #ay that y*ur ne! cla## extends an e;i#ting cla##, like thi#1 c a## Hoo extend# Bar ; The re#t *9 the cla## de9initi*n l**k# the #a+e) -9 y*u create a ne! package and y*u inherit 9r*+ a cla## in an*ther package, the *nly +e+3er# y*u have acce## t* are the public +e+3er# *9 the *riginal package) GO9 c*ur#e, i9 y*u per9*r+ the inheritance in the same package, y*u have the n*r+al package acce## t* all the I9riendlyJ +e+3er#)H S*+eti+e# the creat*r *9 the 3a#e cla## !*uld like t* take a particular +e+3er and grant acce## t* derived cla##e# 3ut n*t the !*rld in general) That# !hat protected d*e#) -9 y*u re9er 3ack t* the 9ile Coo(ie6)ava, the 9*ll*!ing cla## cannot acce## the I9riendlyJ +e+3er1 //: c0P:Choco ateChip.Da*a // Can't acce## friend y !e!$er // in another c a##. i!port c0P.de##ert.=3 pu$ ic c a## Choco ateChip extend# Coo%ie ; pu$ ic Choco ateChip01 ; Sy#te!.out.print n0 &Choco ateChip con#tructor&13 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; Choco ateChip x 9 ne. Choco ateChip013 //! x.$ite013 // Can't acce## $ite < < ///:8 One *9 the intere#ting thing# a3*ut inheritance i# that i9 a +eth*d bite( ) e;i#t# in cla## Coo(ie, then it al#* e;i#t# in any cla## inherited 9r*+ Coo(ie) But #ince bite( ) i# I9riendlyJ in a 9*reign package, it# unavaila3le t* u# in thi# *ne) O9 c*ur#e, y*u c*uld +ake it public, 3ut then every*ne !*uld have acce## and +ay3e that# n*t !hat y*u !ant) -9 !e change the cla## Coo(ie a# 9*ll*!#1 pu$ ic c a## Coo%ie ; pu$ ic Coo%ie01 ; Sy#te!.out.print n0&Coo%ie con#tructor&13 < protected *oid $ite01 ; Sy#te!.out.print n0&$ite&13 < <
)44
Thinking in C
www.ThinkingIn.!et
then bite( ) #till ha# I9riendlyJ acce## !ithin package dessert, 3ut it i# al#* acce##i3le t* any*ne inheriting 9r*+ Coo(ie) H*!ever, it i# not public) protected al#* give# package acce## P that i#, *ther cla##e# in the #a+e package +ay acce## protected ele+ent#)
)45
pu$ ic *oid -u$"0 1 pu$ ic *oid -u$20 1 pu$ ic *oid -u$T0 1 pri*ate *oid pri*"0 pri*ate *oid pri*20 pri*ate *oid pri*T0 pri*ate int i3 // . . . <
; ; ; 1 1 1
/= . /= . /= . ; /= ; /= ; /=
. . . . . .
. . . . . .
Thi# !ill +ake it *nly partially ea#ier t* read 3ecau#e the inter9ace and i+ple+entati*n are #till +i;ed t*gether) That i#, y*u #till #ee the #*urce c*deRthe i+ple+entati*nR3ecau#e it# right there in the cla##) -n additi*n, the c*++ent d*cu+entati*n #*+e!hat le##en# the i+p*rtance *9 c*de reada3ility 3y the client pr*gra++er) ?i#playing the inter9ace t* the c*n#u+er *9 a cla## i# really the 4*3 *9 the class 2rowser, a t**l !h*#e 4*3 i# t* l**k at all the availa3le cla##e# and #h*! y*u !hat y*u can d* !ith the+ Gi)e), !hat +e+3er# are availa3leH in a u#e9ul 9a#hi*n) Aicr*#*9t# Ci#ual Studi* ) ET i# the 9ir#t, 3ut n*t the *nly, t**l t* pr*vide a cla## 3r*!#er 9*r C#)
Class access
-n C#, the acce## #peci9ier# can al#* 3e u#ed t* deter+ine !hich cla##e# within a li3rary !ill 3e availa3le t* the u#er# *9 that li3rary) -9 y*u !ant a cla## t* 3e availa3le t* a client pr*gra++er, y*u place the public key!*rd #*+e!here 3e9*re the *pening 3race *9 the cla## 3*dy) Thi# c*ntr*l# !hether the client pr*gra++er can even create an *34ect *9 the cla##) T* c*ntr*l the acce## *9 a cla##, the #peci9ier +u#t appear 3e9*re the key!*rd class) Thu# y*u can #ay1 pu$ ic c a## Vidget ; *! i9 the na+e *9 y*ur li3rary i# .ylib any client pr*gra++er can acce## =idget 3y #aying u#ing Gy i$3 Vidget .3 ,hat i9 y*uve g*t a cla## in#ide .ylib that y*ure 4u#t u#ing t* acc*+pli#h the ta#k# per9*r+ed 3y =idget *r #*+e *ther public cla## in .ylibF :*u d*nt !ant t* g* t* the 3*ther *9 creating d*cu+entati*n 9*r the client pr*gra++er, and y*u think that #*+eti+e later y*u +ight !ant t* c*+pletely change thing# and rip *ut y*ur cla## alt*gether, #u3#tituting a di99erent *ne) T* give y*u thi# 9le;i3ility, y*u need t* en#ure that n* client pr*gra++er# 3ec*+e dependent *n y*ur particular i+ple+entati*n detail# hidden in#ide .ylib) T* acc*+pli#h thi#, y*u 4u#t leave the public key!*rd *99 the cla##, in !hich ca#e it 3ec*+e# 9riendly) GThat cla## can 3e u#ed *nly !ithin that package)H
)46
Thinking in C
www.ThinkingIn.!et
*te that a cla## cann*t 3e private Gthat !*uld +ake it acce##i3le t* n* *ne 3ut the cla##H, *r protected) S* y*u have *nly t!* ch*ice# 9*r cla## acce##1 I9riendlyJ *r public) -9 y*u d*nt !ant any*ne el#e t* have acce## t* that cla##, y*u can +ake all the c*n#truct*r# private, there3y preventing any*ne 3ut y*u, in#ide a static +e+3er *9 the cla##, 9r*+ creating an *34ect *9 that cla## /) Here# an e;a+ple1 //Wexa!p eZ ///WchapterZc0PW/chapterZ ///Wprogra!ZLunch.c#W/progra!Z // :e!on#trate# c a## acce## #pecifier#. // Ga%e a c a## effecti*e y pri*ate // .ith pri*ate con#tructor#: c a## Soup ; pri*ate Soup01 ;< // 0"1 ) o. creation *ia #tatic !ethod: pu$ ic #tatic Soup Ga%eSoup01 ; return ne. Soup013 < // 021 Create a #tatic o$Dect and // return a reference upon re7ue#t. // 0'he &Sing eton& pattern1: pri*ate #tatic Soup p#" 9 ne. Soup013 pu$ ic #tatic Soup )cce##01 ; return p#"3 < pu$ ic *oid H01 ;< < c a## Sand.ich ; // O#e# Lunch *oid H01 ; ne. Lunch013 < < // On y one pu$ ic c a## a o.ed per fi e: pu$ ic c a## Lunch ; *oid 'e#t01 ; // Can't do thi#! -ri*ate con#tructor: Soup pri*" 9 ne. Soup013 //! Soup pri*2 9 Soup.Ga%eSoup013 Sand.ich f" 9 ne. Sand.ich013 Soup.)cce##01.H013 < < //W/exa!p eZ Up t* n*!, +*#t *9 the +eth*d# have 3een returning either void *r a pri+itive type, #* the de9initi*n1 pu$ ic #tatic Soup )cce##01 ; return p#"3
/ :*u can al#* d* it 3y inheriting GChapter .H 9r*+ that cla##)
)4#
< +ight l**k a little c*n9u#ing at 9ir#t) The !*rd 3e9*re the +eth*d na+e G 'ccessH tell# !hat the +eth*d return#) S* 9ar thi# ha# +*#t *9ten 3een void, !hich +ean# it return# n*thing) But y*u can al#* return a re9erence t* an *34ect, !hich i# !hat happen# here) Thi# +eth*d return# a re9erence t* an *34ect *9 cla## #oup) The class #oup #h*!# h*! t* prevent direct creati*n *9 a cla## 3y +aking all the c*n#truct*r# private) Re+e+3er that i9 y*u d*nt e;plicitly create at lea#t *ne c*n#truct*r, the de9ault c*n#truct*r Ga c*n#truct*r !ith n* argu+ent#H !ill 3e created 9*r y*u) By !riting the de9ault c*n#truct*r, it !*nt 3e created aut*+atically) By +aking it private, n* *ne can create an *34ect *9 that cla##) But n*! h*! d*e# any*ne u#e thi# cla##F The a3*ve e;a+ple #h*!# t!* *pti*n#) 5ir#t, a static +eth*d i# created that create# a ne! #oup and return# a re9erence t* it) Thi# c*uld 3e u#e9ul i9 y*u !ant t* d* #*+e e;tra *perati*n# *n the #oup 3e9*re returning it, *r i9 y*u !ant t* keep c*unt *9 h*! +any #oup *34ect# t* create Gperhap# t* re#trict their p*pulati*nH) The #ec*nd *pti*n u#e# !hat# called a design "attern, !hich i# c*vered in Thinking in /atterns with ,a-a, d*!nl*ada3le at www.BruceEckel.com) Thi# particular pattern i# called a I#inglet*nJ 3ecau#e it all*!# *nly a #ingle *34ect t* ever 3e created) The *34ect *9 cla## #oup i# created a# a static private +e+3er *9 #oup, #* there# *ne and *nly *ne, and y*u cant get at it e;cept thr*ugh the public +eth*d access( )) =# previ*u#ly +enti*ned, i9 y*u d*nt put an acce## #peci9ier 9*r cla## acce## it de9ault# t* I9riendly)J Thi# +ean# that an *34ect *9 that cla## can 3e created 3y any *ther cla## in the package, 3ut n*t *ut#ide the package) GRe+e+3er, all the 9ile# !ithin the #a+e direct*ry that d*nt have e;plicit pac(age declarati*n# are i+plicitly part *9 the de9ault package 9*r that direct*ry)H H*!ever, i9 a static +e+3er *9 that cla## i# public, the client pr*gra++er can #till acce## that static +e+3er even th*ugh they cann*t create an *34ect *9 that cla##)
'u##ar5
-n any relati*n#hip it# i+p*rtant t* have 3*undarie# that are re#pected 3y all partie# inv*lved) ,hen y*u create a li3rary, y*u e#ta3li#h a relati*n#hip !ith the u#er *9 that li3raryRthe client pr*gra++erR!h* i# an*ther pr*gra++er, 3ut *ne putting t*gether an applicati*n *r u#ing y*ur li3rary t* 3uild a 3igger li3rary) ,ith*ut rule#, client pr*gra++er# can d* anything they !ant !ith all the +e+3er# *9 a cla##, even i9 y*u +ight pre9er they d*nt directly +anipulate #*+e *9 the +e+3er#) Everything# naked t* the !*rld) Thi# chapter l**ked at h*! cla##e# are 3uilt t* 9*r+ li3rarie#Q 9ir#t, the !ay a gr*up *9 cla##e# i# packaged !ithin a li3rary, and #ec*nd, the !ay the cla## c*ntr*l# acce## t* it# +e+3er#)
)4&
Thinking in C
www.ThinkingIn.!et
-t i# e#ti+ated that a C pr*gra++ing pr*4ect 3egin# t* 3reak d*!n #*+e!here 3et!een '$N and 0$$N line# *9 c*de 3ecau#e C ha# a #ingle Ina+e #paceJ #* na+e# 3egin t* c*llide, cau#ing an e;tra +anage+ent *verhead) -n "ava, the pac(age key!*rd, the package na+ing #che+e, and the import key!*rd give y*u c*+plete c*ntr*l *ver na+e#, #* the i##ue *9 na+e c*lli#i*n i# ea#ily av*ided) There are t!* rea#*n# 9*r c*ntr*lling acce## t* +e+3er#) The 9ir#t i# t* keep u#er# hand# *99 t**l# that they #h*uldnt t*uchQ t**l# that are nece##ary 9*r the internal +achinati*n# *9 the data type, 3ut n*t part *9 the inter9ace that u#er# need t* #*lve their particular pr*3le+#) S* +aking +eth*d# and 9ield# private i# a #ervice t* u#er# 3ecau#e they can ea#ily #ee !hat# i+p*rtant t* the+ and !hat they can ign*re) -t #i+pli9ie# their under#tanding *9 the cla##) The #ec*nd and +*#t i+p*rtant rea#*n 9*r acce## c*ntr*l i# t* all*! the li3rary de#igner t* change the internal !*rking# *9 the cla## !ith*ut !*rrying a3*ut h*! it !ill a99ect the client pr*gra++er) :*u +ight 3uild a cla## *ne !ay at 9ir#t, and then di#c*ver that re#tructuring y*ur c*de !ill pr*vide +uch greater #peed) -9 the inter9ace and i+ple+entati*n are clearly #eparated and pr*tected, y*u can acc*+pli#h thi# !ith*ut 9*rcing the u#er t* re!rite their c*de) =cce## #peci9ier# in "ava give valua3le c*ntr*l t* the creat*r *9 a cla##) The u#er# *9 the cla## can clearly #ee e;actly !hat they can u#e and !hat t* ign*re) A*re i+p*rtant, th*ugh, i# the a3ility t* en#ure that n* u#er 3ec*+e# dependent *n any part *9 the underlying i+ple+entati*n *9 a cla##) -9 y*u kn*! thi# a# the creat*r *9 the cla##, y*u can change the underlying i+ple+entati*n !ith the kn*!ledge that n* client pr*gra++er !ill 3e a99ected 3y the change# 3ecau#e they cant acce## that part *9 the cla##) ,hen y*u have the a3ility t* change the underlying i+ple+entati*n, y*u can n*t *nly i+pr*ve y*ur de#ign later, 3ut y*u al#* have the 9reed*+ t* +ake +i#take#) * +atter h*! care9ully y*u plan and de#ign y*ull +ake +i#take#) Nn*!ing that it# relatively #a9e t* +ake the#e +i#take# +ean# y*ull 3e +*re e;peri+ental, y*ull learn 9a#ter, and y*ull 9ini#h y*ur pr*4ect #**ner) The pu3lic inter9ace t* a cla## i# !hat the u#er does #ee, #* that i# the +*#t i+p*rtant part *9 the cla## t* get IrightJ during analy#i# and de#ign) Even that all*!# y*u #*+e lee!ay 9*r change) -9 y*u d*nt get the inter9ace right the 9ir#t ti+e, y*u can add +*re +eth*d#, a# l*ng a# y*u d*nt re+*ve any that client pr*gra++er# have already u#ed in their c*de)
)4'
%&ercises
C, 6eusing classes
,hat i# inheritanceF ,hy d*e# it helpF -nheritance in C#1 declaring derived cla##e#, pr*tected and pr*tected internal c*+p*nent#, virtual and *verride +eth*d#, a3#tract cla##e#, #ealed cla##e#, hiding inherited c*+p*nent#, ver#i*ning, lack *9 inheritance in #truct#) ,hat are alternative# t* inheritance 9*r c*+p*#ing c*+ple; #tructure#F H*! #h*uld !e decide 3et!een c*+p*#iti*n and aggregati*nF ,hat are the di99erent type# *9 de#ign pattern#F
)5(
Thinking in C
www.ThinkingIn.!et
One *9 the +*#t c*+pelling 9eature# a3*ut *34ect *rientati*n i# c*de reu#e) But t* 3e rev*luti*nary, y*uve g*t t* 3e a3le t* d* a l*t +*re than c*py c*de and change it)
That# the appr*ach u#ed in pr*cedural language# like C, and it ha#nt !*rked very !ell) Like everything in C#, the #*luti*n rev*lve# ar*und the cla##) :*u reu#e c*de 3y creating ne! cla##e#, 3ut in#tead *9 creating the+ 9r*+ #cratch, y*u u#e e;i#ting cla##e# that #*+e*ne ha# already 3uilt and de3ugged) The trick i# t* u#e the cla##e# !ith*ut #*iling the e;i#ting c*de) -n thi# chapter y*ull #ee t!* !ay# t* acc*+pli#h thi#) The 9ir#t i# Duite #traight9*r!ard1 :*u #i+ply create *34ect# *9 y*ur e;i#ting cla## in#ide the ne! cla##) Thi# i# called com"osition6 3ecau#e the ne! cla## i# c*+p*#ed *9 *34ect# *9 e;i#ting cla##e#) :*ure #i+ply reu#ing the 9uncti*nality *9 the c*de, n*t it# 9*r+) The #ec*nd appr*ach i# +*re #u3tle) -t create# a ne! cla## a# a t4"e o$ an e;i#ting cla##) :*u literally take the 9*r+ *9 the e;i#ting cla## and add c*de t* it !ith*ut +*di9ying the e;i#ting cla##) Thi# +agical act i# called inheritance, and the c*+piler d*e# +*#t *9 the !*rk) -nheritance i# *ne *9 the c*rner#t*ne# *9 *34ectE*riented pr*gra++ing, and ha# additi*nal i+plicati*n# that !ill 3e e;pl*red in Chapter #inheritance#) -t turn# *ut that +uch *9 the #ynta; and 3ehavi*r are #i+ilar 9*r 3*th c*+p*#iti*n and inheritance G!hich +ake# #en#e 3ecau#e they are 3*th
)51
!ay# *9 +aking ne! type# 9r*+ e;i#ting type#H) -n thi# chapter, y*ull learn a3*ut the#e c*de reu#e +echani#+#)
Co#$osition s5nta&
Until n*!, c*+p*#iti*n ha# 3een u#ed Duite 9reDuently) :*u #i+ply place *34ect re9erence# in#ide ne! cla##e#) 5*r e;a+ple, #upp*#e y*ud like an *34ect that h*ld# #everal string *34ect#, a c*uple *9 pri+itive#, and an *34ect *9 an*ther cla##) 5*r the n*npri+itive *34ect#, y*u put re9erence# in#ide y*ur ne! cla##, 3ut y*u de9ine the pri+itive# directly1 //:c0?:Sprin% erSy#te!.c# // Co!po#ition for code reu#e. c a## VaterSource ; pri*ate #tring #3 VaterSource01 ; Sy#te!.Con#o e.VriteLine0&VaterSource01&13 # 9 &Con#tructed&3 < pu$ ic o*erride #tring 'oString01 ; return #3 < < pu$ ic c a## Sprin% erSy#te! ; pri*ate #tring *a *e"2 *a *e22 *a *eT2 *a *eE3 VaterSource #ource3 int i3
)5)
f oat f3 *oid -rint01 ; Sy#te!.Con#o e.VriteLine0&*a *e" 9 & R *a *e"13 Sy#te!.Con#o e.VriteLine0&*a *e2 9 & R *a *e213 Sy#te!.Con#o e.VriteLine0&*a *eT 9 & R *a *eT13 Sy#te!.Con#o e.VriteLine0&*a *eE 9 & R *a *eE13 Sy#te!.Con#o e.VriteLine0&i 9 & R i13 Sy#te!.Con#o e.VriteLine0&f 9 & R f13 Sy#te!.Con#o e.VriteLine0&#ource 9 & R #ource13 < pu$ ic #tatic *oid Gain01 ; Sprin% erSy#te! x 9 ne. Sprin% erSy#te!013 x.-rint013 < < ///:8 One *9 the +eth*d# de9ined in =ater#ource i# #pecial1 +o#tring( )) :*u !ill learn later that every *34ect ha# a +o#tring( ) +eth*d, and it# called in #pecial #ituati*n# !hen the c*+piler !ant# a string 3ut it# g*t *ne *9 the#e *34ect#) S* in the e;pre##i*n1 Sy#te!.Con#o e.VriteLine0&#ource 9 & R #ource13 the c*+piler #ee# y*u trying t* add a string *34ect GYsource I YH t* a =ater#ource) Thi# d*e#nt +ake #en#e t* it, 3ecau#e y*u can *nly IaddJ a string t* an*ther #tring, #* it #ay# I-ll turn source int* a string 3y calling +o#tring( )KJ =9ter d*ing thi# it can c*+3ine the t!* string# and pa## the re#ulting #tring t* #ystem6Console6=riteLine( )) =ny ti+e y*u !ant t* all*! thi# 3ehavi*r !ith a cla## y*u create y*u need *nly !rite a +o#tring( ) +eth*d) =t 9ir#t glance, y*u +ight a##u+eRC# 3eing a# #a9e and care9ul a# it i#R that the c*+piler !*uld aut*+atically c*n#truct *34ect# 9*r each *9 the re9erence# in the a3*ve c*deQ 9*r e;a+ple, calling the de9ault c*n#truct*r 9*r =ater#ource t* initiali7e source) The *utput *9 the print #tate+ent i# in 9act1 *a *e" 9 nu *a *e2 9 nu *a *eT 9 nu
)53
*a *eE 9 nu i 9 0 f 9 0.0 #ource 9 nu Pri+itive# that are 9ield# in a cla## are aut*+atically initiali7ed t* 7er*, a# n*ted in Chapter #initiali7ati*n#) But the *34ect re9erence# are initiali7ed t* null, and i9 y*u try t* call +eth*d# 9*r any *9 the+ y*ull get an e;cepti*n) -t# actually pretty g**d Gand u#e9ulH that y*u can #till print the+ *ut !ith*ut thr*!ing an e;cepti*n) -t +ake# #en#e that the c*+piler d*e#nt 4u#t create a de9ault *34ect 9*r every re9erence 3ecau#e that !*uld incur unnece##ary *verhead in +any ca#e#) -9 y*u !ant the re9erence# initiali7ed, y*u can d* it1 0) =t the p*int the *34ect# are de9ined) Thi# +ean# that theyll al!ay# 3e initiali7ed 3e9*re the c*n#truct*r i# called) 2) -n the c*n#truct*r 9*r that cla##) /) Right 3e9*re y*u actually need t* u#e the *34ect) Thi# i# *9ten called la;4 initiali;ation) -t can reduce *verhead in #ituati*n# !here the *34ect d*e#nt need t* 3e created every ti+e) =ll three appr*ache# are #h*!n here1 //:c0?:Bath.c# // Con#tructor initia iMation .ith co!po#ition. c a## Soap ; pri*ate #tring #3 interna Soap01 ; Sy#te!.Con#o e.VriteLine0&Soap01&13 # 9 &Con#tructed&3 < pu$ ic o*erride #tring 'oString01 ; return #3 < < pu$ ic c a## Bath ; pri*ate #tring // 5nitia iMing at point of definition: //\todo: Change to #ho. arg con#tructor
)54
Thinking in C
www.ThinkingIn.!et
#" 9 &Uappy&2 #2 9 &Uappy&2 #T2 #E3 Soap ca#ti e3 int i3 f oat toy3 Bath01 ; Sy#te!.Con#o e.VriteLine0&5n#ide Bath01&13 #T 9 &`oy&3 i 9 EF3 toy 9 T."Ef3 ca#ti e 9 ne. Soap013 < *oid -rint01 ; // :e ayed initia iMation: if0#E 99 nu 1 #E 9 &`oy&3 Sy#te!.Con#o e.VriteLine0&#" 9 & R #"13 Sy#te!.Con#o e.VriteLine0 9 & R #213 Sy#te!.Con#o e.VriteLine0&#T 9 & R #T13 Sy#te!.Con#o e.VriteLine0&#E 9 & R #E13 Sy#te!.Con#o e.VriteLine0&i 9 & R i13 Sy#te!.Con#o e.VriteLine0&toy 9 & R toy13 Sy#te!.Con#o e.VriteLine0&ca#ti e 9 & R ca#ti e13 < pu$ ic #tatic *oid Gain01 ; Bath $ 9 ne. Bath013 $.-rint013 < < ///:8 *te that in the Bath c*n#truct*r a #tate+ent i# e;ecuted 3e9*re any *9 the initiali7ati*n# take place) ,hen y*u d*nt initiali7e at the p*int *9 de9initi*n, there# #till n* guarantee that y*ull per9*r+ any initiali7ati*n 3e9*re y*u #end a +e##age t* an *34ect re9erenceRe;cept 9*r the inevita3le runEti+e e;cepti*n) Here# the *utput 9*r the pr*gra+1 5n#ide Bath01 Soap01
)55
#" 9 Uappy #2 9 Uappy #T 9 `oy #E 9 `oy i 9 EF toy 9 T."E ca#ti e 9 Con#tructed ,hen !rint( ) i# called it 9ill# in sJ #* that all the 9ield# are pr*perly initiali7ed 3y the ti+e they are u#ed)
Inheritance s5nta&
-nheritance i# an integral part *9 C# Gand OOP language# in generalH) -t turn# *ut that y*ure al!ay# d*ing inheritance !hen y*u create a cla##, 3ecau#e unle## y*u e;plicitly inherit 9r*+ #*+e *ther cla##, y*u i+plicitly inherit 9r*+ C## #tandard r**t cla## ob)ect) The #ynta; 9*r c*+p*#iti*n i# *3vi*u#, 3ut t* per9*r+ inheritance there# a di#tinctly di99erent 9*r+) ,hen y*u inherit, y*u #ay IThi# ne! cla## i# like that *ld cla##)J :*u #tate thi# in c*de 3y giving the na+e *9 the cla## a# u#ual, 3ut 3e9*re the *pening 3race *9 the cla## 3*dy, put a c*l*n 9*ll*!ed 3y the na+e *9 the 2ase class) ,hen y*u d* thi#, y*u aut*+atically get all the data +e+3er# and +eth*d# in the 3a#e cla##) Here# an e;a+ple1 //:c0?::etergent.c# ///Co!pi e .ith: &/!ain::etergent& // 5nheritance #yntax @ propertie#. interna c a## C ean#er ; pri*ate #tring # 9 &C ean#er&3 pu$ ic *oid )ppend0#tring a1 ; # R9 a3 < pu$ ic *oid :i ute01 ; )ppend0& di ute01&13 < pu$ ic *oid )pp y01 ; )ppend0& app y01&13 < *irtua pu$ ic *oid Scru$01 ; )ppend0& #cru$01&13 < pu$ ic *oid -rint01 ; Sy#te!.Con#o e.VriteLine0#13 < pu$ ic #tatic *oid Gain0#tringJK arg#1 ; C ean#er x 9 ne. C ean#er013 x.:i ute013 x.)pp y013 x.Scru$013
)56
Thinking in C
www.ThinkingIn.!et
x.-rint013 < < interna c a## :etergent : C ean#er ; // Change a !ethod: o*erride pu$ ic *oid Scru$01 ; )ppend0& :etergent.#cru$01&13 $a#e.Scru$013 // Ca $a#e6c a## *er#ion < // )dd !ethod# to the interface: pu$ ic *oid Hoa!01 ; )ppend0& Hoa!01&13 < // 'e#t the ne. c a##: ne. pu$ ic #tatic *oid Gain0#tringJK arg#1 ; :etergent x 9 ne. :etergent0arg#13 x.:i ute013 x.)pp y013 x.Scru$013 x.Hoa!013 x.-rint013 Sy#te!.Con#o e.VriteLine0&'e#ting $a#e c a##:&13 C ean#er.Gain013 < < ///:8 Thi# de+*n#trate# a nu+3er *9 9eature#) 5ir#t, 3*th Cleanser and $etergent c*ntain a .ain( ) +eth*d) :*u can create a .ain( ) 9*r each *ne *9 y*ur cla##e#, 3ut i9 y*u d* #*, the c*+piler !ill generate an err*r, #aying that y*u are de9ining +ultiple entry p*int#) :*u can ch**#e !hich .ain() y*u !ant t* have a##*ciated !ith the a##e+3ly 3y u#ing the <Aain1Cla##na+e #!itch) Thu#, i9 y*u c*+pile the a3*ve !ith csc $etergent6cs /.ainDCleanser, the *utput !ill 3e1 C ean#er di ute01 app y01 #cru$01 ,hile i9 c*+piled !ith csc $etergent6cs /.ainD$etergent, the re#ult i#1 C ean#er di ute01 app y01 :etergent.#cru$01 #cru$01 Hoa!01 'e#ting $a#e c a##: C ean#er di ute01 app y01 #cru$01
)5#
Thi# techniDue *9 putting a .ain( ) in each cla## can #*+eti+e# help !ith te#ting, !hen y*u 4u#t !ant t* !rite a Duick little pr*gra+ t* +ake #ure y*ur +eth*d# are !*rking the !ay y*u intend the+ t*) But 9*r general te#ting purp*#e#, y*u #h*uld u#e a unitEte#ting 9ra+e!*rk G#ee Chapter #te#ting#H) :*u d*nt need t* re+*ve the .ain( ) !hen y*ure 9ini#hed te#tingQ y*u can leave it in 9*r later te#ting) Here, y*u can #ee that $etergent6.ain( ) call# Cleanser6.ain( ) e;plicitly, pa##ing it the #a+e argu+ent# 9r*+ the c*++and line Gh*!ever, y*u c*uld pa## it any string arrayH) -t# i+p*rtant that all *9 the +eth*d# in Cleanser are public) Re+e+3er that i9 y*u leave *99 any acce## #peci9ier the +e+3er de9ault# t* private, !hich all*!# acce## *nly t* the very cla## in !hich the 9ield *r +eth*d i# de9ined) S* t* plan 9*r inheritance, a# a general rule leave 9ield# private, 3ut +ake all +eth*d# public) Gprotected +e+3er# al#* all*! acce## 3y derived cla##e#Q y*ull learn a3*ut thi# later)H O9 c*ur#e, in particular ca#e# y*u +u#t +ake ad4u#t+ent#, 3ut thi# i# a u#e9ul guideline) *te that Cleanser ha# a #et *9 +eth*d# in it# inter9ace1 'ppend( ), $ilute( ), 'pply( ), #crub( ), and !rint( )) Becau#e $etergent i# deri-ed $rom Cleanser it aut*+atically get# all the#e +eth*d# in it# inter9ace, even th*ugh y*u d*nt #ee the+ all e;plicitly de9ined in $etergent) :*u can think *9 inheritance, then, a# reusing the inter$ace. GThe i+ple+entati*n al#* c*+e# !ith it, 3ut that part i#nt the pri+ary p*int)H =# #een in #crub( ), it# p*##i3le t* take a +eth*d that# 3een de9ined in the 3a#e cla## and +*di9y it) -n thi# ca#e, y*u +ight !ant t* call the +eth*d 9r*+ the 3a#e cla## in#ide the ne! ver#i*n) But in#ide #crub( ) y*u cann*t #i+ply call #crub( ), #ince that !*uld pr*duce a recur#ive call, !hich i#nt !hat y*u !ant) T* #*lve thi# pr*3le+ C# ha# the key!*rd base that re9er# t* the I3a#e cla##J Gal#* called the I#upercla##JH 9r*+ !hich the current cla## ha# 3een inherited) Thu# the e;pre##i*n base6#crub( ) call# the 3a#eEcla## ver#i*n *9 the +eth*d #crub( )) ,hen inheriting y*ure n*t re#tricted t* u#ing the +eth*d# *9 the 3a#e cla##) :*u can al#* add ne! +eth*d# t* the derived cla## e;actly the !ay
)5&
Thinking in C
www.ThinkingIn.!et
y*u put any +eth*d in a cla##1 4u#t de9ine it) The +eth*d :oam( ) i# an e;a+ple *9 thi#) -n $etergent6.ain( ) y*u can #ee that 9*r a $etergent *34ect y*u can call all the +eth*d# that are availa3le in Cleanser a# !ell a# in $etergent Gi)e), :oam( )H)
)5'
Sy#te!.Con#o e.VriteLine0&:ra.ing con#tructor&13 < < pu$ ic c a## Cartoon : :ra.ing ; interna Cartoon01 ; Sy#te!.Con#o e.VriteLine0&Cartoon con#tructor&13 < pu$ ic #tatic *oid Gain01 ; Cartoon x 9 ne. Cartoon013 < < ///:8 The *utput 9*r thi# pr*gra+ #h*!# the aut*+atic call#1 )rt con#tructor :ra.ing con#tructor Cartoon con#tructor :*u can #ee that the c*n#tructi*n happen# 9r*+ the 3a#e I*ut!ard,J #* the 3a#e cla## i# initiali7ed 3e9*re the derivedEcla## c*n#truct*r# can acce## it) Even i9 y*u d*nt create a c*n#truct*r 9*r Cartoon( ), the c*+piler !ill #ynthe#i7e a de9ault c*n#truct*r 9*r y*u that call# the 3a#e cla## c*n#truct*r)
)6(
Thinking in C
www.ThinkingIn.!et
< < pu$ ic c a## Board_a!e : _a!e ; interna Board_a!e0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0&Board_a!e con#tructor&13 < < pu$ ic c a## Che## : Board_a!e ; interna Che##01 : $a#e0""1; Sy#te!.Con#o e.VriteLine0&Che## con#tructor&13 < pu$ ic #tatic *oid Gain01 ; Che## x 9 ne. Che##013 < <///:8 -9 y*u d*nt call the 3a#eEcla## c*n#truct*r in Board ame( ), the c*+piler !ill c*+plain that it cant 9ind a c*n#truct*r *9 the 9*r+ ame( ))
)61
Sy#te!.Con#o e.VriteLine0&5ngeniou# Nau ting&13 < pu$ ic #tatic *oid Gain01; try; ne. Brune e#chi013 <catch0+xception ex1; Sy#te!.Con#o e.VriteLine0ex13 < < <///:8 print#1 Sy#te!.5n*a idOperation+xception: Operation i# not *a id due to the current #tate of the o$Dect. at :o!e..ctor01 at Brune e#chi.Gain01
)6)
Thinking in C
www.ThinkingIn.!et
&:inner- ate con#tructor&13 < < c a## Oten#i ; interna Oten#i 0int i1 ; Sy#te!.Con#o e.VriteLine0&Oten#i < <
con#tructor&13
c a## Spoon : Oten#i ; interna Spoon0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0&Spoon con#tructor&13 < < c a## Hor% : Oten#i ; interna Hor%0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0&Hor% con#tructor&13 < < c a## anife : Oten#i ; interna anife0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0&anife con#tructor&13 < < // ) cu tura .ay of doing #o!ething: c a## Cu#to! ; interna Cu#to!0int i1 ; Sy#te!.Con#o e.VriteLine0&Cu#to! con#tructor&13 < < c a## - aceSetting : Cu#to! ; Spoon #p3 Hor% fr%3 anife %n3 :inner- ate p 3 - aceSetting0int i1 : $a#e0i R "1 ;
)63
#p 9 ne. Spoon0i R 213 fr% 9 ne. Hor%0i R T13 %n 9 ne. anife0i R E13 p 9 ne. :inner- ate0i R P13 Sy#te!.Con#o e.VriteLine0 &- aceSetting con#tructor&13 < pu$ ic #tatic *oid Gain 01; - aceSetting x 9 ne. - aceSetting0>13 < <///:8 ,hile the c*+piler 9*rce# y*u t* initiali7e the 3a#e cla##e#, and reDuire# that y*u d* it right at the 3eginning *9 the c*n#truct*r, it d*e#nt !atch *ver y*u t* +ake #ure that y*u initiali7e the +e+3er *34ect#, #* y*u +u#t re+e+3er t* pay attenti*n t* that)
)64
Thinking in C
www.ThinkingIn.!et
< c a## Circ e : Shape ; interna Circ e0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0&:ra.ing a Circ e&13 < pu$ ic o*erride *oid :i#po#e01 ; Sy#te!.Con#o e.VriteLine0&+ra#ing a Circ e&13 $a#e.:i#po#e013 < < c a## 'riang e : Shape ; interna 'riang e0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0&:ra.ing a 'riang e&13 < pu$ ic o*erride *oid :i#po#e01 ; Sy#te!.Con#o e.VriteLine0&+ra#ing a 'riang e&13 $a#e.:i#po#e013 < < c a## Line : Shape ; pri*ate int #tart2 end3 interna Line0int #tart2 int end1 : $a#e0#tart1; thi#.#tart 9 #tart3 thi#.end 9 end3 Sy#te!.Con#o e.VriteLine0&:ra.ing a Line: & R #tart R &2 & R end13 < pu$ ic o*erride *oid :i#po#e01 ; Sy#te!.Con#o e.VriteLine0&+ra#ing a Line: & R #tart R &2 & R end13 $a#e.:i#po#e013 < < c a## C):Sy#te! : Shape ; pri*ate Circ e c3 pri*ate 'riang e t3 pri*ate LineJK ine# 9 ne. LineJ"0K3
)65
C):Sy#te!0int i1 : $a#e0i R "1; for0int D 9 03 D W "03 DRR1 ine#JDK 9 ne. Line0D2 D=D13 c 9 ne. Circ e0"13 t 9 ne. 'riang e0"13 Sy#te!.Con#o e.VriteLine0&Co!$ined con#tructor&13 < pu$ ic o*erride *oid :i#po#e01 ; Sy#te!.Con#o e.VriteLine0&C):Sy#te!.:i#po#e01&13 // 'he order of c eanup i# the re*er#e // of the order of initia iMation t.:i#po#e013 c.:i#po#e013 for0int i 9 ine#.Length 6 "3 i Z9 03 i661 ine#JiK.:i#po#e013 $a#e.:i#po#e013 < pu$ ic #tatic *oid Gain01 ; C):Sy#te! x 9 ne. C):Sy#te!0EF13 u#ing0x1; // Code and exception hand ing... < Sy#te!.Con#o e.VriteLine0&O#ing $ oc% eft&13 < <///:8 Everything in thi# #y#te+ i# #*+e kind *9 #hape G!hich it#el9 i# a kind *9 ob)ect #ince it# i+plicitly inherited 9r*+ the r**t cla## and !hich i+ple+ent# an inter$ace called -?i#p*#a3leH) Each cla## rede9ine# #hape# $ispose( ) +eth*d in additi*n t* calling the 3a#eEcla## ver#i*n *9 that +eth*d u#ing base) The #peci9ic #hape cla##e#RCircle, +riangle and LineRall have c*n#truct*r# that Idra!,J alth*ugh any +eth*d called during the li9eti+e *9 the *34ect c*uld 3e re#p*n#i3le 9*r d*ing #*+ething that need# cleanup) Each cla## ha# it# *!n $ispose( ) +eth*d t* re#t*re n*n+e+*ry thing# 3ack t* the !ay they !ere 3e9*re the *34ect e;i#ted) -n .ain( ), y*u can #ee the using key!*rd in acti*n) = using 3l*ck take# an B$isposable a# an argu+ent) ,hen e;ecuti*n leave# the 3l*ck Geven i9 an e;cepti*n i# thr*!nH, B$isposable6$ispose() i# called) But 3ecau#e !e have i+ple+ented $ispose() in #hape and all the cla##e#
)66
Thinking in C
www.ThinkingIn.!et
derived 9r*+ it, inheritance kick# in and the appr*priate $ispose() +eth*d i# called) -n thi# ca#e, the u#ing 3l*ck ha# a C'$#ystem) -t# $ispose() +eth*d call#, in turn, the $ispose() +eth*d *9 the *34ect# !hich c*+pri#e it) *te that in y*ur cleanup +eth*d y*u +u#t al#* pay attenti*n t* the calling *rder 9*r the 3a#eEcla## and +e+3erE*34ect cleanup +eth*d# in ca#e *ne #u3*34ect depend# *n an*ther) -n general, y*u #h*uld 9*ll*! the #a+e 9*r+ that i# i+p*#ed 3y a C@@ c*+piler *n it# de#truct*r#1 5ir#t per9*r+ all *9 the cleanup !*rk #peci9ic t* y*ur cla##, in the rever#e *rder *9 creati*n) G-n general, thi# reDuire# that 3a#eEcla## ele+ent# #till 3e via3le)H Then call the 3a#eEcla## $ispose +eth*d, a# de+*n#trated here) There can 3e +any ca#e# in !hich the cleanup i##ue i# n*t a pr*3le+Q y*u 4u#t let the gar3age c*llect*r d* the !*rk) But !hen y*u +u#t d* it e;plicitly, diligence and attenti*n i# reDuired)
)6#
*34ect #* that y*u can u#e it t* i+ple+ent 9uncti*nality in y*ur ne! cla##, 3ut the u#er *9 y*ur ne! cla## #ee# the inter9ace y*uve de9ined 9*r the ne! cla## rather than the inter9ace 9r*+ the e+3edded *34ect) 5*r thi# e99ect, y*u e+3ed private *34ect# *9 e;i#ting cla##e# in#ide y*ur ne! cla##) S*+eti+e# it +ake# #en#e t* all*! the cla## u#er t* directly acce## the c*+p*#iti*n *9 y*ur ne! cla##Q that i#, t* +ake the +e+3er *34ect# public) The +e+3er *34ect# u#e i+ple+entati*n hiding the+#elve#, #* thi# i# a #a9e thing t* d*) ,hen the u#er kn*!# y*ure a##e+3ling a 3unch *9 part#, it +ake# the inter9ace ea#ier t* under#tand) = car *34ect i# a g**d e;a+ple1 //:c0?:Car.c# // Co!po#ition .ith pu$ ic o$Dect#. //\todo: _ood p ace to ta % a$out enforced acce## *i#i$i ity 0+ngine can't $e interna if +ngine i# pu$ ic in Car1 pu$ ic c pu$ ic pu$ ic pu$ ic < a## +ngine ; *oid #tart01 ;< *oid re*01 ;< *oid #top01 ;<
pu$ ic c a## Vhee ; pu$ ic *oid inf ate0int p#i1 ;< < pu$ ic c a## Vindo. ; pu$ ic *oid ro up01 ;< pu$ ic *oid ro do.n01 ;< < pu$ ic c pu$ ic pu$ ic pu$ ic < a## :oor ; Vindo. .indo. 9 ne. Vindo.013 *oid open01 ;< *oid c o#e01 ;<
)6&
Thinking in C
www.ThinkingIn.!et
pu$ ic Vhee JK .hee 9 ne. Vhee JEK3 pu$ ic :oor eft 9 ne. :oor012 right 9 ne. :oor013 // 26door pu$ ic Car01 ; for0int i 9 03 i W E3 iRR1 .hee JiK 9 ne. Vhee 013 < pu$ ic #tatic *oid Gain01 ; Car car 9 ne. Car013 car. eft..indo..ro up013 car..hee J0K.inf ate0F213 < < ///:8 Ot*d*1 >**d place t* talk a3*ut inde;er#F Becau#e the c*+p*#iti*n *9 a car i# part *9 the analy#i# *9 the pr*3le+ Gand n*t #i+ply part *9 the underlying de#ignH, +aking the +e+3er# public a##i#t# the client pr*gra++er# under#tanding *9 h*! t* u#e the cla## and reDuire# le## c*de c*+ple;ity 9*r the creat*r *9 the cla##) H*!ever, keep in +ind that thi# i# a #pecial ca#e and that in general y*u #h*uld +ake 9ield# private) ,hen y*u inherit, y*u take an e;i#ting cla## and +ake a #pecial ver#i*n *9 it) -n general, thi# +ean# that y*ure taking a generalEpurp*#e cla## and #peciali7ing it 9*r a particular need) ,ith a little th*ught, y*ull #ee that it !*uld +ake n* #en#e t* c*+p*#e a car u#ing a vehicle *34ectRa car d*e#nt c*ntain a vehicle, it is a vehicle) The is9a relati*n#hip i# e;pre##ed !ith inheritance, and the has9a relati*n#hip i# e;pre##ed !ith c*+p*#iti*n)
$rotected
*! that y*uve 3een intr*duced t* inheritance, the key!*rd protected 9inally ha# +eaning) -n an ideal !*rld, private +e+3er# !*uld al!ay# 3e hardEandE9a#t private, 3ut in real pr*4ect# there are ti+e# !hen y*u !ant t* +ake #*+ething hidden 9r*+ the !*rld at large and yet all*! acce## 9*r +e+3er# *9 derived cla##e#) The protected key!*rd i# a n*d t* prag+ati#+) -t #ay# IThi# i# private a# 9ar a# the cla## u#er i# c*ncerned,
)6'
3ut availa3le t* any*ne !h* inherit# 9r*+ thi# cla##)J Ot*d*1 -ntr*duce internal in di#cu##i*n *9 na+e#pace# The 3e#t tack t* take i# t* leave the data +e+3er# privateRy*u #h*uld al!ay# pre#erve y*ur right t* change the underlying i+ple+entati*n) :*u can then all*! c*ntr*lled acce## t* inherit*r# *9 y*ur cla## thr*ugh protected +eth*d#1 //:c0?:Orc.c# // 'he protected %ey.ord. pu$ ic c a## Ni ain ; pri*ate int i3 protected int read01 ; return i3 protected *oid #et0int ii1 ; i 9 pu$ ic Ni ain0int ii1 ; i 9 ii3 pu$ ic int *a ue0int !1 ; return <
pu$ ic c a## Orc : Ni ain ; pri*ate int D3 pu$ ic Orc0int DD1 :$a#e0DD1 ; D 9 DD3 < pu$ ic *oid change0int x1 ; #et0x13 < < ///:8 :*u can #ee that change( ) ha# acce## t* set( ) 3ecau#e it# protected)
Incre#ental develo$#ent
One *9 the advantage# *9 inheritance i# that it #upp*rt# incremental de-elo"ment 3y all*!ing y*u t* intr*duce ne! c*de !ith*ut cau#ing 3ug# in e;i#ting c*de) Thi# al#* i#*late# ne! 3ug# in#ide the ne! c*de) By inheriting 9r*+ an e;i#ting, 9uncti*nal cla## and adding data +e+3er# and +eth*d# Gand rede9ining e;i#ting +eth*d#H, y*u leave the e;i#ting c*deRthat #*+e*ne el#e +ight #till 3e u#ingRunt*uched and un3ugged) -9 a 3ug happen#, y*u kn*! that it# in y*ur ne! c*de, !hich i# +uch #h*rter and ea#ier t* read than i9 y*u had +*di9ied the 3*dy *9 e;i#ting c*de)
)#(
Thinking in C
www.ThinkingIn.!et
-t# rather a+a7ing h*! cleanly the cla##e# are #eparated) :*u d*nt even need the #*urce c*de 9*r the +eth*d# in *rder t* reu#e the c*de) =t +*#t, y*u 4u#t i+p*rt a package) GThi# i# true 9*r 3*th inheritance and c*+p*#iti*n)H -t# i+p*rtant t* reali7e that pr*gra+ devel*p+ent i# an incre+ental pr*ce##, 4u#t like hu+an learning) :*u can d* a# +uch analy#i# a# y*u !ant, 3ut y*u #till !*nt kn*! all the an#!er# !hen y*u #et *ut *n a pr*4ect) :*ull have +uch +*re #ucce##Rand +*re i++ediate 9eed3ackR i9 y*u #tart *ut t* Igr*!J y*ur pr*4ect a# an *rganic, ev*luti*nary creature, rather than c*n#tructing it all at *nce like a gla##E3*; #ky#craper) =lth*ugh inheritance 9*r e;peri+entati*n can 3e a u#e9ul techniDue, at #*+e p*int a9ter thing# #ta3ili7e y*u need t* take a ne! l**k at y*ur cla## hierarchy !ith an eye t* c*llap#ing it int* a #en#i3le #tructure) Re+e+3er that underneath it all, inheritance i# +eant t* e;pre## a relati*n#hip that #ay# IThi# ne! cla## i# a t4"e o$ that *ld cla##)J :*ur pr*gra+ #h*uld n*t 3e c*ncerned !ith pu#hing 3it# ar*und, 3ut in#tead !ith creating and +anipulating *34ect# *9 vari*u# type# t* e;pre## a +*del in the ter+# that c*+e 9r*+ the pr*3le+ #pace)
>$casting
The +*#t i+p*rtant a#pect *9 inheritance i# n*t that it pr*vide# +eth*d# 9*r the ne! cla##) -t# the relati*n#hip e;pre##ed 3et!een the ne! cla## and the 3a#e cla##) Thi# relati*n#hip can 3e #u++ari7ed 3y #aying IThe ne! cla## is a t4"e o$ the e;i#ting cla##)J Thi# de#cripti*n i# n*t 4u#t a 9anci9ul !ay *9 e;plaining inheritanceRit# #upp*rted directly 3y the language) =# an e;a+ple, c*n#ider a 3a#e cla## called Bnstrument that repre#ent# +u#ical in#tru+ent#, and a derived cla## called =ind) Becau#e inheritance +ean# that all *9 the +eth*d# in the 3a#e cla## are al#* availa3le in the derived cla##, any +e##age y*u can #end t* the 3a#e cla## can al#* 3e #ent t* the derived cla##) -9 the Bnstrument cla## ha# a !lay( ) +eth*d, #* !ill =ind in#tru+ent#) Thi# +ean# !e can accurately #ay that a =ind *34ect i# al#* a type *9 Bnstrument) The 9*ll*!ing e;a+ple #h*!# h*! the c*+piler #upp*rt# thi# n*ti*n1
)#1
//:c0?:Vind.c# // 5nheritance @ upca#ting. pu$ ic c a## 5n#tru!ent ; pu$ ic *oid p ay01 ;< #tatic interna *oid tune05n#tru!ent i1 ; // ... i.p ay013 < < // Vind o$Dect# are in#tru!ent# // $ecau#e they ha*e the #a!e interface: pu$ ic c a## Vind : 5n#tru!ent ; pu$ ic #tatic *oid Gain01 ; Vind f ute 9 ne. Vind013 5n#tru!ent.tune0f ute13 // Opca#ting < < ///:8 ,hat# intere#ting in thi# e;a+ple i# the +une( ) +eth*d, !hich accept# an Bnstrument re9erence) H*!ever, in =ind).ain( ) the +une( ) +eth*d i# called 3y giving it a =ind re9erence) >iven that C# i# particular a3*ut type checking, it #ee+# #trange that a +eth*d that accept# *ne type !ill readily accept an*ther type, until y*u reali7e that a =ind *34ect i# al#* an Bnstrument *34ect, and there# n* +eth*d that +une( ) c*uld call 9*r an Bnstrument that i#nt al#* in =ind) -n#ide +une( ), the c*de !*rk# 9*r Bnstrument and anything derived 9r*+ Bnstrument, and the act *9 c*nverting a =ind re9erence int* an Bnstrument re9erence i# called u"casting)
Wh5 Gu$castingH<
The rea#*n 9*r the ter+ i# hi#t*rical, and 3a#ed *n the !ay cla## inheritance diagra+# have traditi*nally 3een dra!n1 !ith the r**t at the t*p *9 the page, gr*!ing d*!n!ard) GO9 c*ur#e, y*u can dra! y*ur diagra+# any !ay y*u 9ind help9ul)H The inheritance diagra+ 9*r =ind6)ava i# then1
)#)
Thinking in C
www.ThinkingIn.!et
In stru # e n t
W in d
Ca#ting 9r*+ derived t* 3a#e +*ve# u" *n the inheritance diagra+, #* it# c*++*nly re9erred t* a# u"casting) Upca#ting i# al!ay# #a9e 3ecau#e y*ure g*ing 9r*+ a +*re #peci9ic type t* a +*re general type) That i#, the derived cla## i# a #uper#et *9 the 3a#e cla##) -t +ight c*ntain +*re +eth*d# than the 3a#e cla##, 3ut it +u#t c*ntain at least the +eth*d# in the 3a#e cla##) The *nly thing that can *ccur t* the cla## inter9ace during the upca#t i# that it can l*#e +eth*d#, n*t gain the+) Thi# i# !hy the c*+piler all*!# upca#ting !ith*ut any e;plicit ca#t# *r *ther #pecial n*tati*n) :*u can al#* per9*r+ the rever#e *9 upca#ting, called downcasting, 3ut thi# inv*lve# a dile++a that i# the #u34ect *9 Chapter 02)
)#3
-n "ava, thi# !*uld l**k like1 c a## Oten#i ; pu$ ic *oid _etHood01; //L< < c a## Hor% extend# Oten#i ; pu$ ic *oid _etHood01; Sy#te!.out.print n0ASpearB13 < < c a## Spoon extend# Oten#i ; pu$ ic *oid _etHood01; Sy#te!.out.print n0AScoopB13 < < -n C#, y*u have t* 4u+p thr*ugh a 3it *9 a h**pQ +eth*d# 9*r !hich *verl*ading i# intended +u#t 3e declared virtual and the *verl*ading
)#4
Thinking in C
www.ThinkingIn.!et
+eth*d +u#t 3e declared a# an override) T* get the de#ired #tructure !*uld l**k like thi#1 c a## Oten#i ; pu$ ic *irtua < *oid _etHood01; //L<
c a## Hor% extend# Oten#i ; pu$ ic o*erride *oid _etHood01; Sy#te!.out.print n0ASpearB13 < < c a## Spoon extend# Oten#i ; pu$ ic o*erride *oid _etHood01; Sy#te!.out.print n0AScoopB13 < < Thi# i# a 3ehavi*r that #te+# 9r*+ Aicr*#*9t# e;perience !ith I?LL HellJ and th*ught# a3*ut a !*rld in !hich *34ectE*riented c*+p*nent# are the 3uilding 3l*ck# *9 very large #y#te+#) -+agine that y*u are u#ing "ava and u#ing a /rdEparty INitchenJ c*+p*nent that include# the 3a#e cla## *9 Uten#il, 3ut y*u cu#t*+i7e it t* u#e that #taple *9 d*r+ li9e P the Sp*rk) But in additi*n t* i+ple+enting et:ood(), y*u add a d*r+Elike +eth*d =ash()1 //Spor%.Da*a c a## Spor% extend# Oten#i ; pu$ ic *oid _etHood01; Sy#te!.out.print n0ASpear OR Scoop!B13 < pu$ ic *oid Va#h01; Sy#te!.out.print n0AVipe .ith nap%inB13 < < O9 c*ur#e, #ince =ash i#nt i+ple+ented in Vtensil, y*u c*uld *nly I!a#hJ a #p*rk G!hich i# 4u#t a# !ell, c*n#idering the unhygienic nature *9 the i+ple+entati*nH) S* the pr*3le+ happen# !hen the /rdEparty Nitchen c*+p*nent vend*r relea#e# a ne! ver#i*n *9 their c*+p*nent, and thi#
)#5
ti+e theyve i+ple+ent a +eth*d !ith an identical #ignature t* the *ne y*u !r*te1 //Oten#i .Da*a \*er#ion: 2.0 c a## Oten#i ; pu$ ic *oid _etHood01; //L < pu$ ic *oid Va#h01; !y:i#h.a#her.add0thi#13 //etcL < < The vend*r ha# i+ple+ented a =ash() +eth*d !ith c*+ple; 3ehavi*r inv*lving a di#h!a#her) >iven thi# ne! capa3ility, pe*ple pr*gra++ing !ith Uten#il v2 !ill have every right t* a##u+e that *nce =ash() ha# 3een called, all Uten#il# !ill have g*ne thr*ugh the di#h!a#her) But in language# #uch a# "ava, the =ash() +eth*d in Sp*rk !ill #till 3e calledK
-t +ay #ee+ highly unlikely that a ne! ver#i*n *9 a 3a#e cla## !*uld I4u#t happenJ t* have the #a+e na+e a# an endEu#er# e;ten#i*n, 3ut i9 y*u think a3*ut it, it# actually kind *9 #urpri#ing it d*e#nt happen +*re *9ten, a# the nu+3er *9 l*gical +eth*d na+e# 9*r a given categ*ry *9 3a#e cla## i# 9airly li+ited) -n C#, the 3ehavi*r in Client# =ash'll() +eth*d !*uld !*rk e;actly the !ay client# e;pect, !ith Vtensil# di#h!a#her =ash() 3eing called 9*r all uten#il# in myVtensils, even i9 *ne happen# t* 3e a #por()
)#6
Thinking in C
www.ThinkingIn.!et
*! let# #ay y*u c*+e al*ng and #tart !*rking *n Sp*rk again a9ter upgrading t* the ver#i*n *9 Uten#il that ha# a =ash() +eth*d) ,hen y*u c*+pile Sp*rk)c#, the c*+piler !ill #ay1 .arning CS0"0I: 'he %ey.ord ne. i# re7uired on 'Spor%.Va#h01' $ecau#e it hide# inherited !e!$er 'Oten#i .Va#h01' =t thi# p*int, call# t* Vtensil6=ash() are re#*lved !ith the di#h!a#her !a#hing +eth*d, !hile i9 y*u have a handle t* a Sp*rk, the napkinE!iping !a#h +eth*d !ill 3e called) //:c0?:Oten#i .c# c a## Oten#i ; pu$ ic *irtua *oid _etHood01; < pu$ ic *oid Va#h01; Sy#te!.Con#o e.VriteLine0&Va#hing in a di#h.a#her&13 < < c a## Hor% : Oten#i ; pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear&13 < < c a## Spor% : Oten#i ; pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear OR Scoop!&13 < pu$ ic *oid Va#h01; Sy#te!.Con#o e.VriteLine0&Vipe .ith nap%in&13 < < c a## C ient; Oten#i JK !yOten#i #3
)##
C ient01; !yOten#i # 9 ne. Oten#i J2K3 !yOten#i #J0K 9 ne. Spor%013 !yOten#i #J"K 9 ne. Hor%013 < pu$ ic *oid Va#h) 01; foreach0Oten#i u in !yOten#i #1; u.Va#h013 < < pu$ ic #tatic *oid Gain01; C ient c 9 ne. C ient013 c.Va#h) 013 Spor% # 9 ne. Spor%013 #.Va#h013 < <///:8 re#ult# in the *utput1 Va#hing in a di#h.a#her Va#hing in a di#h.a#her Vipe .ith nap%in -n *rder t* re+*ve the !arning that #por(6=ash() i# hiding the ne!ly +inted Vtensil6=ash(), !e can add the key!*rd new t* #por(# declarati*n1 pu$ ic ne. *oid Va#h01; //L etc ... -t# even p*##i3le 9*r y*u t* have entirely #eparate +eth*d inheritance hierarchie# 3y declaring a +eth*d a# new virtual) -+agine that 9*r ver#i*n / *9 the Nitchen c*+p*nent, theyve created a ne! type *9 Vtensil, #ilverware, !hich reDuire# p*li#hing a9ter cleaning) Aean!hile, y*uve created a ne! kind *9 #por(, a #uper#por(, !hich al#* ha# *verridden the 3a#e #por(6=ash() +eth*d) The c*de l**k# like thi#1 //:c0?:Oten#i 2.c# c a## Oten#i ; pu$ ic *irtua *oid _etHood01; <
)#&
Thinking in C
www.ThinkingIn.!et
pu$ ic *irtua *oid Va#h01; Sy#te!.Con#o e.VriteLine0&Va#hing in a di#h.a#her&13 < < c a## Si *er.are : Oten#i ; pu$ ic o*erride *oid Va#h01; $a#e.Va#h013 Sy#te!.Con#o e.VriteLine0&-o i#h .ith #i *er c eaner&13 < < c a## Hor% : Si *er.are; pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear&13 < < c a## Spor% : Si *er.are; pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear OR Scoop!&13 < pu$ ic ne. *irtua *oid Va#h01; Sy#te!.Con#o e.VriteLine0&Vipe .ith nap%in&13 < < c a## SuperSpor% : Spor%; pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear )C: Scoop&13 < pu$ ic o*erride *oid Va#h01; $a#e.Va#h013 Sy#te!.Con#o e.VriteLine0&-o i#h .ith #hirt&13 < <
)#'
c a## C ient; Oten#i JK !yOten#i #3 C ient01; !yOten#i # 9 ne. Oten#i JTK3 !yOten#i #J0K 9 ne. Spor%013 !yOten#i #J"K 9 ne. Hor%013 !yOten#i #J2K 9 ne. SuperSpor%013 < pu$ ic *oid Va#h) 01; foreach0Oten#i u in !yOten#i #1; u.Va#h013 < Sy#te!.Con#o e.VriteLine0&) Oten#i # .a#hed&13 < pu$ ic #tatic *oid Gain01; C ient c 9 ne. C ient013 c.Va#h) 013 Spor% # 9 ne. SuperSpor%013 #.Va#h013 < <///:8 *!, all *9 *ur Uten#il# have 3een replaced 3y Silver!are and, !hen Client),a#h=llGH i# called, #ilverware6=ash() *verl*ad# Vtensil6=ash()) G *te that #ilverware6=ash() call# Vtensil6=ash() u#ing base6=ash(), in the #a+e +anner a# 3a#e c*n#truct*r# can 3e called)H =ll Uten#il# in Client# )+yUten#il# array are n*! !a#hed in a di#h!a#her and then p*li#hed) *te the declarati*n in Sp*rk1 pu$ ic ne. *irtua *oid Va#h01; //etc <
and the declarati*n in the ne!ly +inted #uper#por( cla##1 pu$ ic o*erride *oid Va#h01; //etc. <
)&(
Thinking in C
www.ThinkingIn.!et
,hen the Client cla## ha# a re9erence t* a Uten#il #uch a# it d*e# in =ash'llGH G!hether the c*ncrete type *9 that Uten#il 3e a 5*rk, a Sp**n, *r a Sp*rkH, the =ash() +eth*d re#*lve# t* the appr*priate *verl*aded +eth*d in #ilverware) ,hen, h*!ever, the client ha# a re9erence t* a Sp*rk *r any Sp*rkE#u3type, the =ash() +eth*d re#*lve# t* !hatever ha# *verl*aded #por(# new virtual =ash()) The *utput l**k# like thi#1 Va#hing in a di#h.a#her -o i#h .ith #i *er c eaner Va#hing in a di#h.a#her -o i#h .ith #i *er c eaner Va#hing in a di#h.a#her -o i#h .ith #i *er c eaner ) Oten#i # .a#hed Vipe .ith nap%in -o i#h .ith #hirt =nd thi# UAL diagra+ #h*!# the 3ehavi*r graphically1
)&1
Let# #ay that y*u !anted t* create a ne! cla## #elfCleansing#uper#por(, that *verl*aded 3*th the =ash() +eth*d a# de9ined in Vtensil and the =ash() +eth*d a# de9ined in #por() ,hat c*uld y*u d*F :*u cann*t create a #ingle +eth*d na+e that *verride# 3*th 3a#e +eth*d#) =# i# generally the ca#e, !hen 9aced !ith a hard pr*gra++ing pr*3le+, the an#!er lie# in de#ign, n*t language #ynta;) Re+e+3er *ur +a;i+1 3*ring c*de, intere#ting re#ult#) One *9 the 9ir#t thing# that 4u+p# *ut !hen c*n#idering thi# pr*3le+ i# that the inheritance hierarchy i# getting deep) ,hat !ere pr*p*#ing i# that a #elfCleaning#uper#por( i#Ea #uper#por( i#Ea #por( i#Ea #ilverware i#Ea Vtensil i#Ean ob)ect) That# #i; level# *9 hierarchy P *ne +*re than Linnaeu# u#ed t* cla##i9y all living 3eing# in 0%/'K -t# n*t i+p*##i3le 9*r a de#ign t* have thi# +any layer# *9 inheritance, 3ut in general, *ne #h*uld 3e du3i*u# *9 hierarchie# *9 +*re than t!* *r three level# 3el*! ob)ect6
)&)
Thinking in C
www.ThinkingIn.!et
Bearing in +ind that *ur hierarchy i# getting deep, !e +ight al#* n*tice that *ur na+e# are 3ec*+ing l*ng and unnatural P #elfCleaning#uper#por(6 ,hile c*+ing up !ith de#criptive na+e# !ith*ut getting cute i# *ne *9 the harder ta#k# in pr*gra++ing EE - cant tell y*u h*! +any execute(), run(), and %uery() +eth*d# -ve #een, !hile -ve heard a #t*ry *9 a varia3le la3eled beethoven 3ecau#e it# initial value happened t* 3e 020., the c*+p*#er# 3irthday P #*+ething# !r*ng !hen a cla## na+e 3ec*+e# a h*dgeEp*dge *9 ad4ective#) -n thi# ca#e, *ur na+e# are 3eing u#ed t* di#tingui#h 3et!een t!* di99erent pr*pertie# P the #hape *9 the Uten#il G:or(, #poon, #por(, and #uper#por(H and the cleaning 3ehavi*r G#ilverware, #por(, and #elfCleaning#uper#por(H) Thi# i# a clue that *ur de#ign !*uld 3e 3etter u#ing c*+p*#iti*n rather than inheritance) =# i# very *9ten the ca#e, !e di#c*ver that *ne *9 the Ivect*r# *9 changeJ i# +*re naturally #tructural Gthe #hape *9 the uten#ilH and that an*ther i# +*re 3ehavi*ral Gthe cleaning regi+enH) ,e can try *ut the phra#e I= uten#il ha# a cleaning regi+en,J t* #ee i9 it #*und# right, !hich indeed it d*e#1
,hen a Uten#il i# c*n#tructed, it ha# a handle t* a particular type *9 cleaning regi+en, 3ut it# ,a#h +eth*d d*e#nt have t* kn*! the #peci9ic #u3type *9 CleaningRegi+en it i# u#ing1
)&3
Thi# i# called the @trateg4 Pattern and it i#, - think, the +*#t i+p*rtant *9 all the de#ign pattern#)
Thi# i# !hat the c*de !*uld l**k like1 //:c0?:Oten#i T.c# u#ing Sy#te!3
)&4
Thinking in C
www.ThinkingIn.!et
pu$ ic c a## Oten#i ; pri*ate C eaningRegi!en !yC eaningRegi!en3 protected Oten#i 0C eaningRegi!en reg1; !yC eaningRegi!en 9 reg3 < pu$ ic *oid Va#h01; !yC eaningRegi!en.Va#h013 < pu$ ic *irtua < < c a## Hor%; pu$ ic Hor%01 : $a#e0ne. :i#h.a#h011;< pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear food&13 < < c a## Spoon; pu$ ic Spoon01 : $a#e0ne. :i#h.a#h011;< pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Scoop food&13 < < c a## Spor%; pu$ ic Spor%01 : $a#e0ne. VipeVithCap%in011;< pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear or #coop!&13 < < c a## C eaningRegi!en; protected o*erride *oid Va#h013 < *oid _etHood01;
)&5
c a## :i#h.a#h : C eaningRegi!en; protected o*erride *oid Va#h01; Sy#te!.Con#o e.VriteLine0&Va#h in di#h.a#her&13 < < c a## VipeVithCap%in : C eaningRegi!en; protected o*erride *oid Va#h01; Sy#te!.Con#o e.VriteLine0&Vipe .ith nap%in&13 < <///:8 =t thi# p*int, every type *9 Uten#il ha# a particular type *9 CleaningRegi+en a##*ciated !ith it, an a##*ciati*n !hich i# hardEc*ded in the c*n#truct*r# *9 the Uten#il #u3type# Gi)e), public #por(() D base(new =ipe=ith,ap(in())H) H*!ever, y*u can #ee h*! it !*uld 3e a trivial +atter t* t*tally dec*uple the Vtensil# type *9 Cleaning*egimen 9r*+ the c*n#truct*r P y*u c*uld pa## in the Cleaning*egimen 9r*+ #*+eplace el#e, ch**#e it rand*+ly, and #* 9*rth) ,ith thi# de#ign, *ne can ea#ily achieve *ur g*al *9 a #uper uten#il that c*+3ine# +ultiple cleaning #trategie#1 c a## SuperSpor% : Spor%; C eaningRegi!en #econdRegi!en3 pu$ ic SuperSpor%: #uper0ne. :i#h.a#h011; #econdRegi!en 9 ne. Cap%inVa#h013 < pu$ ic o*erride *oid Va#h01; $a#e.Va#h013 #econdRegi!en.Va#h013 < < -n thi# #ituati*n, the SuperSp*rk n*! ha# t!* CleaningRegi+en#, the n*r+al myCleaning*egimen and a ne! second*egimen) Thi# i# the type *9 9le;i3ility that y*u can h*pe t* achieve 3y 9av*ring aggregati*n *ver inheritance)
)&6
Thinking in C
www.ThinkingIn.!et
Our *riginal challenge, th*ugh, inv*lved a /rd party Nitchen c*+p*nent that pr*vided the 3a#ic de#ign) ,ith*ut acce## t* the #*urce c*de, there i# n* !ay t* i+ple+ent *ur i+pr*ved de#ign) Thi# i# *ne *9 the thing# that +ake# it hard t* !rite c*+p*nent# 9*r reu#e P I9ully 3akedJ c*+p*nent# that are ea#y t* u#e *ut *9 the 3*; are *9ten hard t* cu#t*+i7e and e;tend, !hile Ic*n#tructi*n kitJ c*+p*nent# that need t* 3e a##e+3led typically can #*+eti+e# take a l*ng ti+e t* learn)
)&#
The readonly key!*rd i# +*re general) -t can 3e applied t* any type and i# evaluated *nceEandE*nlyE*nce at runti+e) Typically, readonly 9ield# are initiali7ed at either the ti+e *9 cla## l*ading Gin the ca#e *9 #tatic 9ield#H, *r at the ti+e *9 in#tance initiali7ati*n 9*r in#tance varia3le#) -t# n*t nece##ary t* li+it readonly 9ield# t* value# that are e##entially c*n#tant, y*u c*uld u#e a readonly 9ield 9*r any data that, *nce a##igned, #h*uld 3e invariant P a per#*n# na+e *r #*cial #ecurity nu+3er, a net!*rk addre## *r p*rt *9 a h*#t, etc) readonly d*e# n*t +ake an *34ect i++uta3le) ,hen applied t* a n*nE valueEtype *34ect, readonly l*ck# *nly y*ur re9erence t* the *34ect, n*t the #tate *9 the *34ect it#el9) Such an *34ect can g* thr*ugh !hatever #tate tran#iti*n# are pr*gra++ed int* it P pr*pertie# can 3e #et, it can change it# internal #tate 3a#ed *n calculati*n#, etc) The *nly thing y*u cant d* i# change the re9erence t* the *34ect) Thi# can 3e #een in thi# e;a+ple, !hich de+*n#trate# readonly) //:c0?:Co!po#ition.c# u#ing Sy#te!3 u#ing Sy#te!.'hreading3 na!e#pace Co!po#ition ; pu$ ic c a## ReadOn y; #tatic readon y :ate'i!e ti!eOfC a##Load 9 :ate'i!e.Co.3 readon y :ate'i!e ti!eOf5n#tanceCreation 9 :ate'i!e.Co.3 pu$ ic ReadOn y01 ; Sy#te!.Con#o e.VriteLine0&C a## oaded at ;0<2 5n#tance created at ;"<&2 ti!eOfC a##Load2 ti!eOf5n#tanceCreation13 < //u#ed in #econd part of progra! #tatic readon y ReadOn y ro 9 ne. ReadOn y013 pu$ ic int id3 pu$ ic int 5d; get; return id3 < #et; id 9 *a ue3 < <
)&&
Thinking in C
www.ThinkingIn.!et
pu$ ic #tatic *oid Gain01; for0int i 9 03 i W "03 iRR1; ne. ReadOn y013 'hread.S eep0"00013 < //Can change !e!$er ro.5d 9 P3 Sy#te!.Con#o e.VriteLine0ro.5d13 //! Co!pi er #ay# Aa #tatic readon y fie d cannot $e // a##igned toB //ro 9 ne. ReadOn y013 < < <///:8
-n *rder t* de+*n#trate h*! *34ect# created at di99erent ti+e# !ill have di99erent 9ield#, the pr*gra+ u#e# the Thread)SleepGH +eth*d 9r*+ the Threading na+e#pace, !hich !ill 3e di#cu##ed at length in #+ultithreading#) The cla## *ead1nly c*ntain# t!* readonly 9ield# P the #tatic +ime1fClassLoad 9ield and the in#tance varia3le time1fBnstanceCreation) The#e 9ield# are *9 type $ate+ime, !hich i# the 3a#ic ) ET *34ect 9*r c*unting ti+e) B*th 9ield# are initiali7ed 9r*+ the #tatic ?ateTi+e pr*perty *!, !hich repre#ent# the #y#te+ cl*ck) ,hen the .ain create# the 9ir#t *ead1nly *34ect and the #tatic 9ield# are initiali7ed a# di#cu##ed previ*u#ly, +ime1fClassLoad i# #et *nceE andE9*rEall) Then, the in#tance varia3le 9ield time1fBnstanceCreation i# initiali7ed) 5inally, the c*n#truct*r i# called, and it print# the value *9 the#e t!* 9ield# t* the c*n#*le) +hread6#leep(7444) i# then u#ed t* pau#e the pr*gra+ 9*r a #ec*nd G0,$$$ +illi#ec*nd#H 3e9*re creating an*ther *ead1nly) The 3ehavi*r *9 the pr*gra+ until thi# p*int !*uld 3e n* di99erent i9 the#e 9ield# !ere n*t declared a# readonly, #ince !e have +ade n* atte+pt t* +*di9y the 9ield#) That change# in the line# 3el*! the l**p) -n additi*n t* the readonly $ate+ime 9ield#, !e have a static readonly *ead1nly 9ield la3eled ro
)&'
Gthe cla## *ead1nly c*ntain# a re9erence t* an in#tance *9 *ead1nly P a c*++*n idi*+ that i# kn*!n a# a I#inglet*nJH) ,e al#* have a pr*perty called Bd, 3ut n*te that it i# n*t readonly) G=# a revie! *9 the di#cu##i*n in #initiali7ati*n#, y*u #h*uld 3e a3le t* 9igure *ut h*! the value# *9 ro# time1fClassLoad and time1fBnstanceCreation !ill relate t* the 9ir#t *ead1nly created in the .ain l**p)H =lth*ugh the re9erence t* ro i# read *nly, the line r*)-d X 'Q de+*n#trate# h*! it i# p*##i3le t* change the #tate *9 a readonly re9erence) ,hat !e cant d*, th*ugh, i# #h*!n in the c*++entedE*ut line# in the e;a+ple P i9 !e atte+pt t* a##ign t* ro, !ell get a c*+pile ti+e err*r) The advantage *9 readonly *ver const i# that const# c*+pileEti+e +ath i# i++uta3le) -9 a cla## Phy#icalC*n#tant# had a public const that #et the #peed *9 light t* /$$,$$$ kil*+eter# per #ec*nd and an*ther cla## u#ed that 9*r c*+pileEti+e +ath Gcon#t ong a5LOG+'+RSX5CX)XL5_U'X/+)R 9 -hy#ica Con#tant#.C = T?00 = 2E = :)/SX-+RX/+)RH, the value *9 a5LOG+'+RSX5CX)XL5_U'X/+)R !ill 3e 3a#ed *n the /$$,$$$ value, even i9 the 3a#e cla## i# updated t* a +*re accurate value #uch a# 266,%62) Thi# !ill 3e true until the cla## that de9ined EBL1.&+&*#AB,A'ALB "+A@&'* i# rec*+piled !ith acce## t* the updated Phy#icalC*n#tant# cla##) -9 the 9ield# !ere readonly th*ugh, the value 9*r EBL1.&+&*#AB,A'ALB "+A@&'* !*uld 3e calculated at runti+e, and !*uld n*t need t* 3e rec*+piled t* pr*perly re9lect the late#t value *9 C) =gain, thi# i# *ne *9 th*#e 9eature# !hich +ay n*t #ee+ like a 3ig deal t* +any applicati*n devel*per#, 3ut !h*#e nece##ity i# clear t* Aicr*#*9t a9ter a decade *9 I?LL Hell)J
'ealed classes
The readonly and const key!*rd# are u#ed 9*r l*cking d*!n value# and re9erence# that #h*uld n*t 3e changed) Becau#e *ne ha# t* declare a +eth*d a# virtual in *rder t* 3e *verridden, it i# ea#y t* create +eth*d# that !ill n*t 3e +*di9ied at runti+e) aturally, there i# a !ay t* #peci9y that an entire cla## 3e un+*di9ia3le) ,hen a cla## i# declared a# sealed, n* *ne can derive 9r*+ it)
)'(
Thinking in C
www.ThinkingIn.!et
There are t!* +ain rea#*n# t* +ake a cla## sealed) = sealed cla## i# +*re #ecure 9r*+ intenti*nal *r unintenti*nal ta+pering) =dditi*nally, virtual +eth*d# e;ecuted *n a sealed cla## can 3e replaced !ith direct 9uncti*n call#, pr*viding a #light per9*r+ance increa#e) //:c0?:`ura##ic.c# // Sea ing a c a## c a## S!a Brain ;<
#ea ed c a## :ino#aur ; interna int i 9 F3 interna int D 9 "3 S!a Brain x 9 ne. S!a interna *oid H01 ;< <
Brain013
//! c a## Hurther : :ino#aur ;< // error: Cannot extend #ea ed c a## ':ino#aur' pu$ ic c a## `ura##ic ; pu$ ic #tatic *oid Gain01 ; :ino#aur n 9 ne. :ino#aur013 n.H013 n.i 9 E03 n.DRR3 < <///:8 ?e9ining the cla## a# sealed #i+ply prevent# inheritanceRn*thing +*re) H*!ever, 3ecau#e it prevent# inheritance all +eth*d# in a sealed cla## are i+plicitly n*nEvirtual, #ince there# n* !ay t* *verride the+)
)'1
But 3e care9ul !ith y*ur a##u+pti*n#) -n general, it# di99icult t* anticipate h*! a cla## can 3e reu#ed, e#pecially a generalEpurp*#e cla##) Unle## y*u declare a +eth*d a# virtual, y*u prevent the p*##i3ility *9 reu#ing y*ur cla## thr*ugh inheritance in #*+e *ther pr*gra++er# pr*4ect #i+ply 3ecau#e y*u c*uldnt i+agine it 3eing u#ed that !ay)
)')
Thinking in C
www.ThinkingIn.!et
// 'he fu
c a## 5n#ect ; int i 9 >3 interna int D3 interna 5n#ect01 ; -rt0&i 9 & R i R &2 D 9 & R D13 D 9 T>3 < #tatic int x" 9 -rt0&#tatic 5n#ect.x" initia iMed&13 interna #tatic int -rt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 return EF3 < < c a## Beet e : 5n#ect ; int % 9 -rt0&Beet e.% initia iMed&13 Beet e01 ; -rt0&% 9 & R %13 -rt0&D 9 & R D13 < #tatic int x2 9 -rt0&#tatic Beet e.x2 initia iMed&13 pu$ ic #tatic *oid Gain01 ; -rt0&Beet e con#tructor&13 Beet e $ 9 ne. Beet e013 < < ///:8 The *utput 9*r thi# pr*gra+ i#1 #tatic 5n#ect.x" initia iMed #tatic Beet e.x2 initia iMed Beet e con#tructor i 9 >2 D 9 0 Beet e.% initia iMed % 9 EF D 9 T>
)'3
The 9ir#t thing that happen# !hen y*u run Beetle i# that y*u try t* acce## Beetle6.ain( ) Ga static +eth*dH, #* the l*ader g*e# *ut and 9ind# the c*+piled c*de 9*r the Beetle cla## Gthi# happen# t* 3e in an a##e+3ly called Beetle6exeH) -n the pr*ce## *9 l*ading it, the l*ader n*tice# that it ha# a 3a#e cla## Gthat# !hat the c*l*n a9ter class Beetle #ay#H, !hich it then l*ad#) Thi# !ill happen !hether *r n*t y*ure g*ing t* +ake an *34ect *9 that 3a#e cla##) GTry c*++enting *ut the *34ect creati*n t* pr*ve it t* y*ur#el9)H -9 the 3a#e cla## ha# a 3a#e cla##, that #ec*nd 3a#e cla## !*uld then 3e l*aded, and #* *n) e;t, the static initiali7ati*n in the r**t 3a#e cla## Gin thi# ca#e, BnsectH i# per9*r+ed, and then the ne;t derived cla##, and #* *n) Thi# i# i+p*rtant 3ecau#e the derivedEcla## #tatic initiali7ati*n +ight depend *n the 3a#e cla## +e+3er 3eing initiali7ed pr*perly) =t thi# p*int, the nece##ary cla##e# have all 3een l*aded #* the *34ect can 3e created) 5ir#t, all the pri+itive# in thi# *34ect are #et t* their de9ault value# and the *34ect re9erence# are #et t* nullRthi# happen# in *ne 9ell #!**p 3y #etting the +e+*ry in the *34ect t* 3inary 7er*) Then the 3a#eE cla## c*n#truct*r !ill 3e called) -n thi# ca#e the call i# aut*+atic, 3ut y*u can al#* #peci9y the 3a#eEcla## c*n#truct*r call Ga# the 9ir#t *perati*n in the Beetle( ) c*n#truct*rH u#ing base) The 3a#e cla## c*n#tructi*n g*e# thr*ugh the #a+e pr*ce## in the #a+e *rder a# the derivedEcla## c*n#truct*r) =9ter the 3a#eEcla## c*n#truct*r c*+plete#, the in#tance varia3le# are initiali7ed in te;tual *rder) 5inally, the re#t *9 the 3*dy *9 the c*n#truct*r i# e;ecuted)
'u##ar5
B*th inheritance and c*+p*#iti*n all*! y*u t* create a ne! type 9r*+ e;i#ting type#) Typically, h*!ever, y*u u#e c*+p*#iti*n t* reu#e e;i#ting type# a# part *9 the underlying i+ple+entati*n *9 the ne! type, and inheritance !hen y*u !ant t* reu#e the inter9ace) Since the derived cla## ha# the 3a#eEcla## inter9ace, it can 3e u"cast t* the 3a#e, !hich i# critical 9*r p*ly+*rphi#+, a# y*ull #ee in the ne;t chapter) ?e#pite the #tr*ng e+pha#i# *n inheritance in *34ectE*riented pr*gra++ing, !hen y*u #tart a de#ign y*u #h*uld generally pre9er c*+p*#iti*n during the 9ir#t cut and u#e inheritance *nly !hen it i# clearly
)'4
Thinking in C
www.ThinkingIn.!et
nece##ary) C*+p*#iti*n tend# t* 3e +*re 9le;i3le) -n additi*n, 3y u#ing the added arti9ice *9 inheritance !ith y*ur +e+3er type, y*u can change the e;act type, and thu# the 3ehavi*r, *9 th*#e +e+3er *34ect# at runE ti+e) There9*re, y*u can change the 3ehavi*r *9 the c*+p*#ed *34ect at runEti+e) =lth*ugh c*de reu#e thr*ugh c*+p*#iti*n and inheritance i# help9ul 9*r rapid pr*4ect devel*p+ent, y*ull generally !ant t* rede#ign y*ur cla## hierarchy 3e9*re all*!ing *ther pr*gra++er# t* 3ec*+e dependent *n it) :*ur g*al i# a hierarchy in !hich each cla## ha# a #peci9ic u#e and i# neither t** 3ig Genc*+pa##ing #* +uch 9uncti*nality that it# un!ieldy t* reu#eH n*r ann*yingly #+all Gy*u cant u#e it 3y it#el9 *r !ith*ut adding 9uncti*nalityH)
%&ercises
)'5
)'#
P*ly+*rphi#+ i# the ne;t e##ential 9eature *9 an *34ectE *riented pr*gra++ing language a9ter data a3#tracti*n) -t all*!# pr*gra+# t* 3e devel*ped in the 9*r+ *9 interacting agree+ent# *r Ic*ntract#J that #peci9y the 3ehavi*r, 3ut n*t the i+ple+entati*n, *9 cla##e#)
P*ly+*rphi#+ pr*vide# a di+en#i*n *9 #eparati*n *9 inter9ace 9r*+ i+ple+entati*n, t* dec*uple what 9r*+ how) P*ly+*rphi#+ all*!# i+pr*ved c*de *rgani7ati*n and reada3ility a# !ell a# the creati*n *9 e%tensi2le pr*gra+# that can 3e Igr*!nJ n*t *nly during the *riginal creati*n *9 the pr*4ect 3ut al#* !hen ne! 9eature# are de#ired) Encap#ulati*n create# ne! data type# 3y c*+3ining characteri#tic# and 3ehavi*r#) -+ple+entati*n hiding #eparate# the inter9ace 9r*+ the i+ple+entati*n 3y +aking the detail# private) Thi# #*rt *9 +echanical *rgani7ati*n +ake# ready #en#e t* #*+e*ne !ith a pr*cedural pr*gra++ing 3ackgr*und) But p*ly+*rphi#+ deal# !ith dec*upling in ter+# *9 t4"es) -n the la#t chapter, y*u #a! h*! inheritance all*!# the treat+ent *9 an *34ect a# it# *!n type or it# 3a#e type) Thi# a3ility i# critical 3ecau#e it all*!# +any type# Gderived 9r*+ the #a+e 3a#e typeH t* 3e treated a# i9 they !ere *ne type, and a #ingle piece *9 c*de t* !*rk *n all th*#e di99erent type# eDually) The p*ly+*rphic +eth*d call all*!# *ne type t* e;pre## it# di#tincti*n 9r*+ an*ther, #i+ilar type, a# l*ng a# theyre 3*th derived 9r*+ the #a+e 3a#e type) Thi# di#tincti*n i# e;pre##ed thr*ugh di99erence# in 3ehavi*r *9 the +eth*d# that y*u can call thr*ugh the 3a#e cla##)
)''
-n thi# chapter, y*ull learn a3*ut p*ly+*rphi#+ Gal#* called d4namic 2inding *r late 2inding *r run9time 2indingH #tarting 9r*+ the 3a#ic#, !ith #i+ple e;a+ple# that #trip a!ay everything 3ut the p*ly+*rphic 3ehavi*r *9 the pr*gra+)
>$casting revisited
-n Chapter #Reu#ing y*ur *34ect## y*u #a! h*! an *34ect can 3e u#ed a# it# *!n type *r a# an *34ect *9 it# 3a#e type) Taking an *34ect re9erence and treating it a# a re9erence t* it# 3a#e type i# called u"casting6 3ecau#e *9 the !ay inheritance tree# are dra!n !ith the 3a#e cla## at the t*p) :*u al#* #a! a pr*3le+ ari#e, !hich i# e+3*died in the 9*ll*!ing1 //:c0F:Gu#ic.c# // 5nheritance @ upca#ting. pu$ ic c a## Cote ; pri*ate int *a ue3 pri*ate Cote0int *a 1 ; *a ue 9 *a 3 < pu$ ic #tatic Cote G5::L+XC 9 ne. Cote0012 CXSU)R- 9 ne. Cote0"12 BXHL)' 9 ne. Cote0213 < // +tc. pu$ ic c a## 5n#tru!ent ;
3((
pu$ ic *irtua *oid - ay0Cote n1 ; Sy#te!.Con#o e.VriteLine0&5n#tru!ent.- ay01&13 < < // Vind o$Dect# are in#tru!ent# // $ecau#e they ha*e the #a!e interface: pu$ ic c a## Vind : 5n#tru!ent ; // Redefine interface !ethod: pu$ ic o*erride *oid - ay0Cote n1 ; Sy#te!.Con#o e.VriteLine0&Vind.- ay01&13 < < pu$ ic c a## Gu#ic ; pu$ ic #tatic *oid 'une05n#tru!ent i1 ; // ... i.- ay0Cote.G5::L+XC13 < pu$ ic #tatic *oid Gain01 ; Vind f ute 9 ne. Vind013 'une0f ute13 // Opca#ting < < ///:8 The +eth*d .usic6+une( ) accept# an Bnstrument re9erence, 3ut al#* anything derived 9r*+ Bnstrument) -n .ain( ), y*u can #ee thi# happening a# a =ind re9erence i# pa##ed t* +une( ), !ith n* ca#t nece##ary) Thi# i# accepta3leQ the inter9ace in Bnstrument +u#t e;i#t in =ind, 3ecau#e =ind i# inherited 9r*+ Bnstrument) Upca#ting 9r*+ =ind t* Bnstrument +ay Inarr*!J that inter9ace, 3ut it cann*t +ake it anything le## than the 9ull inter9ace t* Bnstrument)
Cha"ter #* /ol4mor"hism
3(1
every type *9 Bnstrument in y*ur #y#te+) Supp*#e !e 9*ll*! thi# rea#*ning and add #tringed and Brass in#tru+ent#1 //:c0F:Gu#ic2.c# // O*er oading in#tead of upca#ting. c a## Cote ; pri*ate int *a ue3 pri*ate Cote0int *a 1 ; *a ue 9 *a 3 < pu$ ic #tatic readon y Cote G5::L+XC 9 ne. Cote0012 CXSU)R- 9 ne. Cote0"12 BXHL)' 9 ne. Cote0213 < // +tc. c a## 5n#tru!ent ; interna *irtua *oid - ay0Cote n1 ; Sy#te!.Con#o e.VriteLine0&5n#tru!ent.- ay01&13 < < c a## Vind : 5n#tru!ent ; interna o*erride *oid - ay0Cote n1 ; Sy#te!.Con#o e.VriteLine0&Vind.- ay01&13 < < c a## Stringed : 5n#tru!ent ; interna o*erride *oid - ay0Cote n1 ; Sy#te!.Con#o e.VriteLine0&Stringed.- ay01&13 < < c a## Bra## : 5n#tru!ent ; interna o*erride *oid - ay0Cote n1 ; Sy#te!.Con#o e.VriteLine0&Bra##.- ay01&13 < < pu$ ic c a## Gu#ic2 ; interna #tatic *oid 'une0Vind i1 ;
3()
Thinking in C
www.ThinkingIn.!et
i.- ay0Cote.G5::L+XC13 < interna #tatic *oid 'une0Stringed i1 ; i.- ay0Cote.G5::L+XC13 < interna #tatic *oid 'une0Bra## i1 ; i.- ay0Cote.G5::L+XC13 < pu$ ic #tatic *oid Gain01 ; Vind f ute 9 ne. Vind013 Stringed *io in 9 ne. Stringed013 Bra## frenchUorn 9 ne. Bra##013 'une0f ute13 // Co upca#ting 'une0*io in13 'une0frenchUorn13 < < ///:8 Thi# !*rk#, 3ut there# a +a4*r dra!3ack1 :*u +u#t !rite typeE#peci9ic +eth*d# 9*r each ne! Bnstrument cla## y*u add) Thi# +ean# +*re pr*gra++ing in the 9ir#t place, 3ut it al#* +ean# that i9 y*u !ant t* add a ne! +eth*d like +une( ) *r a ne! type *9 Bnstrument, y*uve g*t a l*t *9 !*rk t* d*) =dd the 9act that the c*+piler !*nt give y*u any err*r +e##age# i9 y*u 9*rget t* *verl*ad *ne *9 y*ur +eth*d# and the !h*le pr*ce## *9 !*rking !ith type# 3ec*+e# un+anagea3le) ,*uldnt it 3e +uch nicer i9 y*u c*uld 4u#t !rite a #ingle +eth*d that take# the 3a#e cla## a# it# argu+ent, and n*t any *9 the #peci9ic derived cla##e#F That i#, !*uldnt it 3e nice i9 y*u c*uld 9*rget that there are derived cla##e#, and !rite y*ur c*de t* talk *nly t* the 3a#e cla##F That# e;actly !hat p*ly+*rphi#+ all*!# y*u t* d*) H*!ever, +*#t pr*gra++er# !h* c*+e 9r*+ a pr*cedural pr*gra++ing 3ackgr*und have a 3it *9 tr*u3le !ith the !ay p*ly+*rphi#+ !*rk#)
-he twist
The di99iculty !ith .usic)cs can 3e #een 3y running the pr*gra+) The *utput i# =ind6!lay( )) Thi# i# clearly the de#ired *utput, 3ut it d*e#nt
Cha"ter #* /ol4mor"hism
3(3
#ee+ t* +ake #en#e that it !*uld !*rk that !ay) L**k at the +une( ) +eth*d1 pu$ ic #tatic *oid tune05n#tru!ent i1 ; // ... i.- ay0Cote.G5::L+XC13 < -t receive# an Bnstrument re9erence) S* h*! can the c*+piler p*##i3ly kn*! that thi# Bnstrument re9erence p*int# t* a =ind in thi# ca#e and n*t a Brass *r #tringedF The c*+piler cant) T* get a deeper under#tanding *9 the i##ue, it# help9ul t* e;a+ine the #u34ect *9 2inding)
@ethod;call +inding
C*nnecting a +eth*d call t* a +eth*d 3*dy i# called 2inding) ,hen 3inding i# per9*r+ed 3e9*re the pr*gra+ i# run G3y the c*+piler and linker, i9 there i# *neH, it# called earl4 2inding) :*u +ight n*t have heard the ter+ 3e9*re 3ecau#e it ha# never 3een an *pti*n !ith pr*cedural language#) C c*+piler# have *nly *ne kind *9 +eth*d call, and that# early 3inding) The c*n9u#ing part *9 the a3*ve pr*gra+ rev*lve# ar*und early 3inding 3ecau#e the c*+piler cann*t kn*! the c*rrect +eth*d t* call !hen it ha# *nly an Bnstrument re9erence) The #*luti*n i# called late 2inding, !hich +ean# that the 3inding *ccur# at runEti+e 3a#ed *n the type *9 *34ect) Late 3inding i# al#* called d4namic 2inding *r run9time 2inding) ,hen a language i+ple+ent# late 3inding, there +u#t 3e #*+e +echani#+ t* deter+ine the type *9 the *34ect at runEti+e and t* call the appr*priate +eth*d) That i#, the c*+piler #till d*e#nt kn*! the *34ect type, 3ut the +eth*dEcall +echani#+ 9ind# *ut and call# the c*rrect +eth*d 3*dy) The lateE3inding +echani#+ varie# 9r*+ language t* language, 3ut y*u can i+agine that #*+e #*rt *9 type in9*r+ati*n +u#t 3e in#talled in the *34ect#) O3vi*u#ly, #ince there# additi*nal 3ehavi*r at runti+e, late 3inding i# a little +*re ti+eEc*n#u+ing than early 3inding) A*re i+p*rtantly, i9 a +eth*d i# early 3*und and #*+e *ther c*nditi*n# are +et, an *pti+i7ing c*+piler +ay decide n*t t* +ake a call at all, 3ut in#tead t* place a c*py
3(4
Thinking in C
www.ThinkingIn.!et
*9 the +eth*d# #*urce c*de directly int* the #*urce c*de !here the call *ccur#) Such inlining +ay cau#e the re#ulting 3inary c*de t* 3e a little larger, 3ut can re#ult in #igni9icant per9*r+ance increa#e# in tight l**p#, e#pecially !hen the called +eth*d i# #+all) =dditi*nally, the c*ntent# *9 an earlyE3*und +eth*d can 3e analy7ed and additi*nal *pti+i7ati*n# that can never 3e #a9ely applied t* lateE3*und +eth*d# G#uch a# aggre##ive code motion *pti+i7ati*n#H +ay 3e p*##i3le) T* give y*u an idea, a 2$$0 #tudy0 #h*!ed 5*rtranE6$ running #everal ti+e# a# 9a#t a#, and #*+eti+e# +*re than an *rder *9 +agnitude 9a#ter than, "ava *n a #erie# *9 +athE *riented 3ench+ark# Gthe auth*r# pr*t*type per9*r+anceE*riented "ava c*+piler and li3rarie# gave dra+atic #peedup#H) - p*rted #*+e *9 the 3ench+ark# t* C# and !a# di#app*inted t* #ee re#ult# that !ere very c*+para3le t* "ava per9*r+ance2) =ll +eth*d# declared a# virtual *r override in C# u#e late 3inding, *ther!i#e, they u#e early 3inding Gc*n9ir+H) Thi# i# an irritati*n 3ut n*t a 3ig 3urden) There are t!* #cenari*#1 either y*u kn*! that y*ure g*ing t* *verride a +eth*d later *n, in !hich ca#e it# n* 3ig deal t* add the key!*rd, *r y*u di#c*ver d*!n the r*ad that y*u need t* *verride a +eth*d that y*u hadnt planned *n *verriding, !hich i# a #igni9icant en*ugh de#ign change t* 4u#ti9y a reEe;a+inati*n and rec*+pilati*n *9 the 3a#e cla## c*deK The *ne thing y*u cant d* i# change the 3inding 9r*+ earlyE3*und t* lateE3*und in a c*+p*nent 9*r !hich y*u cant per9*r+ a rec*+pile 3ecau#e y*u d*nt have the #*urce c*de)
Cha"ter #* /ol4mor"hism
3(5
The #hape e;a+ple ha# a 3a#e cla## called #hape and vari*u# derived type#1 Circle, #%uare, +riangle, etc) The rea#*n the e;a+ple !*rk# #* !ell i# that it# ea#y t* #ay Ia circle i# a type *9 #hapeJ and 3e under#t**d) The inheritance diagra+ #h*!# the relati*n#hip#1
The upca#t c*uld *ccur in a #tate+ent a# #i+ple a#1 Shape # 9 ne. Circ e013
Here, a Circle *34ect i# created and the re#ulting re9erence i# i++ediately a##igned t* a #hape, !hich !*uld #ee+ t* 3e an err*r Ga##igning *ne type t* an*therHQ and yet it# 9ine 3ecau#e a Circle is a #hape 3y inheritance) S* the c*+piler agree# !ith the #tate+ent and d*e#nt i##ue an err*r +e##age) Supp*#e y*u call *ne *9 the 3a#eEcla## +eth*d# Gthat have 3een *verridden in the derived cla##e#H1 #.:ra.013 =gain, y*u +ight e;pect that #hape# $raw( ) i# called 3ecau#e thi# i#, a9ter all, a #hape re9erenceR#* h*! c*uld the c*+piler kn*! t* d* anything el#eF =nd yet the pr*per Circle6$raw( ) i# called 3ecau#e *9 late 3inding Gp*ly+*rphi#+H)
3(6
Thinking in C
www.ThinkingIn.!et
The 9*ll*!ing e;a+ple put# it a #lightly di99erent !ay1 //:c0F:Shape#.c# // -o y!orphi#! in C( u#ing Sy#te!3 pu$ ic c a## Shape ; interna *irtua *oid :ra.01 ;< interna *irtua *oid +ra#e01 ;< < c a## Circ e : Shape ; interna o*erride *oid :ra.01 ; Sy#te!.Con#o e.VriteLine0&Circ e.:ra.01&13 < interna o*erride *oid +ra#e01 ; Sy#te!.Con#o e.VriteLine0&Circ e.+ra#e01&13 < < c a## S7uare : Shape ; interna o*erride *oid :ra.01 ; Sy#te!.Con#o e.VriteLine0&S7uare.:ra.01&13 < interna o*erride *oid +ra#e01 ; Sy#te!.Con#o e.VriteLine0&S7uare.+ra#e01&13 < < c a## 'riang e : Shape ; interna o*erride *oid :ra.01 ; Sy#te!.Con#o e.VriteLine0&'riang e.:ra.01&13 < interna o*erride *oid +ra#e01 ; Sy#te!.Con#o e.VriteLine0&'riang e.+ra#e01&13 < < pu$ ic c a## Shape# ; #tatic Rando! rand 9 ne. Rando!013
Cha"ter #* /ol4mor"hism
3(#
pu$ ic #tatic Shape RandShape01 ; #.itch0rand.Cext0T11 ; ca#e 0: return ne. Circ e013 ca#e ": return ne. S7uare013 ca#e 2: return ne. 'riang e013 defau t: return nu 3 < < pu$ ic #tatic *oid Gain01 ; ShapeJK # 9 ne. ShapeJ>K3 // Hi up the array .ith #hape#: for0int i 9 03 i W #.Length3iRR1 #JiK 9 RandShape013 // Ga%e po y!orphic !ethod ca #: foreach0Shape aShape in #1 aShape.:ra.013 < < ///:8 The 3a#e cla## #hape e#ta3li#he# the c*++*n inter9ace t* anything inherited 9r*+ #hapeRthat i#, all #hape# can 3e dra!n and era#ed) The derived cla##e# *verride the#e de9initi*n# t* pr*vide uniDue 3ehavi*r 9*r each #peci9ic type *9 #hape) The +ain cla## #hapes c*ntain# a static +eth*d *and#hape( ) that pr*duce# a re9erence t* a rand*+lyE#elected #hape *34ect each ti+e y*u call it) *te that the upca#ting happen# in the return #tate+ent#, each *9 !hich take# a re9erence t* a Circle, #%uare, *r +riangle and #end# it *ut *9 the +eth*d a# the return type, #hape) S* !henever y*u call thi# +eth*d y*u never get a chance t* #ee !hat #peci9ic type it i#, #ince y*u al!ay# get 3ack a plain #hape re9erence) .ain( ) c*ntain# an array *9 #hape re9erence# 9illed thr*ugh call# t* *and#hape( )) =t thi# p*int y*u kn*! y*u have #hape#, 3ut y*u d*nt kn*! anything +*re #peci9ic than that Gand neither d*e# the c*+pilerH) H*!ever, !hen y*u #tep thr*ugh thi# array and call $raw( ) 9*r each *ne, the c*rrect typeE#peci9ic 3ehavi*r +agically *ccur#, a# y*u can #ee 9r*+ *ne *utput e;a+ple1 Circ e.:ra.01 'riang e.:ra.01 Circ e.:ra.01
3(&
Thinking in C
www.ThinkingIn.!et
Circ e.:ra.01 Circ e.:ra.01 S7uare.:ra.01 'riang e.:ra.01 S7uare.:ra.01 S7uare.:ra.01 O9 c*ur#e, #ince the #hape# are all ch*#en rand*+ly each ti+e, y*ur run# !ill have di99erent re#ult#) The p*int *9 ch**#ing the #hape# rand*+ly i# t* drive h*+e the under#tanding that the c*+piler can have n* #pecial kn*!ledge that all*!# it t* +ake the c*rrect call# at c*+pileEti+e) =ll the call# t* $raw( ) are +ade thr*ugh dyna+ic 3inding)
%&tensi+ilit5
*! let# return t* the +u#ical in#tru+ent e;a+ple) Becau#e *9 p*ly+*rphi#+, y*u can add a# +any ne! type# a# y*u !ant t* the #y#te+ !ith*ut changing the +une( ) +eth*d) -n a !ellEde#igned OOP pr*gra+, +*#t *r all *9 y*ur +eth*d# !ill 9*ll*! the +*del *9 +une( ) and c*++unicate *nly !ith the 3a#eEcla## inter9ace) Such a pr*gra+ i# e%tensi2le 3ecau#e y*u can add ne! 9uncti*nality 3y inheriting ne! data type# 9r*+ the c*++*n 3a#e cla##) The +eth*d# that +anipulate the 3a#eEcla## inter9ace !ill n*t need t* 3e changed at all t* acc*++*date the ne! cla##e#) C*n#ider !hat happen# i9 y*u take the in#tru+ent e;a+ple and add +*re +eth*d# in the 3a#e cla## and a nu+3er *9 ne! cla##e#) Here# the diagra+1
Cha"ter #* /ol4mor"hism
3('
=ll the#e ne! cla##e# !*rk c*rrectly !ith the *ld, unchanged +une( ) +eth*d) Even i9 +une( ) i# in a #eparate 9ile and ne! +eth*d# are added t* the inter9ace *9 Bnstrument, +une( ) !*rk# c*rrectly !ith*ut rec*+pilati*n) Here i# the i+ple+entati*n *9 the a3*ve diagra+1 //:c0F:Gu#icT.c# // )n exten#i$ e progra!. c a## 5n#tru!ent ; pu$ ic *irtua *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&5n#tru!ent.- ay01&13 < pu$ ic *irtua #tring Vhat01 ; return &5n#tru!ent&3 <
31(
Thinking in C
www.ThinkingIn.!et
c a## Vind : 5n#tru!ent ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Vind.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &Vind&3 < pu$ ic o*erride *oid )dDu#t01 ;< < c a## -ercu##ion : 5n#tru!ent ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&-ercu##ion.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &-ercu##ion&3 < pu$ ic o*erride *oid )dDu#t01 ;< < c a## Stringed : 5n#tru!ent ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&#tringed.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &#tringed&3 < pu$ ic o*erride *oid )dDu#t01 ;< < c a## Bra## : Vind ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Bra##.- ay01&13 < pu$ ic o*erride *oid )dDu#t01 ; Sy#te!.Con#o e.VriteLine0&Bra##.)dDu#t01&13 < < c a## Vood.ind : Vind ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Vood.ind.- ay01&13 <
Cha"ter #* /ol4mor"hism
311
pu$ ic o*erride #tring Vhat01 ; return &Vood.ind&3 < < pu$ ic c a## Gu#icT ; // :oe#n't care a$out type2 #o ne. type# // added to the #y#te! #ti .or% right: #tatic *oid 'une05n#tru!ent i1 ; // ... i.- ay013 < #tatic *oid 'une) 05n#tru!entJK e1 ; foreach05n#tru!ent i in e1 'une0i13 < pu$ ic #tatic *oid Gain01 ; 5n#tru!entJK orche#tra 9 ne. 5n#tru!entJPK3 int i 9 03 // Opca#ting during addition to the array: orche#traJiRRK 9 ne. Vind013 orche#traJiRRK 9 ne. -ercu##ion013 orche#traJiRRK 9 ne. Stringed013 orche#traJiRRK 9 ne. Bra##013 orche#traJiRRK 9 ne. Vood.ind013 'une) 0orche#tra13 < < ///:8 The ne! +eth*d# are =hat( ), !hich return# a #tring re9erence !ith a de#cripti*n *9 the cla##, and 'd)ust( ), !hich pr*vide# #*+e !ay t* ad4u#t each in#tru+ent) -n .ain( ), !hen y*u place #*+ething in#ide the Bnstrument array y*u aut*+atically upca#t t* Bnstrument) :*u can #ee that the +une( ) +eth*d i# 3li##9ully ign*rant *9 all the c*de change# that have happened ar*und it, and yet it !*rk# c*rrectly) Thi# i# e;actly !hat p*ly+*rphi#+ i# #upp*#ed t* pr*vide) :*ur c*de change# d*nt cau#e da+age t* part# *9 the pr*gra+ that #h*uld n*t 3e a99ected) Put an*ther !ay, p*ly+*rphi#+ i# *ne *9 the +*#t i+p*rtant techniDue# that all*! the pr*gra++er t* I#eparate the thing# that change 9r*+ the thing# that #tay the #a+e)J
31)
Thinking in C
www.ThinkingIn.!et
Cha"ter #* /ol4mor"hism
313
There# an*ther c*n9u#ing a#pect thr*!n in here) -n Bnstrument?, the !lay( ) +eth*d take# an int that ha# the identi9ier ,ote?) That i#, even th*ugh ,ote? i# a cla## na+e, it can al#* 3e u#ed a# an identi9ier !ith*ut c*+plaint) But in =ind?, !lay( ) take# a ,ote? re9erence that ha# an identi9ier n6 G=lth*ugh y*u c*uld even #ay !lay(,ote? ,ote?) !ith*ut an err*r)H Thu# it appear# that the pr*gra++er intended t* *verride !lay( ) 3ut +i#typed the +eth*d a 3it) The c*+piler, h*!ever, a##u+ed that an *verl*ad and n*t an *verride !a# intended) *te that i9 y*u 9*ll*! the #tandard C# na+ing c*nventi*n, the argu+ent identi9ier !*uld 3e note? Gl*!erca#e TnH, !hich !*uld di#tingui#h it 9r*+ the cla## na+e) -n +une, the Bnstrument? i i# #ent the !lay( ) +e##age, !ith *ne *9 ,ote?# +e+3er# G.B$$L&ACH a# an argu+ent) Since ,ote? c*ntain# int de9initi*n#, thi# +ean# that the int ver#i*n *9 the n*!E*verl*aded !lay( ) +eth*d i# called, and #ince that ha# not 3een *verridden the 3a#eE cla## ver#i*n i# u#ed) The *utput i#1 5n#tru!ent,.- ay01 Thi# certainly d*e#nt appear t* 3e a p*ly+*rphic +eth*d call) Once y*u under#tand !hat# happening, y*u can 9i; the pr*3le+ 9airly ea#ily, 3ut i+agine h*! di99icult it +ight 3e t* 9ind the 3ug i9 it# 3uried in a pr*gra+ *9 #igni9icant #i7e)
314
Thinking in C
www.ThinkingIn.!et
The *nly rea#*n t* e#ta3li#h thi# c*++*n inter9ace i# #* it can 3e e;pre##ed di99erently 9*r each di99erent #u3type) -t e#ta3li#he# a 3a#ic 9*r+, #* y*u can #ay !hat# in c*++*n !ith all the derived cla##e#) =n*ther !ay *9 #aying thi# i# t* call Bnstrument an a2stract 2ase class G*r #i+ply an a2stract classH) :*u create an a3#tract cla## !hen y*u !ant t* +anipulate a #et *9 cla##e# thr*ugh thi# c*++*n inter9ace) =ll derivedE cla## +eth*d# that +atch the #ignature *9 the 3a#eEcla## declarati*n !ill 3e called u#ing the dyna+ic 3inding +echani#+) GH*!ever, a# #een in the la#t #ecti*n, i9 the +eth*d# na+e i# the #a+e a# the 3a#e cla## 3ut the argu+ent# are di99erent, y*uve g*t *verl*ading, !hich pr*3a3ly i#nt !hat y*u !ant)H -9 y*u have an a3#tract cla## like Bnstrument, *34ect# *9 that cla## al+*#t al!ay# have n* +eaning) That i#, Bnstrument i# +eant t* e;pre## *nly the inter9ace, and n*t a particular i+ple+entati*n, #* creating an Bnstrument *34ect +ake# n* #en#e, and y*ull pr*3a3ly !ant t* prevent the u#er 9r*+ d*ing it) Thi# can 3e acc*+pli#hed 3y +aking all the +eth*d# in Bnstrument print err*r +e##age#, 3ut that delay# the in9*r+ati*n until runEti+e and reDuire# relia3le e;hau#tive te#ting *n the u#er# part) -t# al!ay# 3etter t* catch pr*3le+# at c*+pileEti+e) C# pr*vide# a +echani#+ 9*r d*ing thi# called the a2stract method/) Thi# i# a +eth*d that i# inc*+pleteQ it ha# *nly a declarati*n and n* +eth*d 3*dy) Here i# the #ynta; 9*r an a3#tract +eth*d declarati*n1 a$#tract *oid H013 = cla## c*ntaining a3#tract +eth*d# i# called an a2stract class) -9 a cla## c*ntain# *ne *r +*re a3#tract +eth*d#, the cla## +u#t 3e Duali9ied a# abstract) GOther!i#e, the c*+piler give# y*u an err*r +e##age)H There# n* need t* Duali9y abstract +eth*d# a# virtual, a# they are al!ay# re#*lved !ith late 3inding) -9 an a3#tract cla## i# inc*+plete, !hat i# the c*+piler #upp*#ed t* d* !hen #*+e*ne trie# t* in#tantiate an *34ect *9 that cla##F -t cann*t #a9ely create an *34ect *9 an a3#tract cla##, #* y*u get an err*r +e##age 9r*+ the c*+piler) Thi# !ay the c*+piler en#ure# the purity *9 the a3#tract cla##, and y*u d*nt need t* !*rry a3*ut +i#u#ing it)
/ 5*r C@@ pr*gra++er#, thi# i# the anal*gue *9 C@@# "ure -irtual $unction)
Cha"ter #* /ol4mor"hism
315
-9 y*u inherit 9r*+ an a3#tract cla## and y*u !ant t* +ake *34ect# *9 the ne! type, y*u +u#t pr*vide +eth*d de9initi*n# 9*r all the a3#tract +eth*d# in the 3a#e cla##) -9 y*u d*nt Gand y*u +ay ch**#e n*t t*H, then the derived cla## i# al#* a3#tract and the c*+piler !ill 9*rce y*u t* Duali9y that cla## !ith the abstract key!*rd) -t# p*##i3le t* create a cla## a# abstract !ith*ut including any abstract +eth*d#) Thi# i# u#e9ul !hen y*uve g*t a cla## in !hich it d*e#nt +ake #en#e t* have any abstract +eth*d#, and yet y*u !ant t* prevent any in#tance# *9 that cla##) The Bnstrument cla## can ea#ily 3e turned int* an abstract cla##) Only #*+e *9 the +eth*d# !ill 3e abstract, #ince +aking a cla## a3#tract d*e#nt 9*rce y*u t* +ake all the +eth*d# abstract) Here# !hat it l**k# like1
316
Thinking in C
www.ThinkingIn.!et
a+stract Instru#ent a+stract void Pla512L 'tring What12 M ?N ... N? O a+stract void )d/ust12L
Here# the *rche#tra e;a+ple +*di9ied t* u#e abstract cla##e# and +eth*d#1 //:c0F:Gu#icE.c# // )n exten#i$ e progra!. a$#tract c a## 5n#tru!ent ; pu$ ic a$#tract *oid - ay013 pu$ ic *irtua #tring Vhat01 ; return &5n#tru!ent&3 < pu$ ic a$#tract *oid )dDu#t013
Cha"ter #* /ol4mor"hism
31#
< c a## Vind : 5n#tru!ent ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Vind.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &Vind&3 < pu$ ic o*erride *oid )dDu#t01 ;< < c a## -ercu##ion : 5n#tru!ent ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&-ercu##ion.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &-ercu##ion&3 < pu$ ic o*erride *oid )dDu#t01 ;< < c a## Stringed : 5n#tru!ent ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&#tringed.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &#tringed&3 < pu$ ic o*erride *oid )dDu#t01 ;< < c a## Bra## : Vind ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Bra##.- ay01&13 < pu$ ic o*erride *oid )dDu#t01 ; Sy#te!.Con#o e.VriteLine0&Bra##.)dDu#t01&13 <
31&
Thinking in C
www.ThinkingIn.!et
< c a## Vood.ind : Vind ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Vood.ind.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &Vood.ind&3 < < pu$ ic c a## Gu#icT ; // :oe#n't care a$out type2 #o ne. type# // added to the #y#te! #ti .or% right: #tatic *oid 'une05n#tru!ent i1 ; // ... i.- ay013 < #tatic *oid 'une) 05n#tru!entJK e1 ; foreach05n#tru!ent i in e1 'une0i13 < pu$ ic #tatic *oid Gain01 ; 5n#tru!entJK orche#tra 9 ne. 5n#tru!entJPK3 int i 9 03 // Opca#ting during addition to the array: orche#traJiRRK 9 ne. Vind013 orche#traJiRRK 9 ne. -ercu##ion013 orche#traJiRRK 9 ne. Stringed013 orche#traJiRRK 9 ne. Bra##013 orche#traJiRRK 9 ne. Vood.ind013 'une) 0orche#tra13 < < ///:8 :*u can #ee that there# really n* change e;cept in the 3a#e cla##)
Cha"ter #* /ol4mor"hism
31'
-t# help9ul t* create abstract cla##e# and +eth*d# 3ecau#e they +ake the a3#tractne## *9 a cla## e;plicit, and tell 3*th the u#er and the c*+piler h*! it !a# intended t* 3e u#ed)
3)(
Thinking in C
www.ThinkingIn.!et
#.
pu$ ic c a## Gea ; interna Gea 01 ; Sy#te!.Con#o e.VriteLine0&Gea 01&13 < < pu$ ic c a## Bread ; interna Bread01 ; Sy#te!.Con#o e.VriteLine0&Bread01&13 < < pu$ ic c a## Chee#e ; interna Chee#e01 ; Sy#te!.Con#o e.VriteLine0&Chee#e01&13 < < pu$ ic c a## Lettuce ; interna Lettuce01 ; Sy#te!.Con#o e.VriteLine0&Lettuce01&13 < < pu$ ic c a## Lunch : Gea ; interna Lunch01 ; Sy#te!.Con#o e.VriteLine0&Lunch01&13< < pu$ ic c a## -orta$ eLunch : Lunch ; interna -orta$ eLunch01 ; Sy#te!.Con#o e.VriteLine0&-orta$ eLunch01&13 < < pu$ ic c a## Sand.ich : -orta$ eLunch ; Bread $ 9 ne. Bread013 Chee#e c 9 ne. Chee#e013 Lettuce 9 ne. Lettuce013 interna Sand.ich01 ; Sy#te!.Con#o e.VriteLine0&Sand.ich01&13 <
Cha"ter #* /ol4mor"hism
3)1
pu$ ic #tatic *oid Gain01 ; ne. Sand.ich013 < < ///:8 Thi# e;a+ple create# a c*+ple; cla## *ut *9 *ther cla##e#, and each cla## ha# a c*n#truct*r that ann*unce# it#el9) The i+p*rtant cla## i# #andwich, !hich re9lect# three level# *9 inheritance G9*ur, i9 y*u c*unt the i+plicit inheritance 9r*+ ob)ectH and three +e+3er *34ect#) ,hen a #andwich *34ect i# created in .ain( ), the *utput i#1 Bread01 Chee#e01 Lettuce01 Gea 01 Lunch01 -orta$ eLunch01 Sand.ich01 Thi# +ean# that the *rder *9 c*n#truct*r call# 9*r a c*+ple; *34ect i# a# 9*ll*!#1 &) Ae+3er initiali7er# are called in the *rder *9 declarati*n ') The 3a#eEcla## c*n#truct*r i# called) Thi# #tep i# repeated recur#ively #uch that the r**t *9 the hierarchy i# c*n#tructed 9ir#t, 9*ll*!ed 3y the ne;tEderived cla##, etc), until the +*#tEderived cla## i# reached) .) The 3*dy *9 the derivedEcla## c*n#truct*r i# called) The *rder *9 the c*n#truct*r call# i# i+p*rtant) ,hen y*u inherit, y*u kn*! all a3*ut the 3a#e cla## and can acce## any public, protected, *r internal +e+3er# *9 the 3a#e cla##) Thi# +ean# that y*u +u#t 3e a3le t* a##u+e that all the +e+3er# *9 the 3a#e cla## are valid !hen y*ure in the derived cla##) -n a n*r+al +eth*d, c*n#tructi*n ha# already taken place, #* all the +e+3er# *9 all part# *9 the *34ect have 3een 3uilt) -n#ide the c*n#truct*r, h*!ever, y*u +u#t 3e a3le t* a##u+e that all +e+3er# that y*u u#e have 3een 3uilt) The *nly !ay t* guarantee thi# i# 9*r the 3a#eE cla## c*n#truct*r t* 3e called 9ir#t) Then !hen y*ure in the derivedEcla## c*n#truct*r, all the +e+3er# y*u can acce## in the 3a#e cla## have 3een initiali7ed) INn*!ing that all +e+3er# are validJ in#ide the c*n#truct*r i# al#* the rea#*n that, !henever p*##i3le, y*u #h*uld initiali7e all +e+3er *34ect# Gthat i#, *34ect# placed in the cla## u#ing c*+p*#iti*nH at their
3))
Thinking in C
www.ThinkingIn.!et
p*int *9 de9initi*n in the cla## Ge)g), b, c, and l in the e;a+ple a3*veH) -9 y*u 9*ll*! thi# practice, y*u !ill help en#ure that all 3a#e cla## +e+3er# and +e+3er *34ect# *9 the current *34ect have 3een initiali7ed) Un9*rtunately, thi# d*e#nt handle every ca#e, a# y*u !ill #ee in the ne;t #ecti*n)
Cha"ter #* /ol4mor"hism
3)3
protected a$#tract *oid :ra.013 interna _ yph01 ; Sy#te!.Con#o e.VriteLine0&_ yph01 $efore dra.01&13 :ra.013 Sy#te!.Con#o e.VriteLine0&_ yph01 after dra.01&13 < < c a## Round_ yph : _ yph ; int radiu# 9 "3 int thic%ne##3 interna Round_ yph0int r1 ; radiu# 9 r3 thic%ne## 9 23 Sy#te!.Con#o e.VriteLine0 &Round_ yph.Round_ yph012 radiu# 9 ;0< thic%ne## 9 ;"<&2 radiu#2 thic%ne##13 < protected o*erride *oid :ra.01 ; Sy#te!.Con#o e.VriteLine0 &Round_ yph.:ra.012 radiu# 9 ;0< thic%ne## 9 ;"<&2 radiu#2 thic%ne##13 < < pu$ ic c a## -o yCon#tructor# ; pu$ ic #tatic *oid Gain01 ; ne. Round_ yph0P13 < < ///:8 -n lyph, the $raw( ) +eth*d i# abstract, #* it i# de#igned t* 3e *verridden) -ndeed, y*u are 9*rced t* *verride it in *ound lyph) But
3)4
Thinking in C
www.ThinkingIn.!et
the lyph c*n#truct*r call# thi# +eth*d, and the call end# up in *ound lyph6$raw( ), !hich !*uld #ee+ t* 3e the intent) But l**k at the *utput1 _ yph01 $efore dra.01 Round_ yph.:ra.012 radiu# 9 " thic%ne## 9 0 _ yph01 after dra.01 Round_ yph.Round_ yph012 radiu# 9 P thic%ne## 9 2 ,hen lyph# c*n#truct*r call# $raw( ), the value *9 radius are #et t* their de9ault value#, n*t their p*#tEc*n#tructi*n intended value#) = g**d guideline 9*r c*n#truct*r# i#, I-9 p*##i3le, initiali7e +e+3er varia3le# directly) ?* a# little a# p*##i3le in a c*n#truct*r t* #et the *34ect int* a g**d #tate, and i9 y*u can p*##i3ly av*id it, d*nt call any +eth*d#)J The *nly #a9e +eth*d# t* call in#ide a c*n#truct*r are n*nEvirtual)
Cha"ter #* /ol4mor"hism
3)5
c a## Uappy)ctor : )ctor ; pu$ ic o*erride *oid )ct01 ; Sy#te!.Con#o e.VriteLine0&Uappy)ctor&13 < < c a## Sad)ctor : )ctor ; pu$ ic o*erride *oid )ct01 ; Sy#te!.Con#o e.VriteLine0&Sad)ctor&13 < < c a## Stage ; )ctor a 9 ne. Uappy)ctor013 interna *oid Change01 ; a 9 ne. Sad)ctor013 < interna *oid _o01 ; a.)ct013 < < pu$ ic c a## 'ran#!ogrify ; pu$ ic #tatic *oid Gain01 ; Stage # 9 ne. Stage013 #._o013 // -rint# &Uappy)ctor& #.Change013 #._o013 // -rint# &Sad)ctor& < < ///:8 = #tage *34ect c*ntain# a re9erence t* an 'ctor, !hich i# initiali7ed t* a "appy'ctor *34ect) Thi# +ean# o( ) pr*duce# a particular 3ehavi*r) But #ince a re9erence can 3e re3*und t* a di99erent *34ect at runEti+e, a re9erence 9*r a #ad'ctor *34ect can 3e #u3#tituted in a and then the 3ehavi*r pr*duced 3y o( ) change#) Thu# y*u gain dyna+ic 9le;i3ility at runEti+e) GThi# i# al#* called the @tate /attern. See Thinking in /atterns, d*!nl*ada3le at www.BruceEckel.com.H -n c*ntra#t, y*u cant decide t* inherit di99erently at runEti+eQ that +u#t 3e c*+pletely deter+ined at c*+pileEti+e) = general guideline i# IU#e inheritance t* e;pre## di99erence# in 3ehavi*r, and 9ield# t* e;pre## variati*n# in #tate)J -n the a3*ve e;a+ple, 3*th are u#ed1 t!* di99erent cla##e# are inherited t* e;pre## the di99erence in the
3)6
Thinking in C
www.ThinkingIn.!et
'ct( ) +eth*d, and #tage u#e# c*+p*#iti*n t* all*! it# #tate t* 3e changed) -n thi# ca#e, that change in #tate happen# t* pr*duce a change in 3ehavi*r)
C ir c le d ra w 12 e ra se 12
S q u a re d ra w 12 e ra se 12
T r ia n g le d ra w 12 e ra se 12
Thi# can 3e ter+ed a pure Ii#EaJ relati*n#hip 3ecau#e the inter9ace *9 a cla## e#ta3li#he# !hat it i#) -nheritance guarantee# that any derived cla## !ill have the inter9ace *9 the 3a#e cla## and n*thing le##) -9 y*u 9*ll*! the a3*ve diagra+, derived cla##e# !ill al#* have no more than the 3a#e cla## inter9ace) Thi# can 3e th*ught *9 a# "ure su2stitution, 3ecau#e derived cla## *34ect# can 3e per9ectly #u3#tituted 9*r the 3a#e cla##, and y*u never need t* kn*! any e;tra in9*r+ati*n a3*ut the #u3cla##e# !hen y*ure u#ing the+1
- a l* s t o ' h a $ e =Is;a = r e la t io n s h i$
@ essage
C ir c le . ' q u a r e . L in e . o r n e w t 5 $ e o0 'ha$e
Cha"ter #* /ol4mor"hism
3)#
That i#, the 3a#e cla## can receive any +e##age y*u can #end t* the derived cla## 3ecau#e the t!* have e;actly the #a+e inter9ace) =ll y*u need t* d* i# upca#t 9r*+ the derived cla## and never l**k 3ack t* #ee !hat e;act type *9 *34ect y*ure dealing !ith) Everything i# handled thr*ugh p*ly+*rphi#+) ,hen y*u #ee it thi# !ay, it #ee+# like a pure Ii#EaJ relati*n#hip i# the *nly #en#i3le !ay t* d* thing#, and any *ther de#ign indicate# +uddled thinking and i# 3y de9initi*n 3r*ken) Thi# t** i# a trap) =# #**n a# y*u #tart thinking thi# !ay, y*ull turn ar*und and di#c*ver that e;tending the inter9ace i# the per9ect #*luti*n t* a particular pr*3le+) Thi# c*uld 3e ter+ed an Ii#ElikeEaJ relati*n#hip 3ecau#e the derived cla## i# like the 3a#e cla##Rit ha# the #a+e 9unda+ental inter9aceR3ut it ha# *ther 9eature# that reDuire additi*nal +eth*d# t* i+ple+ent1
> s e 0u l v o id 0 1 2 v o id g 1 2
) s s u # e t h is r e $ r e s e n t s a + ig in t e r 0 a c e
@ o re > s e 0u l vo vo vo vo vo id id id id id 01 2 g 12 u 12 v12 w 12
= I s ; li* e ; a =
% & t e n d in g t h e in t e r 0 a c e
,hile thi# i# al#* a u#e9ul and #en#i3le appr*ach Gdepending *n the #ituati*nH it ha# a dra!3ack) The e;tended part *9 the inter9ace in the derived cla## i# n*t availa3le 9r*+ the 3a#e cla##, #* *nce y*u upca#t y*u cant call the ne! +eth*d#1
3)&
Thinking in C
www.ThinkingIn.!et
- a l* s t o > s e 0u l o + /e c t
@ essage
> s e 0u l $ a rt @ o re > s e 0u l $ a rt
-9 y*ure n*t upca#ting in thi# ca#e, it !*nt 3*ther y*u, 3ut *9ten y*ull get int* a #ituati*n in !hich y*u need t* redi#c*ver the e;act type *9 the *34ect #* y*u can acce## the e;tended +eth*d# *9 that type) The 9*ll*!ing #ecti*n #h*!# h*! thi# i# d*ne)
) s s u # e t h is r e $ r e s e n t s a + ig in t e r 0a c e
@ o re > s e 0u l vo vo vo vo vo id id id id id 01 2 g 12 u 12 v12 w 12
= I s ; li* e ; a =
% & t e n d in g t h e in t e r 0 a c e
Cha"ter #* /ol4mor"hism
3)'
T* #*lve thi# pr*3le+ there +u#t 3e #*+e !ay t* guarantee that a d*!nca#t i# c*rrect, #* y*u !*nt accidentally ca#t t* the !r*ng type and then #end a +e##age that the *34ect cant accept) Thi# !*uld 3e Duite un#a9e) -n #*+e language# Glike C@@H y*u +u#t per9*r+ a #pecial *perati*n in *rder t* get a typeE#a9e d*!nca#t, 3ut in C# e-er4 cast i# checkedK C# #upp*rt# t!* type# *9 d*!nca#t1 a parenthe#i7ed ca#t that l**k# #i+ilar t* the ca#t# in *ther CEderived language#1 GoreO#efu do.nCa#tO$Dect 9 0GoreO#efu 1 !yO#efu Uand e3 and the as key!*rd1 GoreO#efu do.nCa#tO$Dect 9 !yO#efu Uand e a# GoreO#efu 3 =t runEti+e, 3*th the#e ca#t# are checked t* en#ure that the myVseful"andle d*e# in 9act re9er t* an in#tance *9 type .oreVseful6 -9 thi# a 3ad a##u+pti*n, the parenthe#i7e ca#t !ill thr*! an BnvalidCast&xception and the as ca#t !ill a##ign downCast1b)ect the value *9 null) Thi# act *9 checking type# at runEti+e i# called run9time t4"e identi$ication GRTT-H) The 9*ll*!ing e;a+ple de+*n#trate# the 3ehavi*r *9 RTT-1 //:c0F:R''5.CS // :o.nca#ting @ Run6ti!e 'ype // 5dentification 0R''51. c a## O#efu ; pu$ ic *irtua pu$ ic *irtua <
c a## GoreO#efu : O#efu ; pu$ ic o*erride *oid H01 ;< pu$ ic o*erride *oid _01 ;<
33(
Thinking in C
www.ThinkingIn.!et
pu$ ic *oid O01 ;< pu$ ic *oid N01 ;< pu$ ic *oid V01 ;< < pu$ ic c a## R''5 ; pu$ ic #tatic *oid Gain01 ; O#efu JK x 9 ; ne. O#efu 012 ne. GoreO#efu 01 <3 xJ0K.H013 xJ"K._013 // Co!pi e6ti!e: !ethod not found in O#efu : //! xJ"K.O013 00GoreO#efu 1xJ"K1.O013 // -arenthe#iMed do.nca#t 0xJ"K a# GoreO#efu 1.O013 //a# %ey.ord 00GoreO#efu 1xJ0K1.O013 // +xception thro.n < < ///:8 ,hen y*u run thi# pr*gra+, y*u !ill #ee #*+ething !eve n*t yet di#cu##ed, Ci#ual Studi*# "u#tE-nETi+e ?e3ugging dial*gue1
Cha"ter #* /ol4mor"hism
331
Thi# i# certainly +*re !elc*+e than a ?r) ,at#*n du+p *r a Blue Screen *9 ?eath, 3ut !e kn*! the cau#e P !ere trying t* treat x<4> a# a .oreVseful !hen it# *nly a Vseful) Select I *J and the pr*gra+ !ill end !ith a c*+plaint a3*ut an unhandled BnvalidCast&xception) =# in the diagra+, .oreVseful e;tend# the inter9ace *9 Vseful) But #ince it# inherited, it can al#* 3e upca#t t* a Vseful) :*u can #ee thi# happening in the initiali7ati*n *9 the array x in .ain( )) Since 3*th *34ect# in the array are *9 cla## Vseful, y*u can #end the :( ) and ( ) +eth*d# t* 3*th, and i9 y*u try t* call V( ) G!hich e;i#t# *nly in .oreVsefulH y*ull get a c*+pileEti+e err*r +e##age) -9 y*u !ant t* acce## the e;tended inter9ace *9 a .oreVseful *34ect, y*u can try t* d*!nca#t) -9 it# the c*rrect type, it !ill 3e #ucce##9ul) Other!i#e, y*ull get an BnvalidCast&xception)
33)
Thinking in C
www.ThinkingIn.!et
There# +*re t* RTT- than a #i+ple ca#t) The is key!*rd all*!# y*u check the type *9 an *34ect 3e9*re atte+pting a d*!nca#t) //:c0F:R''52.c# // :o.nca#ting @ Run6ti!e 'ype // 5dentification 0R''51. c a## O#efu ; pu$ ic *irtua pu$ ic *irtua < c a## pu$ pu$ pu$ pu$ pu$ < *oid H01 ;< *oid _01 ;<
GoreO#efu : O#efu ; ic o*erride *oid H01 ;< ic o*erride *oid _01 ;< ic *oid O01 ;< ic *oid N01 ;< ic *oid V01 ;<
pu$ ic c a## R''52 ; pu$ ic #tatic *oid Gain01 ; O#efu JK x 9 ; ne. O#efu 012 ne. GoreO#efu 01 <3 xJ0K.H013 xJ"K._013 foreach0O#efu u in x1; if0u i# GoreO#efu 1; 00GoreO#efu 1 u1.O013 < < < < ///:8 Thi# pr*gra+ run# t* c*+pleti*n !ith*ut any e;cepti*n# 3eing thr*!n) Everything #tay# the #a+e e;cept the 9inal iterati*n *ver the x array) The foreach l**p iterate# *ver the array Gall t!* ele+ent# *9 itKH, 3ut !e guard the d*!nca#t !ith a B**lean te#t t* en#ure that !e *nly atte+pt the d*!nca#t *n *34ect# *9 type .oreVseful)
Cha"ter #* /ol4mor"hism
333
'u##ar5
P*ly+*rphi#+ +ean# Idi99erent 9*r+#)J -n *34ectE*riented pr*gra++ing, y*u have the #a+e 9ace Gthe c*++*n inter9ace in the 3a#e cla##H and di99erent 9*r+# u#ing that 9ace1 the di99erent ver#i*n# *9 the dyna+ically 3*und +eth*d#) :*uve #een in thi# chapter that it# i+p*##i3le t* under#tand, *r even create, an e;a+ple *9 p*ly+*rphi#+ !ith*ut u#ing data a3#tracti*n and inheritance) P*ly+*rphi#+ i# a 9eature that cann*t 3e vie!ed in i#*lati*n Glike a switch #tate+ent can, 9*r e;a+pleH, 3ut in#tead !*rk# *nly in c*ncert, a# part *9 a I3ig pictureJ *9 cla## relati*n#hip#) Pe*ple are *9ten c*n9u#ed 3y *ther, n*nE*34ectE*riented 9eature# *9 C#, like +eth*d *verl*ading, !hich are #*+eti+e# pre#ented a# *34ectE*riented) ?*nt 3e 9**led1 -9 it i#nt late 3inding, it i#nt p*ly+*rphi#+) T* u#e p*ly+*rphi#+Rand thu# *34ectE*riented techniDue#Re99ectively in y*ur pr*gra+# y*u +u#t e;pand y*ur vie! *9 pr*gra++ing t* include n*t 4u#t +e+3er# and +e##age# *9 an individual cla##, 3ut al#* the c*++*nality a+*ng cla##e# and their relati*n#hip# !ith each *ther) =lth*ugh thi# reDuire# #igni9icant e99*rt, it# a !*rthy #truggle, 3ecau#e the re#ult# are 9a#ter pr*gra+ devel*p+ent, 3etter c*de *rgani7ati*n, e;ten#i3le pr*gra+#, and ea#ier c*de +aintenance)
%&ercises
334
Thinking in C
www.ThinkingIn.!et
Da, Inter0aces
-nter9ace# pr*vide +*re #*phi#ticated !ay# t* *rgani7e and c*ntr*l the *34ect# in y*ur #y#te+)
C@@, 9*r e;a+ple, d*e# n*t c*ntain #uch +echani#+#, alth*ugh the clever pr*gra++er +ay #i+ulate the+) The 9act that they e;i#t in "ava indicate# that they !ere c*n#idered i+p*rtant en*ugh t* pr*vide direct #upp*rt thr*ugh language key!*rd#) -n Chapter %, y*u learned a3*ut the abstract key!*rd, !hich all*!# y*u t* create *ne *r +*re +eth*d# in a cla## that have n* de9initi*n#Ry*u pr*vide part *9 the inter9ace !ith*ut pr*viding a c*rre#p*nding i+ple+entati*n, !hich i# created 3y inherit*r#) The interface key!*rd pr*duce# a c*+pletely a3#tract cla##, *ne that pr*vide# n* i+ple+entati*n at all) :*ull learn that the interface i# +*re than 4u#t an a3#tract cla## taken t* the e;tre+e, #ince it all*!# y*u t* per9*r+ a variati*n *n C@@# I+ultiple inheritance,J 3y creating a cla## that can 3e upca#t t* +*re than *ne 3a#e type) =t 9ir#t, inner cla##e# l**k like a #i+ple c*deEhiding +echani#+1 y*u place cla##e# in#ide *ther cla##e#) :*ull learn, h*!ever, that the inner cla##
335
d*e# +*re than thatRit kn*!# a3*ut and can c*++unicate !ith the #urr*unding cla##Rand that the kind *9 c*de y*u can !rite !ith inner cla##e# i# +*re elegant and clear, alth*ugh it i# a ne! c*ncept t* +*#t) -t take# #*+e ti+e t* 3ec*+e c*+9*rta3le !ith de#ign u#ing inner cla##e#)
Inter0aces
The interface key!*rd take# the abstract c*ncept *ne #tep 9urther) :*u c*uld think *9 it a# a IpureJ abstract cla##) -t all*!# the creat*r t* e#ta3li#h the 9*r+ 9*r a cla##1 +eth*d na+e#, argu+ent li#t#, and return type#, 3ut n* +eth*d 3*die#) =n interface can al#* c*ntain 9ield#, 3ut the#e are i+plicitly static and final) =n interface pr*vide# *nly a 9*r+, 3ut n* i+ple+entati*n) =n interface #ay#1 IThi# i# !hat all cla##e# that im"lement thi# particular inter9ace !ill l**k like)J Thu#, any c*de that u#e# a particular interface kn*!# !hat +eth*d# +ight 3e called 9*r that interface, and that# all) S* the interface i# u#ed t* e#ta3li#h a Ipr*t*c*lJ 3et!een cla##e#) GS*+e *34ectE*riented pr*gra++ing language# have a key!*rd called "rotocol t* d* the #a+e thing)H T* create an interface, u#e the interface key!*rd in#tead *9 the class key!*rd) Like a cla##, y*u can add the public key!*rd 3e9*re the interface key!*rd G3ut *nly i9 that interface i# de9ined in a 9ile *9 the
336
#a+e na+eH *r leave it *99 t* give I9riendlyJ #tatu# #* that it i# *nly u#a3le !ithin the #a+e package) T* +ake a cla## that c*n9*r+# t* a particular interface G*r gr*up *9 interface#H u#e the implements key!*rd) :*ure #aying IThe interface i# !hat it l**k# like 3ut n*! -+ g*ing t* #ay h*! it works)J Other than that, it l**k# like inheritance) The diagra+ 9*r the in#tru+ent e;a+ple #h*!# thi#1
in t e r 0a c e I n s t r u # e n t v o id $ la 5 1 2 L ' t r in g w h a t 1 2 L v o id a d /u s t 1 2 L
i# $ le # e n t s W in d v o id $ la 5 1 2 ' t r in g w h a t 1 2 v o id a d /u s t 1 2
i# $ le # e n t s P e r c u s s io n v o id $ la 5 1 2 ' t r in g w h a t 1 2 v o id a d /u s t 1 2
i# $ le # e n t s ' t r in g e d v o id $ la 5 1 2 ' t r in g w h a t 1 2 v o id a d / u s t 1 2
e & te n d s W o o d w in d v o id $ la 5 1 2 ' t r in g w h a t 1 2
e & te n d s 3 ra ss v o id $ la 5 1 2 v o id a d / u s t 1 2
Once y*uve i+ple+ented an interface, that i+ple+entati*n 3ec*+e# an *rdinary cla## that can 3e e;tended in the regular !ay) :*u can ch**#e t* e;plicitly declare the +eth*d declarati*n# in an interface a# public) But they are public even i9 y*u d*nt #ay it) S* !hen y*u implement an interface, the +eth*d# 9r*+ the interface +u#t 3e de9ined a# public) Other!i#e they !*uld de9ault t* I9riendly,J
33#
and y*ud 3e reducing the acce##i3ility *9 a +eth*d during inheritance, !hich i# n*t all*!ed 3y the "ava c*+piler) :*u can #ee thi# in the +*di9ied ver#i*n *9 the Bnstrument e;a+ple) *te that every +eth*d in the interface i# #trictly a declarati*n, !hich i# the *nly thing the c*+piler all*!#) -n additi*n, n*ne *9 the +eth*d# in Bnstrument are declared a# public, 3ut theyre aut*+atically public any!ay1 )B)1 -+ple+enting inter9ace can:t 3e declared virtual, #ince it# n*t rede9ining a cla##) *te that inter9ace# cant have c*+pileEti+e c*n#tant# GcheckH) //:c0I:Gu#icP.c# // 5nterface#. interface 5n#tru!ent ; // Co!pi e6ti!e con#tant: //! Co co!pi e con#tant# int i 9 P3 // Cannot ha*e !ethod definition#: *oid - ay013 // )uto!atica y pu$ ic #tring Vhat013 *oid )dDu#t013 < c a## Vind : 5n#tru!ent ; pu$ ic *irtua *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Vind.- ay01&13 < pu$ ic *irtua #tring Vhat01 ; return &Vind&3 < pu$ ic *irtua *oid )dDu#t01 ;< < c a## -ercu##ion pu$ ic *irtua Sy#te!.Con#o < pu$ ic *irtua &-ercu##ion&3 < pu$ ic *irtua < : 5n#tru!ent ; *oid - ay01 ; e.VriteLine0&-ercu##ion.- ay01&13 #tring Vhat01 ; return *oid )dDu#t01 ;<
33&
Thinking in C
www.ThinkingIn.!et
c a## Stringed : pu$ ic *irtua Sy#te!.Con#o < pu$ ic *irtua pu$ ic *irtua <
5n#tru!ent ; *oid - ay01 ; e.VriteLine0&#tringed.- ay01&13 #tring Vhat01 ; return &#tringed&3 < *oid )dDu#t01 ;<
c a## Bra## : Vind ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Bra##.- ay01&13 < pu$ ic o*erride *oid )dDu#t01 ; Sy#te!.Con#o e.VriteLine0&Bra##.)dDu#t01&13 < < c a## Vood.ind : Vind ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Vood.ind.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &Vood.ind&3 < < pu$ ic c a## Gu#icP ; // :oe#n't care a$out type2 #o ne. type# // added to the #y#te! #ti .or% right: #tatic *oid tune05n#tru!ent i1 ; // ... i.- ay013 < #tatic *oid tune) 05n#tru!entJK e1 ; for0int i 9 03 i W e.Length3 iRR1 tune0eJiK13 < pu$ ic #tatic *oid Gain01 ; 5n#tru!entJK orche#tra 9 ne. 5n#tru!entJPK3 int i 9 03 // Opca#ting during addition to the array: orche#traJiRRK 9 ne. Vind013
33'
orche#traJiRRK 9 ne. orche#traJiRRK 9 ne. orche#traJiRRK 9 ne. orche#traJiRRK 9 ne. tune) 0orche#tra13 < < ///:8
The re#t *9 the c*de !*rk# the #a+e) -t d*e#nt +atter i9 y*u are upca#ting t* a IregularJ cla## called Bnstrument, an abstract cla## called Bnstrument, *r t* an interface called Bnstrument) The 3ehavi*r i# the #a+e) -n 9act, y*u can #ee in the tune( ) +eth*d that there i#nt any evidence a3*ut !hether Bnstrument i# a IregularJ cla##, an abstract cla##, *r an interface) Thi# i# the intent1 Each appr*ach give# the pr*gra++er di99erent c*ntr*l *ver the !ay *34ect# are created and u#ed)
...
...
in t e r 0 a c e n
3 a s e C la s s 7 u n c t io n s
in t e r 0 a c e 1
in t e r 0a c e 2
...
in t e r 0 a c e n
34(
Thinking in C
www.ThinkingIn.!et
-n a derived cla##, y*u arent 9*rced t* have a 3a#e cla## that i# either an abstract *r Ic*ncreteJ G*ne !ith n* abstract +eth*d#H) -9 y*u do inherit 9r*+ a n*nEinterface, y*u can inherit 9r*+ *nly *ne) =ll the re#t *9 the 3a#e ele+ent# +u#t 3e interface#) :*u place all the inter9ace na+e# a9ter the implements key!*rd and #eparate the+ !ith c*++a#) :*u can have a# +any interface# a# y*u !antReach *ne 3ec*+e# an independent type that y*u can upca#t t*) The 9*ll*!ing e;a+ple #h*!# a c*ncrete cla## c*+3ined !ith #everal interface# t* pr*duce a ne! cla##1 //:c0I:)d*enture.c# // Gu tip e interface#. interface 5CanHight ; *oid Hight013 < interface 5CanS.i! ; *oid S.i!013 < interface 5CanH y ; *oid H y013 < c a## )ctionCharacter ; pu$ ic *oid Hight01 ;Sy#te!.Con#o e.VriteLine0&Highting&13< < c a## Uero : )ctionCharacter2 5CanHight2 5CanS.i!2 5CanH y ; pu$ ic *oid S.i!01 ;Sy#te!.Con#o e.VriteLine0&S.i!!ing&13< pu$ ic *oid H y01 ;Sy#te!.Con#o e.VriteLine0&H ying&13< < pu$ ic c #tatic #tatic #tatic a## )d*enture ; *oid '05CanHight x1 ; x.Hight013 < *oid O05CanS.i! x1 ; x.S.i!013 < *oid N05CanH y x1 ; x.H y013 <
341
#tatic *oid V0)ctionCharacter x1 ; x.Hight013 < pu$ ic #tatic *oid Gain01 ; Uero h 9 ne. Uero013 '0h13 // 'reat it a# an 5CanHight O0h13 // 'reat it a# an 5CanS.i! N0h13 // 'reat it a# an 5CanH y V0h13 // 'reat it a# an )ctionCharacter < < ///:8 :*u can #ee that "ero c*+3ine# the c*ncrete cla## 'ctionCharacter !ith the inter9ace# Can:ight, Can#wim, and Can:ly) ,hen y*u c*+3ine a c*ncrete cla## !ith inter9ace# thi# !ay, the c*ncrete cla## +u#t c*+e 9ir#t, then the inter9ace#) GThe c*+piler give# an err*r *ther!i#e)H *te that the #ignature 9*r fight( ) i# the #a+e in the interface Can:ight and the cla## 'ctionCharacter, and that fight( ) i# not pr*vided !ith a de9initi*n in "ero) The rule 9*r an interface i# that y*u can inherit 9r*+ it Ga# y*u !ill #ee #h*rtlyH, 3ut then y*uve g*t an*ther interface) -9 y*u !ant t* create an *34ect *9 the ne! type, it +u#t 3e a cla## !ith all de9initi*n# pr*vided) Even th*ugh "ero d*e# n*t e;plicitly pr*vide a de9initi*n 9*r fight( ), the de9initi*n c*+e# al*ng !ith 'ctionCharacter #* it i# aut*+atically pr*vided and it# p*##i3le t* create *34ect# *9 "ero) -n cla## 'dventure, y*u can #ee that there are 9*ur +eth*d# that take a# argu+ent# the vari*u# inter9ace# and the c*ncrete cla##) ,hen a "ero *34ect i# created, it can 3e pa##ed t* any *9 the#e +eth*d#, !hich +ean# it i# 3eing upca#t t* each interface in turn) Becau#e *9 the !ay inter9ace# are de#igned in "ava, thi# !*rk# !ith*ut a hitch and !ith*ut any particular e99*rt *n the part *9 the pr*gra++er) Neep in +ind that the c*re rea#*n 9*r inter9ace# i# #h*!n in the a3*ve e;a+ple1 t* 3e a3le t* upca#t t* +*re than *ne 3a#e type) H*!ever, a #ec*nd rea#*n 9*r u#ing inter9ace# i# the #a+e a# u#ing an abstract 3a#e cla##1 t* prevent the client pr*gra++er 9r*+ +aking an *34ect *9 thi# cla## and t* e#ta3li#h that it i# *nly an inter9ace) Thi# 3ring# up a Due#ti*n1 Sh*uld y*u u#e an interface *r an abstract cla##F =n interface give# y*u the 3ene9it# *9 an abstract cla## and the 3ene9it# *9 an interface, #* i9 it# p*##i3le t* create y*ur 3a#e cla## !ith*ut any +eth*d de9initi*n# *r +e+3er varia3le# y*u #h*uld al!ay# pre9er
34)
Thinking in C
www.ThinkingIn.!et
interface# t* abstract cla##e#) -n 9act, i9 y*u kn*! #*+ething i# g*ing t* 3e a 3a#e cla##, y*ur 9ir#t ch*ice #h*uld 3e t* +ake it an interface, and *nly i9 y*ure 9*rced t* have +eth*d de9initi*n# *r +e+3er varia3le# #h*uld y*u change t* an abstract cla##, *r i9 nece##ary a c*ncrete cla##)
343
c a## C?: 5E; *oid 5".H01 ; < int 5T.H01 ; return "3 < <///:8 The di99iculty *ccur# 3ecau#e *verriding, i+ple+entati*n, and *verl*ading get unplea#antly +i;ed t*gether, and *verl*aded 9uncti*n# cann*t di99er *nly 3y return type) ,hen the la#t t!* line# are unc*++ented, the err*r +e##age# #ay it all1 Inter$aceCollision.3a-a*)3* $AB in C cannot im"lement $AB in I17 attem"ting to use incom"ati2le return t4"e $ound * int re8uired* -oid Inter$aceCollision.3a-a*)4* inter$aces I3 and I1 are incom"ati2le7 2oth de$ine $AB6 2ut with di$$erent return t4"e U#ing the #a+e +eth*d na+e# in di99erent inter9ace# that are intended t* 3e c*+3ined generally cau#e# c*n9u#i*n in the reada3ility *9 the c*de, a# !ell) Strive t* av*id it)
344
Thinking in C
www.ThinkingIn.!et
c a## :ragonbi a : :angerou#Gon#ter ; pu$ ic *oid Genace01 ;< pu$ ic *oid :e#troy01 ;< < interface Na!pire : :angerou#Gon#ter2 Letha *oid :rin%B ood013 < pu$ ic c a## UorrorSho. ; #tatic *oid O0Gon#ter $1 ; $.Genace013 < #tatic *oid N0:angerou#Gon#ter d1 ; d.Genace013 d.:e#troy013 < pu$ ic #tatic *oid Gain01 ; :ragonbi a if2 9 ne. :ragonbi a013 O0if213 N0if213 < < ///:8 $angerous.onster i# a #i+ple e;ten#i*n t* .onster that pr*duce# a ne! interface) Thi# i# i+ple+ented in $ragon\illa) The #ynta; u#ed in Hampire !*rk# onl4 !hen inheriting inter9ace#) *r+ally, y*u can u#e extends !ith *nly a #ingle cla##, 3ut #ince an interface can 3e +ade 9r*+ +ultiple *ther inter9ace#, extends can re9er t* +ultiple 3a#e inter9ace# !hen 3uilding a ne! interface) =# y*u can #ee, the interface na+e# are #i+ply #eparated !ith c*++a#) ;
345
4oesnt wor* in C#. @ust have section on enu#s and structs earlier
Becau#e any 9ield# y*u put int* an interface are aut*+atically static and final, the interface i# a c*nvenient t**l 9*r creating gr*up# *9 c*n#tant value#, +uch a# y*u !*uld !ith an enum in C *r C@@) 5*r e;a+ple1 //:c0I:Gonth#.Da*a // O#ing interface# to create group# of con#tant#. pac%age c0I3 pu$ ic interface Gonth# ; int `)CO)R/ 9 "2 H+BRO)R/ 9 22 G)RCU 9 T2 )-R5L 9 E2 G)/ 9 P2 `OC+ 9 ?2 `OL/ 9 F2 )O_OS' 9 I2 S+-'+GB+R 9 >2 OC'OB+R 9 "02 CON+GB+R 9 ""2 :+C+GB+R 9 "23 < ///:8 *tice the "ava #tyle *9 u#ing all upperca#e letter# G!ith under#c*re# t* #eparate +ultiple !*rd# in a #ingle identi9ierH 9*r static final# that have c*n#tant initiali7er#) The 9ield# in an interface are aut*+atically public, #* it# unnece##ary t* #peci9y that) *! y*u can u#e the c*n#tant# 9r*+ *ut#ide the package 3y i+p*rting c4]6; *r c4]6.onths 4u#t a# y*u !*uld !ith any *ther package, and re9erencing the value# !ith e;pre##i*n# like .onths6X',V'*@) O9 c*ur#e, !hat y*u get i# 4u#t an int, #* there i#nt the e;tra type #a9ety that C@@# enum ha#, 3ut thi# Gc*++*nly u#edH techniDue i# certainly an i+pr*ve+ent *ver hardEc*ding nu+3er# int* y*ur pr*gra+#) GThat appr*ach i# *9ten re9erred t* a# u#ing I+agic nu+3er#J and it pr*duce# very di99icultEt*E+aintain c*de)H -9 y*u d* !ant e;tra type #a9ety, y*u can 3uild a cla## like thi# 01
0 Thi# appr*ach !a# in#pired 3y an eE+ail 9r*+ Rich H*99arth)
346
Thinking in C
www.ThinkingIn.!et
//: c0I:Gonth2.Da*a // ) !ore ro$u#t enu!eration #y#te!. pac%age c0I3 pu$ ic fina c a## Gonth2 ; pri*ate String na!e3 pri*ate int order3 pri*ate Gonth20int ord2 String n!1 ; order 9 ord3 na!e 9 n!3 < pu$ ic String toString01 ; return na!e3 < pu$ ic fina #tatic Gonth2 `)C 9 ne. Gonth20"2 &`anuary&12 H+B 9 ne. Gonth2022 &He$ruary&12 G)R 9 ne. Gonth20T2 &Garch&12 )-R 9 ne. Gonth20E2 &)pri &12 G)/ 9 ne. Gonth20P2 &Gay&12 `OC 9 ne. Gonth20?2 &`une&12 `OL 9 ne. Gonth20F2 &`u y&12 )O_ 9 ne. Gonth20I2 &)ugu#t&12 S+- 9 ne. Gonth20>2 &Septe!$er&12 OC' 9 ne. Gonth20"02 &Octo$er&12 CON 9 ne. Gonth20""2 &Co*e!$er&12 :+C 9 ne. Gonth20"22 &:ece!$er&13 pu$ ic fina #tatic Gonth2JK !onth 9 ; `)C2 H+B2 G)R2 )-R2 G)/2 `OC2 `OL2 )O_2 S+-2 OC'2 CON2 :+C <3 pu$ ic fina #tatic Gonth2 nu!$er0int ord1 ; return !onthJord 6 "K3 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; Gonth2 ! 9 Gonth2.`)C3 Sy#te!.out.print n0!13 ! 9 Gonth2.nu!$er0"213 Sy#te!.out.print n0!13 Sy#te!.out.print n0! 99 Gonth2.:+C13 Sy#te!.out.print n0!.e7ua #0Gonth2.:+C113 < < ///:8
34#
The cla## i# called .onth8, #ince there# already a .onth in the #tandard "ava li3rary) -t# a final cla## !ith a private c*n#truct*r #* n* *ne can inherit 9r*+ it *r +ake any in#tance# *9 it) The *nly in#tance# are the final static *ne# created in the cla## it#el91 X',, :&B, .'*, etc) The#e *34ect# are al#* u#ed in the array month, !hich let# y*u iterate thr*ugh an array *9 .onth8 *34ect#) The number( ) +eth*d all*!# y*u t* #elect a .onth8 3y giving it# c*rre#p*nding +*nth nu+3er) -n main( ) y*u can #ee the type #a9ety1 m i# a .onth8 *34ect #* it can 3e a##igned *nly t* a .onth8) The previ*u# e;a+ple .onths6)ava pr*vided *nly int value#, #* an int varia3le intended t* repre#ent a +*nth c*uld actually 3e given any integer value, !hich !a#nt very #a9e) Thi# appr*ach al#* all*!# y*u t* u#e II *r e%uals( ) interchangea3ly, a# #h*!n at the end *9 main( )) Thi# !*rk# 3ecau#e there can 3e *nly *ne in#tance *9 each value *9 .onth8)
34&
Thinking in C
www.ThinkingIn.!et
pu$ ic c a## 'e#tRandNa # ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; Sy#te!.out.print n0RandNa #.rint13 Sy#te!.out.print n0RandNa #.r ong13 Sy#te!.out.print n0RandNa #.rf oat13 Sy#te!.out.print n0RandNa #.rdou$ e13 < < ///:8 The 9ield#, *9 c*ur#e, are n*t part *9 the inter9ace 3ut in#tead are #t*red in the static #t*rage area 9*r that inter9ace)
(esting inter0aces
-nter9ace# +ay 3e ne#ted !ithin cla##e# and !ithin *ther inter9ace#) Thi# reveal# a nu+3er *9 very intere#ting 9eature#1
2
//: c0I:Ce#ting5nterface#.Da*a c a## ) ; interface B ; *oid f013 < pu$ ic c a## B5!p i!p e!ent# B ; pu$ ic *oid f01 ;< < pri*ate c a## B5!p2 i!p e!ent# B ; pu$ ic *oid f01 ;< < pu$ ic interface C ; *oid f013 < c a## C5!p i!p e!ent# C ; pu$ ic *oid f01 ;< < pri*ate c a## C5!p2 i!p e!ent# C ; pu$ ic *oid f01 ;< < pri*ate interface : ; *oid f013
2 Thank# t* Aartin ?anner 9*r a#king thi# Due#ti*n during a #e+inar)
34'
< pri*ate c a## :5!p i!p e!ent# : ; pu$ ic *oid f01 ;< < pu$ ic c a## :5!p2 i!p e!ent# : ; pu$ ic *oid f01 ;< < pu$ ic : get:01 ; return ne. :5!p2013 < pri*ate : dRef3 pu$ ic *oid recei*e:0: d1 ; dRef 9 d3 dRef.f013 < < interface + ; interface _ ; *oid f013 < // Redundant &pu$ ic&: pu$ ic interface U ; *oid f013 < *oid g013 // Cannot $e pri*ate .ithin an interface: //! pri*ate interface 5 ;< < pu$ ic c a## Ce#ting5nterface# ; pu$ ic c a## B5!p i!p e!ent# ).B ; pu$ ic *oid f01 ;< < c a## C5!p i!p e!ent# ).C ; pu$ ic *oid f01 ;< < // Cannot i!p e!ent a pri*ate interface except // .ithin that interface'# defining c a##: //! c a## :5!p i!p e!ent# ).: ; //! pu$ ic *oid f01 ;< //! < c a## +5!p i!p e!ent# + ;
35(
Thinking in C
www.ThinkingIn.!et
pu$ ic *oid g01 ;< < c a## +_5!p i!p e!ent# +._ ; pu$ ic *oid f01 ;< < c a## +5!p2 i!p e!ent# + ; pu$ ic *oid g01 ;< c a## +_ i!p e!ent# +._ ; pu$ ic *oid f01 ;< < < pu$ ic #tatic *oid !ain0StringJK arg#1 ; ) a 9 ne. )013 // Can't acce## ).:: //! ).: ad 9 a.get:013 // :oe#n't return anything $ut ).:: //! ).:5!p2 di2 9 a.get:013 // Cannot acce## a !e!$er of the interface: //! a.get:01.f013 // On y another ) can do anything .ith get:01: ) a2 9 ne. )013 a2.recei*e:0a.get:0113 < < ///:8 The #ynta; 9*r ne#ting an inter9ace !ithin a cla## i# rea#*na3ly *3vi*u#, and 4u#t like n*nEne#ted inter9ace# the#e can have public *r I9riendlyJ vi#i3ility) :*u can al#* #ee that 3*th public and I9riendlyJ ne#ted inter9ace# can 3e i+ple+ented a# public, I9riendly,J and private ne#ted cla##e#) =# a ne! t!i#t, inter9ace# can al#* 3e private a# #een in '6$ Gthe #a+e Duali9icati*n #ynta; i# u#ed 9*r ne#ted inter9ace# a# 9*r ne#ted cla##e#H) ,hat g**d i# a private ne#ted inter9aceF :*u +ight gue## that it can *nly 3e i+ple+ented a# a private ne#ted cla## a# in $Bmp, 3ut '6$Bmp8 #h*!# that it can al#* 3e i+ple+ented a# a public cla##) H*!ever, '6$Bmp8 can *nly 3e u#ed a# it#el9) :*u are n*t all*!ed t* +enti*n the 9act that it i+ple+ent# the private inter9ace, #* i+ple+enting a private inter9ace i# a !ay t* 9*rce the de9initi*n *9 the +eth*d# in that inter9ace !ith*ut adding any type in9*r+ati*n Gthat i#, !ith*ut all*!ing any upca#tingH)
351
The +eth*d get$( ) pr*duce# a 9urther Duandary c*ncerning the private inter9ace1 it# a public +eth*d that return# a re9erence t* a private inter9ace) ,hat can y*u d* !ith the return value *9 thi# +eth*dF -n main( ), y*u can #ee #everal atte+pt# t* u#e the return value, all *9 !hich 9ail) The *nly thing that !*rk# i# i9 the return value i# handed t* an *34ect that ha# per+i##i*n t* u#e itRin thi# ca#e, an*ther ', via the receive$( ) +eth*d) -nter9ace & #h*!# that inter9ace# can 3e ne#ted !ithin each *ther) H*!ever, the rule# a3*ut inter9ace#Rin particular, that all inter9ace ele+ent# +u#t 3e publicRare #trictly en9*rced here, #* an inter9ace ne#ted !ithin an*ther inter9ace i# aut*+atically public and cann*t 3e +ade private) ,estingBnterfaces #h*!# the vari*u# !ay# that ne#ted inter9ace# can 3e i+ple+ented) -n particular, n*tice that !hen y*u i+ple+ent an inter9ace, y*u are n*t reDuired t* i+ple+ent any inter9ace# ne#ted !ithin) =l#*, private inter9ace# cann*t 3e i+ple+ented *ut#ide *9 their de9ining cla##e#) -nitially, the#e 9eature# +ay #ee+ like they are added #trictly 9*r #yntactic c*n#i#tency, 3ut - generally 9ind that *nce y*u kn*! a3*ut a 9eature, y*u *9ten di#c*ver place# !here it i# u#e9ul)
Inner classes
-t# p*##i3le t* place a cla## de9initi*n !ithin an*ther cla## de9initi*n) Thi# i# called an inner class) The inner cla## i# a valua3le 9eature 3ecau#e it all*!# y*u t* gr*up cla##e# that l*gically 3el*ng t*gether and t* c*ntr*l the vi#i3ility *9 *ne !ithin the *ther) H*!ever, it# i+p*rtant t* under#tand that inner cla##e# are di#tinctly di99erent 9r*+ c*+p*#iti*n) O9ten, !hile y*ure learning a3*ut the+, the need 9*r inner cla##e# i#nt i++ediately *3vi*u#) =t the end *9 thi# #ecti*n, a9ter all *9 the #ynta; and #e+antic# *9 inner cla##e# have 3een de#cri3ed, y*ull 9ind e;a+ple# that #h*uld +ake clear the 3ene9it# *9 inner cla##e#)
35)
Thinking in C
www.ThinkingIn.!et
:*u create an inner cla## 4u#t a# y*ud e;pectR3y placing the cla## de9initi*n in#ide a #urr*unding cla##1 //: c0I:-arce ".Da*a // Creating inner c a##e#. pu$ ic c a## -arce " ; c a## Content# ; pri*ate int i 9 ""3 pu$ ic int *a ue01 ; return i3 < < c a## :e#tination ; pri*ate String a$e 3 :e#tination0String .here'o1 ; a$e 9 .here'o3 < String readLa$e 01 ; return a$e 3 < < // O#ing inner c a##e# oo%# Du#t i%e // u#ing any other c a##2 .ithin -arce ": pu$ ic *oid #hip0String de#t1 ; Content# c 9 ne. Content#013 :e#tination d 9 ne. :e#tination0de#t13 Sy#te!.out.print n0d.readLa$e 0113 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce " p 9 ne. -arce "013 p.#hip0&'anMania&13 < < ///:8 The inner cla##e#, !hen u#ed in#ide ship( ), l**k 4u#t like the u#e *9 any *ther cla##e#) Here, the *nly practical di99erence i# that the na+e# are ne#ted !ithin !arcel7) :*ull #ee in a !hile that thi# i#nt the *nly di99erence) A*re typically, an *uter cla## !ill have a +eth*d that return# a re9erence t* an inner cla##, like thi#1 //: c0I:-arce 2.Da*a // Returning a reference to an inner c a##.
353
pu$ ic c a## -arce 2 ; c a## Content# ; pri*ate int i 9 ""3 pu$ ic int *a ue01 ; return i3 < < c a## :e#tination ; pri*ate String a$e 3 :e#tination0String .here'o1 ; a$e 9 .here'o3 < String readLa$e 01 ; return a$e 3 < < pu$ ic :e#tination to0String #1 ; return ne. :e#tination0#13 < pu$ ic Content# cont01 ; return ne. Content#013 < pu$ ic *oid #hip0String de#t1 ; Content# c 9 cont013 :e#tination d 9 to0de#t13 Sy#te!.out.print n0d.readLa$e 0113 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce 2 p 9 ne. -arce 2013 p.#hip0&'anMania&13 -arce 2 7 9 ne. -arce 2013 // :efining reference# to inner c a##e#: -arce 2.Content# c 9 7.cont013 -arce 2.:e#tination d 9 7.to0&Borneo&13 < < ///:8 -9 y*u !ant t* +ake an *34ect *9 the inner cla## any!here e;cept 9r*+ !ithin a n*nEstatic +eth*d *9 the *uter cla##, y*u +u#t #peci9y the type *9 that *34ect a# 1uterClass!ame.InnerClass!ame, a# #een in main( ))
354
Thinking in C
www.ThinkingIn.!et
355
pu$ ic int *a ue01 ; return i3 < < protected c a## -:e#tination i!p e!ent# :e#tination ; pri*ate String a$e 3 pri*ate -:e#tination0String .here'o1 ; a$e 9 .here'o3 < pu$ ic String readLa$e 01 ; return a$e 3 < < pu$ ic :e#tination de#t0String #1 ; return ne. -:e#tination0#13 < pu$ ic Content# cont01 ; return ne. -Content#013 < < c a## 'e#t ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce T p 9 ne. -arce T013 Content# c 9 p.cont013 :e#tination d 9 p.de#t0&'anMania&13 // 5 ega 66 can't acce## pri*ate c a##: //! -arce T.-Content# pc 9 p.ne. -Content#013 < < ///:8 *te that #ince main( ) i# in +est, !hen y*u !ant t* run thi# pr*gra+ y*u d*nt e;ecute !arcel9, 3ut in#tead1 Da*a 'e#t -n the e;a+ple, main( ) +u#t 3e in a #eparate cla## in *rder t* de+*n#trate the privatene## *9 the inner cla## !Contents) -n !arcel9, #*+ething ne! ha# 3een added1 the inner cla## !Contents i# private #* n* *ne 3ut !arcel9 can acce## it) !$estination i# protected, #* n* *ne 3ut !arcel9, cla##e# in the !arcel9 package G#ince protected al#* give# package acce##Rthat i#, protected i# al#* I9riendlyJH, and the inherit*r# *9 !arcel9 can acce## !$estination) Thi# +ean# that the client pr*gra++er ha# re#tricted kn*!ledge and acce## t*
356
Thinking in C
www.ThinkingIn.!et
the#e +e+3er#) -n 9act, y*u cant even d*!nca#t t* a private inner cla## G*r a protected inner cla## unle## y*ure an inherit*rH, 3ecau#e y*u cant acce## the na+e, a# y*u can #ee in class +est) Thu#, the private inner cla## pr*vide# a !ay 9*r the cla## de#igner t* c*+pletely prevent any typeE c*ding dependencie# and t* c*+pletely hide detail# a3*ut i+ple+entati*n) -n additi*n, e;ten#i*n *9 an interface i# u#ele## 9r*+ the client pr*gra++er# per#pective #ince the client pr*gra++er cann*t acce## any additi*nal +eth*d# that arent part *9 the public interface) Thi# al#* pr*vide# an *pp*rtunity 9*r the "ava c*+piler t* generate +*re e99icient c*de) *r+al Gn*nEinnerH cla##e# cann*t 3e +ade private *r protected[*nly public *r I9riendly)J
-n the 9*ll*!ing e;a+ple#, the previ*u# c*de !ill 3e +*di9ied t* u#e1 1. 2. 3. = cla## de9ined !ithin a +eth*d = cla## de9ined !ithin a #c*pe in#ide a +eth*d =n an*ny+*u# cla## i+ple+enting an inter9ace
35#
. !. ".
=n an*ny+*u# cla## e;tending a cla## that ha# a n*nde9ault c*n#truct*r =n an*ny+*u# cla## that per9*r+# 9ield initiali7ati*n =n an*ny+*u# cla## that per9*r+# c*n#tructi*n u#ing in#tance initiali7ati*n Gan*ny+*u# inner cla##e# cann*t have c*n#truct*r#H
=lth*ugh it# an *rdinary cla## !ith an i+ple+entati*n, =rapping i# al#* 3eing u#ed a# a c*++*n Iinter9aceJ t* it# derived cla##e#1 //: c0I:Vrapping.Da*a pu$ ic c a## Vrapping ; pri*ate int i3 pu$ ic Vrapping0int x1 ; i 9 x3 < pu$ ic int *a ue01 ; return i3 < < ///:8 :*ull n*tice a3*ve that =rapping ha# a c*n#truct*r that reDuire# an argu+ent, t* +ake thing# a 3it +*re intere#ting) The 9ir#t e;a+ple #h*!# the creati*n *9 an entire cla## !ithin the #c*pe *9 a +eth*d Gin#tead *9 the #c*pe *9 an*ther cla##H1 //: c0I:-arce E.Da*a // Ce#ting a c a## .ithin a !ethod. pu$ ic c a## -arce E ; pu$ ic :e#tination de#t0String #1 ; c a## -:e#tination i!p e!ent# :e#tination ; pri*ate String a$e 3 pri*ate -:e#tination0String .here'o1 ; a$e 9 .here'o3 < pu$ ic String readLa$e 01 ; return a$e 3 < < return ne. -:e#tination0#13 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce E p 9 ne. -arce E013 :e#tination d 9 p.de#t0&'anMania&13
35&
Thinking in C
www.ThinkingIn.!et
< < ///:8 The cla## !$estination i# part *9 dest( ) rather than 3eing part *9 !arcelJ) G=l#* n*tice that y*u c*uld u#e the cla## identi9ier !$estination 9*r an inner cla## in#ide each cla## in the #a+e #u3direct*ry !ith*ut a na+e cla#h)H There9*re, !$estination cann*t 3e acce##ed *ut#ide *9 dest( )) *tice the upca#ting that *ccur# in the return #tate+entRn*thing c*+e# *ut *9 dest( ) e;cept a re9erence t* $estination, the 3a#e cla##) O9 c*ur#e, the 9act that the na+e *9 the cla## !$estination i# placed in#ide dest( ) d*e#nt +ean that !$estination i# n*t a valid *34ect *nce dest( ) return#) The ne;t e;a+ple #h*!# h*! y*u can ne#t an inner cla## !ithin any ar3itrary #c*pe1 //: c0I:-arce P.Da*a // Ce#ting a c a## .ithin a #cope. pu$ ic c a## -arce P ; pri*ate *oid interna 'rac%ing0$oo ean $1 ; if0$1 ; c a## 'rac%ingS ip ; pri*ate String id3 'rac%ingS ip0String #1 ; id 9 #3 < String getS ip01 ; return id3 < < 'rac%ingS ip t# 9 ne. 'rac%ingS ip0&# ip&13 String # 9 t#.getS ip013 < // Can't u#e it here! Out of #cope: //! 'rac%ingS ip t# 9 ne. 'rac%ingS ip0&x&13 < pu$ ic *oid trac%01 ; interna 'rac%ing0true13 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce P p 9 ne. -arce P013 p.trac%013 < < ///:8
35'
The cla## +rac(ing#lip i# ne#ted in#ide the #c*pe *9 an if #tate+ent) Thi# d*e# n*t +ean that the cla## i# c*nditi*nally createdRit get# c*+piled al*ng !ith everything el#e) H*!ever, it# n*t availa3le *ut#ide the #c*pe in !hich it i# de9ined) Other than that, it l**k# 4u#t like an *rdinary cla##)
36(
Thinking in C
www.ThinkingIn.!et
,hat thi# #trange #ynta; +ean# i#1 ICreate an *34ect *9 an an*ny+*u# cla## that# inherited 9r*+ Contents)J The re9erence returned 3y the new e;pre##i*n i# aut*+atically upca#t t* a Contents re9erence) The an*ny+*u# innerEcla## #ynta; i# a #h*rthand 9*r1 c a## GyContent# i!p e!ent# Content# ; pri*ate int i 9 ""3 pu$ ic int *a ue01 ; return i3 < < return ne. GyContent#013 -n the an*ny+*u# inner cla##, Contents i# created u#ing a de9ault c*n#truct*r) The 9*ll*!ing c*de #h*!# !hat t* d* i9 y*ur 3a#e cla## need# a c*n#truct*r !ith an argu+ent1 //: c0I:-arce F.Da*a // )n anony!ou# inner c a## that ca // the $a#e6c a## con#tructor. #
pu$ ic c a## -arce F ; pu$ ic Vrapping .rap0int x1 ; // Ba#e con#tructor ca : return ne. Vrapping0x1 ; pu$ ic int *a ue01 ; return #uper.*a ue01 = EF3 < <3 // Se!ico on re7uired < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce F p 9 ne. -arce F013 Vrapping . 9 p..rap0"013 < < ///:8 That i#, y*u #i+ply pa## the appr*priate argu+ent t* the 3a#eEcla## c*n#truct*r, #een here a# the x pa##ed in new =rapping(x)) =n an*ny+*u# cla## cann*t have a c*n#truct*r !here y*u !*uld n*r+ally call super( )) -n 3*th *9 the previ*u# e;a+ple#, the #e+ic*l*n d*e#nt +ark the end *9 the cla## 3*dy Ga# it d*e# in C@@H) -n#tead, it +ark# the end *9 the
361
e;pre##i*n that happen# t* c*ntain the an*ny+*u# cla##) Thu#, it# identical t* the u#e *9 the #e+ic*l*n every!here el#e) ,hat happen# i9 y*u need t* per9*r+ #*+e kind *9 initiali7ati*n 9*r an *34ect *9 an an*ny+*u# inner cla##F Since it# an*ny+*u#, there# n* na+e t* give the c*n#truct*rR#* y*u cant have a c*n#truct*r) :*u can, h*!ever, per9*r+ initiali7ati*n at the p*int *9 de9initi*n *9 y*ur 9ield#1 //: c0I:-arce I.Da*a // )n anony!ou# inner c a## that perfor!# // initia iMation. ) $riefer *er#ion // of -arce P.Da*a. pu$ ic c a## -arce I ; // )rgu!ent !u#t $e fina to u#e in#ide // anony!ou# inner c a##: pu$ ic :e#tination de#t0fina String de#t1 ; return ne. :e#tination01 ; pri*ate String a$e 9 de#t3 pu$ ic String readLa$e 01 ; return a$e 3 < <3 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce I p 9 ne. -arce I013 :e#tination d 9 p.de#t0&'anMania&13 < < ///:8 -9 y*ure de9ining an an*ny+*u# inner cla## and !ant t* u#e an *34ect that# de9ined *ut#ide the an*ny+*u# inner cla##, the c*+piler reDuire# that the *ut#ide *34ect 3e final) Thi# i# !hy the argu+ent t* dest( ) i# final) -9 y*u 9*rget, y*ull get a c*+pileEti+e err*r +e##age) =# l*ng a# y*ure #i+ply a##igning a 9ield, the a3*ve appr*ach i# 9ine) But !hat i9 y*u need t* per9*r+ #*+e c*n#truct*rElike activityF ,ith instance initiali;ation, y*u can, in e99ect, create a c*n#truct*r 9*r an an*ny+*u# inner cla##1 //: c0I:-arce >.Da*a // O#ing &in#tance initia iMation& to perfor! // con#truction on an anony!ou# inner c a##.
36)
Thinking in C
www.ThinkingIn.!et
pu$ ic c a## -arce > ; pu$ ic :e#tination de#t0fina String de#t2 fina f oat price1 ; return ne. :e#tination01 ; pri*ate int co#t3 // 5n#tance initia iMation for each o$Dect: ; co#t 9 Gath.round0price13 if0co#t Z "001 Sy#te!.out.print n0&O*er $udget!&13 < pri*ate String a$e 9 de#t3 pu$ ic String readLa$e 01 ; return a$e 3 < <3 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce > p 9 ne. -arce >013 :e#tination d 9 p.de#t0&'anMania&2 "0".T>PH13 < < ///:8 -n#ide the in#tance initiali7er y*u can #ee c*de that c*uldnt 3e e;ecuted a# part *9 a 9ield initiali7er Gthat i#, the if #tate+entH) S* in e99ect, an in#tance initiali7er i# the c*n#truct*r 9*r an an*ny+*u# inner cla##) O9 c*ur#e, it# li+itedQ y*u cant *verl*ad in#tance initiali7er# #* y*u can have *nly *ne *9 the#e c*n#truct*r#)
hiding +echani#+) There i# n* link t* an encl*#ing *34ect and n* i+plied per+i##i*n# in C@@)
363
//: c0I:Se7uence.Da*a // Uo d# a #e7uence of O$Dect#. interface Se ector ; $oo ean end013 O$Dect current013 *oid next013 < pu$ ic c a## Se7uence ; pri*ate O$DectJK o$#3 pri*ate int next 9 03 pu$ ic Se7uence0int #iMe1 ; o$# 9 ne. O$DectJ#iMeK3 < pu$ ic *oid add0O$Dect x1 ; if0next W o$#. ength1 ; o$#JnextK 9 x3 nextRR3 < < pri*ate c a## SSe ector i!p e!ent# Se ector ; int i 9 03 pu$ ic $oo ean end01 ; return i 99 o$#. ength3 < pu$ ic O$Dect current01 ; return o$#JiK3 < pu$ ic *oid next01 ; if0i W o$#. ength1 iRR3 < < pu$ ic Se ector getSe ector01 ; return ne. SSe ector013 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; Se7uence # 9 ne. Se7uence0"013 for0int i 9 03 i W "03 iRR1 #.add05nteger.toString0i113 Se ector # 9 #.getSe ector013
364
Thinking in C
www.ThinkingIn.!et
.hi e0!# .end011 ; Sy#te!.out.print n0# .current0113 # .next013 < < < ///:8 The #e%uence i# #i+ply a 9i;edE#i7ed array *9 ob)ect !ith a cla## !rapped ar*und it) :*u call add( ) t* add a ne! ob)ect t* the end *9 the #eDuence Gi9 there# r**+ le9tH) T* 9etch each *9 the *34ect# in a #e%uence, there# an inter9ace called #elector, !hich all*!# y*u t* #ee i9 y*ure at the end( ), t* l**k at the current( ) ob)ect, and t* +*ve t* the next( ) ob)ect in the #e%uence) Becau#e #elector i# an interface, +any *ther cla##e# can i+ple+ent the interface in their *!n !ay#, and +any +eth*d# can take the interface a# an argu+ent, in *rder t* create generic c*de) Here, the ##elector i# a private cla## that pr*vide# #elector 9uncti*nality) -n main( ), y*u can #ee the creati*n *9 a #e%uence, 9*ll*!ed 3y the additi*n *9 a nu+3er *9 #tring *34ect#) Then, a #elector i# pr*duced !ith a call t* get#elector( ) and thi# i# u#ed t* +*ve thr*ugh the #e%uence and #elect each ite+) =t 9ir#t, the creati*n *9 ##elector l**k# like 4u#t an*ther inner cla##) But e;a+ine it cl*#ely) *te that each *9 the +eth*d# end( ), current( ), and next( ) re9er t* obs, !hich i# a re9erence that i#nt part *9 ##elector, 3ut i# in#tead a private 9ield in the encl*#ing cla##) H*!ever, the inner cla## can acce## +eth*d# and 9ield# 9r*+ the encl*#ing cla## a# i9 they *!ned the+) Thi# turn# *ut t* 3e very c*nvenient, a# y*u can #ee in the a3*ve e;a+ple) S* an inner cla## ha# aut*+atic acce## t* the +e+3er# *9 the encl*#ing cla##) H*! can thi# happenF The inner cla## +u#t keep a re9erence t* the particular *34ect *9 the encl*#ing cla## that !a# re#p*n#i3le 9*r creating it) Then !hen y*u re9er t* a +e+3er *9 the encl*#ing cla##, that GhiddenH re9erence i# u#ed t* #elect that +e+3er) 5*rtunately, the c*+piler take# care *9 all the#e detail# 9*r y*u, 3ut y*u can al#* under#tand n*! that an *34ect *9 an inner cla## can 3e created *nly in a##*ciati*n !ith an *34ect *9 the encl*#ing cla##) C*n#tructi*n *9 the inner cla## *34ect reDuire# the re9erence t* the *34ect *9 the encl*#ing cla##, and the c*+piler !ill
365
c*+plain i9 it cann*t acce## that re9erence) A*#t *9 the ti+e thi# *ccur# !ith*ut any interventi*n *n the part *9 the pr*gra++er)
static inner cla##e# are di99erent than n*nEstatic inner cla##e# in an*ther !ay, a# !ell) 5ield# and +eth*d# in n*nEstatic inner cla##e# can *nly 3e at the *uter level *9 a cla##, #* n*nEstatic inner cla##e# cann*t have static data, static 9ield#, *r static inner cla##e#) H*!ever, static inner cla##e# can have all *9 the#e1 //: c0I:-arce "0.Da*a // Static inner c a##e#. pu$ ic c a## -arce "0 ; pri*ate #tatic c a## -Content# i!p e!ent# Content# ; pri*ate int i 9 ""3 pu$ ic int *a ue01 ; return i3 < < protected #tatic c a## -:e#tination i!p e!ent# :e#tination ; pri*ate String a$e 3 pri*ate -:e#tination0String .here'o1 ; a$e 9 .here'o3 < pu$ ic String readLa$e 01 ; return a$e 3 <
366
Thinking in C
www.ThinkingIn.!et
// Static inner c a##e# can contain // other #tatic e e!ent#: pu$ ic #tatic *oid f01 ;< #tatic int x 9 "03 #tatic c a## )notherLe*e ; pu$ ic #tatic *oid f01 ;< #tatic int x 9 "03 < < pu$ ic #tatic :e#tination de#t0String #1 ; return ne. -:e#tination0#13 < pu$ ic #tatic Content# cont01 ; return ne. -Content#013 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; Content# c 9 cont013 :e#tination d 9 de#t0&'anMania&13 < < ///:8 -n main( ), n* *34ect *9 !arcel74 i# nece##aryQ in#tead y*u u#e the n*r+al #ynta; 9*r #electing a static +e+3er t* call the +eth*d# that return re9erence# t* Contents and $estination) =# y*u !ill #ee #h*rtly, in an *rdinary Gn*nEstaticH inner cla##, the link t* the *uter cla## *34ect i# achieved !ith a #pecial this re9erence) = static inner cla## d*e# n*t have thi# #pecial this re9erence, !hich +ake# it anal*g*u# t* a static +eth*d) *r+ally y*u cant put any c*de in#ide an interface, 3ut a static inner cla## can 3e part *9 an interface) Since the cla## i# static it d*e#nt vi*late the rule# 9*r inter9ace#Rthe static inner cla## i# *nly placed in#ide the na+e#pace *9 the inter9ace1 //: c0I:55nterface.Da*a // Static inner c a##e# in#ide interface#. pu$ ic interface 55nterface ; #tatic c a## 5nner ; int i2 D2 %3
36#
pu$ ic 5nner01 ;< *oid f01 ;< < < ///:8 Earlier in thi# 3**k - #ugge#ted putting a main( ) in every cla## t* act a# a te#t 3ed 9*r that cla##) One dra!3ack t* thi# i# the a+*unt *9 e;tra c*+piled c*de y*u +u#t carry ar*und) -9 thi# i# a pr*3le+, y*u can u#e a static inner cla## t* h*ld y*ur te#t c*de1 //: c0I:'e#tBed.Da*a // -utting te#t code in a #tatic inner c a##. pu$ ic c a## 'e#tBed ; 'e#tBed01 ;< *oid f01 ; Sy#te!.out.print n0&f01&13 < pu$ ic #tatic c a## 'e#ter ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; 'e#tBed t 9 ne. 'e#tBed013 t.f013 < < < ///:8 Thi# generate# a #eparate cla## called +estBed^+ester Gt* run the pr*gra+, y*u #ay )ava +estBed^+esterH) :*u can u#e thi# cla## 9*r te#ting, 3ut y*u d*nt need t* include it in y*ur #hipping pr*duct)
36&
Thinking in C
www.ThinkingIn.!et
// Creating in#tance# of inner c a##e#. pu$ ic c a## -arce "" ; c a## Content# ; pri*ate int i 9 ""3 pu$ ic int *a ue01 ; return i3 < < c a## :e#tination ; pri*ate String a$e 3 :e#tination0String .here'o1 ; a$e 9 .here'o3 < String readLa$e 01 ; return a$e 3 < < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce "" p 9 ne. -arce ""013 // Gu#t u#e in#tance of outer c a## // to create an in#tance# of the inner c a##: -arce "".Content# c 9 p.ne. Content#013 -arce "".:e#tination d 9 p.ne. :e#tination0&'anMania&13 < < ///:8 T* create an *34ect *9 the inner cla## directly, y*u d*nt 9*ll*! the #a+e 9*r+ and re9er t* the *uter cla## na+e !arcel77 a# y*u +ight e;pect, 3ut in#tead y*u +u#t u#e an o23ect *9 the *uter cla## t* +ake an *34ect *9 the inner cla##1 -arce "".Content# c 9 p.ne. Content#013 Thu#, it# n*t p*##i3le t* create an *34ect *9 the inner cla## unle## y*u already have an *34ect *9 the *uter cla##) Thi# i# 3ecau#e the *34ect *9 the inner cla## i# Duietly c*nnected t* the *34ect *9 the *uter cla## that it !a# +ade 9r*+) H*!ever, i9 y*u +ake a static inner cla##, then it d*e#nt need a re9erence t* the *uter cla## *34ect)
36'
//: c0I:Gu tiCe#ting)cce##.Da*a // Ce#ted c a##e# can acce## a !e!$er# of a // e*e # of the c a##e# they are ne#ted .ithin. c a## GC) ; pri*ate *oid f01 ;< c a## ) ; pri*ate *oid g01 ;< pu$ ic c a## B ; *oid h01 ; g013 f013 < < < < pu$ ic c a## Gu tiCe#ting)cce## ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; GC) !na 9 ne. GC)013 GC).) !naa 9 !na.ne. )013 GC).).B !naa$ 9 !naa.ne. B013 !naa$.h013 < < ///:8 :*u can #ee that in .,'6'6B, the +eth*d# g( ) and f( ) are calla3le !ith*ut any Duali9icati*n Gde#pite the 9act that they are privateH) Thi# e;a+ple al#* de+*n#trate# the #ynta; nece##ary t* create *34ect# *9 +ultiplyEne#ted inner cla##e# !hen y*u create the *34ect# in a di99erent cla##) The I6newJ #ynta; pr*duce# the c*rrect #c*pe #* y*u d* n*t have t* Duali9y the cla## na+e in the c*n#truct*r call)
& Thank# again t* Aartin ?anner)
3#(
Thinking in C
www.ThinkingIn.!et
3#1
3#)
Thinking in C
www.ThinkingIn.!et
Ce. +gg01 +gg./o %01 Thi# e;a+ple #i+ply #h*!# that there i#nt any e;tra inner cla## +agic g*ing *n !hen y*u inherit 9r*+ the *uter cla##) The t!* inner cla##e# are c*+pletely #eparate entitie#, each in their *!n na+e#pace) H*!ever, it# #till p*##i3le t* e;plicitly inherit 9r*+ the inner cla##1 //: c0I:Big+gg2.Da*a // -roper inheritance of an inner c a##. c a## +gg2 ; protected c a## /o % ; pu$ ic /o %01 ; Sy#te!.out.print n0&+gg2./o %01&13 < pu$ ic *oid f01 ; Sy#te!.out.print n0&+gg2./o %.f01&13 < < pri*ate /o % y 9 ne. /o %013 pu$ ic +gg201 ; Sy#te!.out.print n0&Ce. +gg201&13 < pu$ ic *oid in#ert/o %0/o % yy1 ; y 9 yy3 < pu$ ic *oid g01 ; y.f013 < < pu$ ic c a## Big+gg2 extend# +gg2 ; pu$ ic c a## /o % extend# +gg2./o % ; pu$ ic /o %01 ; Sy#te!.out.print n0&Big+gg2./o %01&13 < pu$ ic *oid f01 ; Sy#te!.out.print n0&Big+gg2./o %.f01&13 < < pu$ ic Big+gg201 ; in#ert/o %0ne. /o %0113 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; +gg2 e2 9 ne. Big+gg2013 e2.g013
3#3
< < ///:8 *! Big&gg86@ol( e;plicitly extends &gg86@ol( and *verride# it# +eth*d#) The +eth*d insert@ol(( ) all*!# Big&gg8 t* upca#t *ne *9 it# *!n @ol( *34ect# int* the y re9erence in &gg8, #* !hen g( ) call# y6f( ) the *verridden ver#i*n *9 f( ) i# u#ed) The *utput i#1 +gg2./o %01 Ce. +gg201 +gg2./o %01 Big+gg2./o %01 Big+gg2./o %.f01 The #ec*nd call t* &gg86@ol(( ) i# the 3a#eEcla## c*n#truct*r call *9 the Big&gg86@ol( c*n#truct*r) :*u can #ee that the *verridden ver#i*n *9 f( ) i# u#ed !hen g( ) i# called)
3#4
Thinking in C
www.ThinkingIn.!et
=lth*ugh thi# #che+e *9 generating internal na+e# i# #i+ple and #traight9*r!ard, it# al#* r*3u#t and handle# +*#t #ituati*n# ') Since it i# the #tandard na+ing #che+e 9*r "ava, the generated 9ile# are aut*+atically plat9*r+Eindependent) G *te that the "ava c*+piler i# changing y*ur inner cla##e# in all #*rt# *9 *ther !ay# in *rder t* +ake the+ !*rk)H
tr*u3le !hen li#ting the 6class 9ile#) Thi# i# a 3it #trange c*+ing 9r*+ Sun, a Uni;E3a#ed c*+pany) Ay gue## i# that they !erent c*n#idering thi# i##ue, 3ut in#tead th*ught y*ud naturally 9*cu# *n the #*urceEc*de 9ile#)
3#5
-nter9ace# #*lve part *9 the pr*3le+, 3ut inner cla##e# e99ectively all*! I+ultiple i+ple+entati*n inheritance)J That i#, inner cla##e# e99ectively all*! y*u t* inherit 9r*+ +*re than *ne n*nE interface) T* #ee thi# in +*re detail, c*n#ider a #ituati*n !here y*u have t!* inter9ace# that +u#t #*+eh*! 3e i+ple+ented !ithin a cla##) Becau#e *9 the 9le;i3ility *9 inter9ace#, y*u have t!* ch*ice#1 a #ingle cla## *r an inner cla##1 //: c0I:Gu ti5nterface#.Da*a // '.o .ay# that a c a## can // i!p e!ent !u tip e interface#. interface ) ;< interface B ;< c a## , i!p e!ent# )2 B ;< c a## / i!p e!ent# ) ; B !a%eB01 ; // )nony!ou# inner c a##: return ne. B01 ;<3 < < pu$ ic c a## Gu ti5nterface# ; #tatic *oid ta%e#)0) a1 ;< #tatic *oid ta%e#B0B $1 ;< pu$ ic #tatic *oid !ain0StringJK arg#1 ; , x 9 ne. ,013 / y 9 ne. /013 ta%e#)0x13 ta%e#)0y13 ta%e#B0x13 ta%e#B0y.!a%eB0113 < < ///:8 O9 c*ur#e, thi# a##u+e# that the #tructure *9 y*ur c*de +ake# l*gical #en#e either !ay) H*!ever, y*ull *rdinarily have #*+e kind *9 guidance 9r*+ the nature *9 the pr*3le+ a3*ut !hether t* u#e a #ingle cla## *r an
3#6
Thinking in C
www.ThinkingIn.!et
inner cla##) But !ith*ut any *ther c*n#traint#, in the a3*ve e;a+ple the appr*ach y*u take d*e#nt really +ake +uch di99erence 9r*+ an i+ple+entati*n #tandp*int) B*th *9 the+ !*rk) H*!ever, i9 y*u have abstract *r c*ncrete cla##e# in#tead *9 interface#, y*u are #uddenly li+ited t* u#ing inner cla##e# i9 y*ur cla## +u#t #*+eh*! i+ple+ent 3*th *9 the *ther#1 //: c0I:Gu ti5!p e!entation.Da*a // Vith concrete or a$#tract c a##e#2 inner // c a##e# are the on y .ay to produce the effect // of &!u tip e i!p e!entation inheritance.& c a## C ;< a$#tract c a## : ;< c a## b extend# C ; : !a%e:01 ; return ne. :01 ;<3 < < pu$ ic c a## Gu ti5!p e!entation ; #tatic *oid ta%e#C0C c1 ;< #tatic *oid ta%e#:0: d1 ;< pu$ ic #tatic *oid !ain0StringJK arg#1 ; b M 9 ne. b013 ta%e#C0M13 ta%e#:0M.!a%e:0113 < < ///:8 -9 y*u didnt need t* #*lve the I+ultiple i+ple+entati*n inheritanceJ pr*3le+, y*u c*uld c*nceiva3ly c*de ar*und everything el#e !ith*ut the need 9*r inner cla##e#) But !ith inner cla##e# y*u have the#e additi*nal 9eature#1 1. The inner cla## can have +ultiple in#tance#, each !ith it# *!n #tate in9*r+ati*n that i# independent *9 the in9*r+ati*n in the *uter cla## *34ect)
3##
2.
-n a #ingle *uter cla## y*u can have #everal inner cla##e#, each *9 !hich i+ple+ent the #a+e interface *r inherit 9r*+ the #a+e cla## in a di99erent !ay) =n e;a+ple *9 thi# !ill 3e #h*!n #h*rtly) The p*int *9 creati*n *9 the inner cla## *34ect i# n*t tied t* the creati*n *9 the *uter cla## *34ect) There i# n* p*tentially c*n9u#ing Ii#EaJ relati*n#hip !ith the inner cla##Q it# a #eparate entity)
3. .
=# an e;a+ple, i9 #e%uence6)ava did n*t u#e inner cla##e#, y*ud have t* #ay Ia #e%uence i# a #elector,J and y*ud *nly 3e a3le t* have *ne #elector in e;i#tence 9*r a particular #e%uence) =l#*, y*u can have a #ec*nd +eth*d, get*#elector( ), that pr*duce# a #elector that +*ve# 3ack!ard thr*ugh the #eDuence) Thi# kind *9 9le;i3ility i# *nly availa3le !ith inner cla##e#)
Closures I Call+ac*s
= closure i# a calla3le *34ect that retain# in9*r+ati*n 9r*+ the #c*pe in !hich it !a# created) 5r*+ thi# de9initi*n, y*u can #ee that an inner cla## i# an *34ectE*riented cl*#ure, 3ecau#e it d*e#nt 4u#t c*ntain each piece *9 in9*r+ati*n 9r*+ the *uter cla## *34ect GIthe #c*pe in !hich it !a# createdJH, 3ut it aut*+atically h*ld# a re9erence 3ack t* the !h*le *uter cla## *34ect, !here it ha# per+i##i*n t* +anipulate all the +e+3er#, even private *ne#) One *9 the +*#t c*+pelling argu+ent# +ade t* include #*+e kind *9 p*inter +echani#+ in "ava !a# t* all*! call2acks) ,ith a call3ack, #*+e *ther *34ect i# given a piece *9 in9*r+ati*n that all*!# it t* call 3ack int* the *riginating *34ect at #*+e later p*int) Thi# i# a very p*!er9ul c*ncept, a# y*u !ill #ee in Chapter# 0/ and 0.) -9 a call3ack i# i+ple+ented u#ing a p*inter, h*!ever, y*u +u#t rely *n the pr*gra++er t* 3ehave and n*t +i#u#e the p*inter) =# y*uve #een 3y n*!, "ava tend# t* 3e +*re care9ul than that, #* p*inter# !ere n*t included in the language) The cl*#ure pr*vided 3y the inner cla## i# a per9ect #*luti*nQ +*re 9le;i3le and 9ar #a9er than a p*inter) Here# a #i+ple e;a+ple1 //: c0I:Ca $ac%#.Da*a // O#ing inner c a##e# for ca $ac%#
3#&
Thinking in C
www.ThinkingIn.!et
interface 5ncre!enta$ e ; *oid incre!ent013 < // Nery #i!p e to Du#t i!p e!ent the interface: c a## Ca ee" i!p e!ent# 5ncre!enta$ e ; pri*ate int i 9 03 pu$ ic *oid incre!ent01 ; iRR3 Sy#te!.out.print n0i13 < < c a## Gy5ncre!ent ; pu$ ic *oid incre!ent01 ; Sy#te!.out.print n0&Other operation&13 < pu$ ic #tatic *oid f0Gy5ncre!ent !i1 ; !i.incre!ent013 < < // 5f your c a## !u#t i!p e!ent incre!ent01 in // #o!e other .ay2 you !u#t u#e an inner c a##: c a## Ca ee2 extend# Gy5ncre!ent ; pri*ate int i 9 03 pri*ate *oid incr01 ; iRR3 Sy#te!.out.print n0i13 < pri*ate c a## C o#ure i!p e!ent# 5ncre!enta$ e ; pu$ ic *oid incre!ent01 ; incr013 < < 5ncre!enta$ e getCa $ac%Reference01 ; return ne. C o#ure013 < < c a## Ca er ; pri*ate 5ncre!enta$ e ca $ac%Reference3
3#'
Ca ca
< *oid go01 ; ca $ac%Reference.incre!ent013 < < pu$ ic c a## Ca $ac%# ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; Ca ee" c" 9 ne. Ca ee"013 Ca ee2 c2 9 ne. Ca ee2013 Gy5ncre!ent.f0c213 Ca er ca er" 9 ne. Ca er0c"13 Ca er ca er2 9 ne. Ca er0c2.getCa $ac%Reference0113 ca er".go013 ca er".go013 ca er2.go013 ca er2.go013 < < ///:8 Thi# e;a+ple al#* pr*vide# a 9urther di#tincti*n 3et!een i+ple+enting an inter9ace in an *uter cla## v#) d*ing #* in an inner cla##) Callee7 i# clearly the #i+pler #*luti*n in ter+# *9 the c*de) Callee8 inherit# 9r*+ .yBncrement !hich already ha# a di99erent increment( ) +eth*d !hich d*e# #*+ething unrelated t* that !hich i# e;pected 3y the Bncrementable inter9ace) ,hen .yBncrement i# inherited int* Callee8, increment( ) cant 3e *verridden 9*r u#e 3y Bncrementable, #* y*ure 9*rced t* pr*vide a #eparate i+ple+entati*n u#ing an inner cla##) =l#* n*te that !hen y*u create an inner cla## y*u d* n*t add t* *r +*di9y the inter9ace *9 the *uter cla##) *tice that everything e;cept getCallbac(*eference( ) in Callee8 i# private) T* all*! an4 c*nnecti*n t* the *ut#ide !*rld, the interface Bncrementable i# e##ential) Here y*u can #ee h*! interface# all*! 9*r a c*+plete #eparati*n *9 inter9ace 9r*+ i+ple+entati*n) The inner cla## Closure #i+ply i+ple+ent# Bncrementable t* pr*vide a h**k 3ack int* Callee8R3ut a #a9e h**k) ,h*ever get# the
3&(
Thinking in C
www.ThinkingIn.!et
Bncrementable re9erence can, *9 c*ur#e, *nly call increment( ) and ha# n* *ther a3ilitie# Gunlike a p*inter, !hich !*uld all*! y*u t* run !ildH) Caller take# an Bncrementable re9erence in it# c*n#truct*r Galth*ugh the capturing *9 the call3ack re9erence c*uld happen at any ti+eH and then, #*+eti+e latter, u#e# the re9erence t* Icall 3ackJ int* the Callee cla##) The value *9 the call3ack i# in it# 9le;i3ilityRy*u can dyna+ically decide !hat 9uncti*n# !ill 3e called at runEti+e) The 3ene9it *9 thi# !ill 3ec*+e +*re evident in Chapter 0/, !here call3ack# are u#ed every!here t* i+ple+ent graphical u#er inter9ace G>U-H 9uncti*nality)
3&1
3ehavi*r i# t* per9*r+ the c*ntr*l 3a#ed *n ti+e, #* #*+e *9 the i+ple+entati*n can 3e included here1 //: c0I:contro er:+*ent.Da*a // 'he co!!on !ethod# for any contro pac%age c0I.contro er3 e*ent.
a$#tract pu$ ic c a## +*ent ; pri*ate ong e*t'i!e3 pu$ ic +*ent0 ong e*ent'i!e1 ; e*t'i!e 9 e*ent'i!e3 < pu$ ic $oo ean ready01 ; return Sy#te!.current'i!eGi i#01 Z9 e*t'i!e3 < a$#tract pu$ ic *oid action013 a$#tract pu$ ic String de#cription013 < ///:8 The c*n#truct*r #i+ply capture# the ti+e !hen y*u !ant the &vent t* run, !hile ready( ) tell# y*u !hen it# ti+e t* run it) O9 c*ur#e, ready( ) c*uld 3e *verridden in a derived cla## t* 3a#e the &vent *n #*+ething *ther than ti+e) action( ) i# the +eth*d that# called !hen the &vent i# ready( ), and description( ) give# te;tual in9*r+ati*n a3*ut the &vent) The 9*ll*!ing 9ile c*ntain# the actual c*ntr*l 9ra+e!*rk that +anage# and 9ire# event#) The 9ir#t cla## i# really 4u#t a IhelperJ cla## !h*#e 4*3 i# t* h*ld &vent *34ect#) :*u can replace it !ith any appr*priate c*ntainer, and in Chapter 6 y*ull di#c*ver *ther c*ntainer# that !ill d* the trick !ith*ut reDuiring y*u t* !rite thi# e;tra c*de1 //: c0I:contro er:Contro er.Da*a // ) ong .ith +*ent2 the generic // fra!e.or% for a contro #y#te!#: pac%age c0I.contro er3 // 'hi# i# Du#t a .ay to ho d +*ent o$Dect#. c a## +*entSet ; pri*ate +*entJK e*ent# 9 ne. +*entJ"00K3 pri*ate int index 9 03
3&)
Thinking in C
www.ThinkingIn.!et
pri*ate int next 9 03 pu$ ic *oid add0+*ent e1 ; if0index Z9 e*ent#. ength1 return3 // 05n rea ife2 thro. exception1 e*ent#JindexRRK 9 e3 < pu$ ic +*ent getCext01 ; $oo ean ooped 9 fa #e3 int #tart 9 next3 do ; next 9 0next R "1 [ e*ent#. ength3 // See if it ha# ooped to the $eginning: if0#tart 99 next1 ooped 9 true3 // 5f it oop# pa#t #tart2 the i#t // i# e!pty: if00next 99 0#tart R "1 [ e*ent#. ength1 @@ ooped1 return nu 3 < .hi e0e*ent#JnextK 99 nu 13 return e*ent#JnextK3 < pu$ ic *oid re!o*eCurrent01 ; e*ent#JnextK 9 nu 3 < < pu$ ic c a## Contro er ; pri*ate +*entSet e# 9 ne. +*entSet013 pu$ ic *oid add+*ent0+*ent c1 ; e#.add0c13 < pu$ ic *oid run01 ; +*ent e3 .hi e00e 9 e#.getCext011 !9 nu 1 ; if0e.ready011 ; e.action013 Sy#te!.out.print n0e.de#cription0113 e#.re!o*eCurrent013 < < < < ///:8
3&3
&vent#et ar3itrarily h*ld# 0$$ &vent#) G-9 a IrealJ c*ntainer 9r*+ Chapter 6 i# u#ed here y*u d*nt need t* !*rry a3*ut it# +a;i+u+ #i7e, #ince it !ill re#i7e it#el9H) The index i# u#ed t* keep track *9 the ne;t availa3le #pace, and next i# u#ed !hen y*ure l**king 9*r the ne;t &vent in the li#t, t* #ee !hether y*uve l**ped ar*und) Thi# i# i+p*rtant during a call t* get,ext( ), 3ecau#e &vent *34ect# are re+*ved 9r*+ the li#t Gu#ing removeCurrent( )H *nce theyre run, #* get,ext( ) !ill enc*unter h*le# in the li#t a# it +*ve# thr*ugh it) *te that removeCurrent( ) d*e#nt 4u#t #et #*+e 9lag indicating that the *34ect i# n* l*nger in u#e) -n#tead, it #et# the re9erence t* null) Thi# i# i+p*rtant 3ecau#e i9 the gar3age c*llect*r #ee# a re9erence that# #till in u#e then it cant clean up the *34ect) -9 y*u think y*ur re9erence# +ight hang ar*und Ga# they !*uld hereH, then it# a g**d idea t* #et the+ t* null t* give the gar3age c*llect*r per+i##i*n t* clean the+ up) Controller i# !here the actual !*rk g*e# *n) -t u#e# an &vent#et t* h*ld it# &vent *34ect#, and add&vent( ) all*!# y*u t* add ne! event# t* thi# li#t) But the i+p*rtant +eth*d i# run( )) Thi# +eth*d l**p# thr*ugh the &vent#et, hunting 9*r an &vent *34ect that# ready( ) t* run) 5*r each *ne it 9ind# ready( ), it call# the action( ) +eth*d, print# *ut the description( ), and then re+*ve# the &vent 9r*+ the li#t) *te that #* 9ar in thi# de#ign y*u kn*! n*thing a3*ut e;actly what an &vent d*e#) =nd thi# i# the cru; *9 the de#ignQ h*! it I#eparate# the thing# that change 9r*+ the thing# that #tay the #a+e)J Or, t* u#e +y ter+, the Ivect*r *9 changeJ i# the di99erent acti*n# *9 the vari*u# kind# *9 &vent *34ect#, and y*u e;pre## di99erent acti*n# 3y creating di99erent &vent #u3cla##e# Gin Cesign /atterns parlance, the &vent #u3cla##e# repre#ent the Command /atternH) Thi# i# !here inner cla##e# c*+e int* play) They all*! t!* thing#1 1. T* create the entire i+ple+entati*n *9 a c*ntr*lE9ra+e!*rk applicati*n in a #ingle cla##, there3y encap#ulating everything that# uniDue a3*ut that i+ple+entati*n) -nner cla##e# are u#ed t* e;pre## the +any di99erent kind# *9 action( ) nece##ary t* #*lve the pr*3le+) -n additi*n, the 9*ll*!ing e;a+ple u#e# private inner cla##e# #* the i+ple+entati*n i# c*+pletely hidden and can 3e changed !ith i+punity)
3&4
Thinking in C
www.ThinkingIn.!et
2.
-nner cla##e# keep thi# i+ple+entati*n 9r*+ 3ec*+ing a!k!ard, #ince y*ure a3le t* ea#ily acce## any *9 the +e+3er# in the *uter cla##) ,ith*ut thi# a3ility the c*de +ight 3ec*+e unplea#ant en*ugh that y*ud end up #eeking an alternative)
C*n#ider a particular i+ple+entati*n *9 the c*ntr*l 9ra+e!*rk de#igned t* c*ntr*l greenh*u#e 9uncti*n#.) Each acti*n i# entirely di99erent1 turning light#, !ater, and ther+*#tat# *n and *99, ringing 3ell#, and re#tarting the #y#te+) But the c*ntr*l 9ra+e!*rk i# de#igned t* ea#ily i#*late thi# di99erent c*de) -nner cla##e# all*! y*u t* have +ultiple derived ver#i*n# *9 the #a+e 3a#e cla##, &vent, !ithin a #ingle cla##) 5*r each type *9 acti*n y*u inherit a ne! &vent inner cla##, and !rite the c*ntr*l c*de in#ide *9 action( )) =# i# typical !ith an applicati*n 9ra+e!*rk, the cla## reenhouseControls i# inherited 9r*+ Controller1 //: c0I:_reenhou#eContro #.Da*a // 'hi# produce# a #pecific app ication of the // contro #y#te!2 a in a #ing e c a##. 5nner // c a##e# a o. you to encap#u ate different // functiona ity for each type of e*ent. i!port c0I.contro er.=3 pu$ ic c a## _reenhou#eContro # extend# Contro er ; pri*ate $oo ean ight 9 fa #e3 pri*ate $oo ean .ater 9 fa #e3 pri*ate String ther!o#tat 9 &:ay&3 pri*ate c a## LightOn extend# +*ent ; pu$ ic LightOn0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // -ut hard.are contro code here to // phy#ica y turn on the ight. ight 9 true3 < pu$ ic String de#cription01 ;
. 5*r #*+e rea#*n thi# ha# al!ay# 3een a plea#ing pr*3le+ 9*r +e t* #*lveQ it ca+e 9r*+
+y earlier 3**k C++ Inside = 1ut, 3ut "ava all*!# a +uch +*re elegant #*luti*n)
3&5
return &Light i# on&3 < < pri*ate c a## LightOff extend# +*ent ; pu$ ic LightOff0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // -ut hard.are contro code here to // phy#ica y turn off the ight. ight 9 fa #e3 < pu$ ic String de#cription01 ; return &Light i# off&3 < < pri*ate c a## VaterOn extend# +*ent ; pu$ ic VaterOn0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // -ut hard.are contro code here .ater 9 true3 < pu$ ic String de#cription01 ; return &_reenhou#e .ater i# on&3 < < pri*ate c a## VaterOff extend# +*ent ; pu$ ic VaterOff0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // -ut hard.are contro code here .ater 9 fa #e3 < pu$ ic String de#cription01 ; return &_reenhou#e .ater i# off&3 < < pri*ate c a## 'her!o#tatCight extend# +*ent ;
3&6
Thinking in C
www.ThinkingIn.!et
pu$ ic 'her!o#tatCight0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // -ut hard.are contro code here ther!o#tat 9 &Cight&3 < pu$ ic String de#cription01 ; return &'her!o#tat on night #etting&3 < < pri*ate c a## 'her!o#tat:ay extend# +*ent ; pu$ ic 'her!o#tat:ay0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // -ut hard.are contro code here ther!o#tat 9 &:ay&3 < pu$ ic String de#cription01 ; return &'her!o#tat on day #etting&3 < < // )n exa!p e of an action01 that in#ert# a // ne. one of it#e f into the e*ent i#t: pri*ate int ring#3 pri*ate c a## Be extend# +*ent ; pu$ ic Be 0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // Ring e*ery 2 #econd#2 'ring#' ti!e#: Sy#te!.out.print n0&Bing!&13 if066ring# Z 01 add+*ent0ne. Be 0 Sy#te!.current'i!eGi i#01 R 2000113 < pu$ ic String de#cription01 ; return &Ring $e &3 < <
3&#
pri*ate c a## Re#tart extend# +*ent ; pu$ ic Re#tart0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; ong t! 9 Sy#te!.current'i!eGi i#013 // 5n#tead of hard6.iring2 you cou d par#e // configuration infor!ation fro! a text // fi e here: ring# 9 P3 add+*ent0ne. 'her!o#tatCight0t!113 add+*ent0ne. LightOn0t! R "000113 add+*ent0ne. LightOff0t! R 2000113 add+*ent0ne. VaterOn0t! R T000113 add+*ent0ne. VaterOff0t! R I000113 add+*ent0ne. Be 0t! R >000113 add+*ent0ne. 'her!o#tat:ay0t! R "0000113 // Can e*en add a Re#tart o$Dect! add+*ent0ne. Re#tart0t! R 20000113 < pu$ ic String de#cription01 ; return &Re#tarting #y#te!&3 < < pu$ ic #tatic *oid !ain0StringJK arg#1 ; _reenhou#eContro # gc 9 ne. _reenhou#eContro #013 ong t! 9 Sy#te!.current'i!eGi i#013 gc.add+*ent0gc.ne. Re#tart0t!113 gc.run013 < < ///:8 *te that light, water, thermostat, and rings all 3el*ng t* the *uter cla## reenhouseControls, and yet the inner cla##e# can acce## th*#e 9ield# !ith*ut Duali9icati*n *r #pecial per+i##i*n) =l#*, +*#t *9 the action( ) +eth*d# inv*lve #*+e #*rt *9 hard!are c*ntr*l, !hich !*uld +*#t likely inv*lve call# t* n*nE"ava c*de) A*#t *9 the &vent cla##e# l**k #i+ilar, 3ut Bell and *estart are #pecial) Bell ring#, and i9 it ha#nt yet rung en*ugh ti+e# it add# a ne! Bell *34ect
3&&
Thinking in C
www.ThinkingIn.!et
t* the event li#t, #* it !ill ring again later) *tice h*! inner cla##e# almost l**k like +ultiple inheritance1 Bell ha# all the +eth*d# *9 &vent and it al#* appear# t* have all the +eth*d# *9 the *uter cla## reenhouseControls) *estart i# re#p*n#i3le 9*r initiali7ing the #y#te+, #* it add# all the appr*priate event#) O9 c*ur#e, a +*re 9le;i3le !ay t* acc*+pli#h thi# i# t* av*id hardEc*ding the event# and in#tead read the+ 9r*+ a 9ile) G=n e;erci#e in Chapter 00 a#k# y*u t* +*di9y thi# e;a+ple t* d* 4u#t that)H Since *estart( ) i# 4u#t an*ther &vent *34ect, y*u can al#* add a *estart *34ect !ithin *estart6action( ) #* that the #y#te+ regularly re#tart# it#el9) =nd all y*u need t* d* in main( ) i# create a reenhouseControls *34ect and add a *estart *34ect t* get it g*ing) 'hi# exa!p e #hou d !o*e you a ong .ay to.ard appreciating the *a ue of inner c a##e#2 e#pecia y .hen u#ed .ithin a contro fra!e.or%. Uo.e*er2 in Chapter "T you4 #ee ho. e egant y inner c a##e# are u#ed to de#cri$e the action# of a graphica u#er interface. By the ti!e you fini#h that chapter you #hou d $e fu y con*inced.
'u##ar5
-nter9ace# and inner cla##e# are +*re #*phi#ticated c*ncept# than !hat y*ull 9ind in +any OOP language#) 5*r e;a+ple, there# n*thing like the+ in C@@) T*gether, they #*lve the #a+e pr*3le+ that C@@ atte+pt# t* #*lve !ith it# +ultiple inheritance GA-H 9eature) H*!ever, A- in C@@ turn# *ut t* 3e rather di99icult t* u#e, !hile "ava inter9ace# and inner cla##e# are, 3y c*+pari#*n, +uch +*re acce##i3le) =lth*ugh the 9eature# the+#elve# are rea#*na3ly #traight9*r!ard, the u#e *9 the#e 9eature# i# a de#ign i##ue, +uch the #a+e a# p*ly+*rphi#+) Over ti+e, y*ull 3ec*+e 3etter at rec*gni7ing #ituati*n# !here y*u #h*uld u#e an inter9ace, *r an inner cla##, *r 3*th) But at thi# p*int in thi# 3**k y*u #h*uld at lea#t 3e c*+9*rta3le !ith the #ynta; and #e+antic#) =# y*u #ee the#e language 9eature# in u#e y*ull eventually internali7e the+)
3&'
%&ercises
S*luti*n# t* #elected e;erci#e# can 3e 9*und in the electr*nic d*cu+ent The Thinking in ,a-a 5nnotated @olution Duide, availa3le 9*r a #+all 9ee 9r*+ www.BruceEckel.com)
1. 2. 3. .
Pr*ve that the 9ield# in an interface are i+plicitly static and final) Create an interface c*ntaining three +eth*d#, in it# *!n pac(age) -+ple+ent the inter9ace in a di99erent pac(age) Pr*ve that all the +eth*d# in an interface are aut*+atically public) -n c4SD#andwich6)ava, create an inter9ace called :ast:ood G!ith appr*priate +eth*d#H and change #andwich #* that it al#* i+ple+ent# :ast:ood) Create three interface#, each !ith t!* +eth*d#) -nherit a ne! interface 9r*+ the three, adding a ne! +eth*d) Create a cla## 3y i+ple+enting the ne! interface and al#* inheriting 9r*+ a c*ncrete cla##) *! !rite 9*ur +eth*d#, each *9 !hich take# *ne *9 the 9*ur interface# a# an argu+ent) -n main( ), create an *34ect *9 y*ur cla## and pa## it t* each *9 the +eth*d#) A*di9y E;erci#e ' 3y creating an abstract cla## and inheriting that int* the derived cla##) A*di9y .usicY6)ava 3y adding a !layable interface) A*ve the play( ) declarati*n 9r*+ Bnstrument t* !layable) =dd !layable t* the derived cla##e# 3y including it in the implements li#t) Change tune( ) #* that it take# a !layable in#tead *9 an Bnstrument) Change E;erci#e . in Chapter % #* that *odent i# an interface) -n 'dventure6)ava, add an interface called CanClimb, 9*ll*!ing the 9*r+ *9 the *ther inter9ace#) ,rite a pr*gra+ that i+p*rt# and u#e# .onth86)ava)
!.
". C.
D. E. 1F.
3'(
Thinking in C
www.ThinkingIn.!et
11. 12.
5*ll*!ing the e;a+ple given in .onth86)ava, create an enu+erati*n *9 day# *9 the !eek) Create an interface !ith at lea#t *ne +eth*d, in it# *!n package) Create a cla## in a #eparate package) =dd a protected inner cla## that i+ple+ent# the interface) -n a third package, inherit 9r*+ y*ur cla## and, in#ide a +eth*d, return an *34ect *9 the protected inner cla##, upca#ting t* the interface during the return) Create an interface !ith at lea#t *ne +eth*d, and i+ple+ent that interface 3y de9ining an inner cla## !ithin a +eth*d, !hich return# a re9erence t* y*ur interface) Repeat E;erci#e 0/ 3ut de9ine the inner cla## !ithin a #c*pe !ithin a +eth*d) Repeat E;erci#e 0/ u#ing an an*ny+*u# inner cla##) Create a private inner cla## that i+ple+ent# a public interface) ,rite a +eth*d that return# a re9erence t* an in#tance *9 the private inner cla##, upca#t t* the interface) Sh*! that the inner cla## i# c*+pletely hidden 3y trying t* d*!nca#t t* it) Create a cla## !ith a n*nde9ault c*n#truct*r and n* de9ault c*n#truct*r) Create a #ec*nd cla## that ha# a +eth*d !hich return# a re9erence t* the 9ir#t cla##) Create the *34ect t* return 3y +aking an an*ny+*u# inner cla## that inherit# 9r*+ the 9ir#t cla##) Create a cla## !ith a private 9ield and a private +eth*d) Create an inner cla## !ith a +eth*d that +*di9ie# the *uter cla## 9ield and call# the *uter cla## +eth*d) -n a #ec*nd *uter cla## +eth*d, create an *34ect *9 the inner cla## and call it# +eth*d, then #h*! the e99ect *n the *uter cla## *34ect) Repeat E;erci#e 0( u#ing an an*ny+*u# inner cla##) Create a cla## c*ntaining a static inner cla##) -n main( ), create an in#tance *9 the inner cla##) Create an interface c*ntaining a static inner cla##) -+ple+ent thi# interface and create an in#tance *9 the inner cla##)
13.
1 . 1!. 1".
1C.
1D.
3'1
22.
Create a cla## c*ntaining an inner cla## that it#el9 c*ntain# an inner cla##) Repeat thi# u#ing static inner cla##e#) *te the na+e# *9 the 6class 9ile# pr*duced 3y the c*+piler) Create a cla## !ith an inner cla##) -n a #eparate cla##, +ake an in#tance *9 the inner cla##) Create a cla## !ith an inner cla## that ha# a n*nde9ault c*n#truct*r) Create a #ec*nd cla## !ith an inner cla## that inherit# 9r*+ the 9ir#t inner cla##) Repair the pr*3le+ in =ind&rror6)ava) A*di9y #e%uence6)ava 3y adding a +eth*d get*#elector( ) that pr*duce# a di99erent i+ple+entati*n *9 the #elector interface that +*ve# 3ack!ard thr*ugh the #eDuence 9r*+ the end t* the 3eginning) Create an interface V !ith three +eth*d#) Create a cla## ' !ith a +eth*d that pr*duce# a re9erence t* a V 3y 3uilding an an*ny+*u# inner cla##) Create a #ec*nd cla## B that c*ntain# an array *9 V) B #h*uld have *ne +eth*d that accept# and #t*re# a re9erence t* a V in the array, a #ec*nd +eth*d that #et# a re9erence in the array G#peci9ied 3y the +eth*d argu+entH t* null and a third +eth*d that +*ve# thr*ugh the array and call# the +eth*d# in V) -n main( ), create a gr*up *9 ' *34ect# and a #ingle B) 5ill the B !ith V re9erence# pr*duced 3y the ' *34ect#) U#e the B t* call 3ack int* all the ' *34ect#) Re+*ve #*+e *9 the V re9erence# 9r*+ the B) -n reenhouseControls6)ava, add &vent inner cla##e# that turn 9an# *n and *99) Sh*! that an inner cla## ha# acce## t* the private ele+ent# *9 it# *uter cla##) ?eter+ine !hether the rever#e i# true)
23. 2 .
2!. 2".
2C.
2D. 2E.
3')
Thinking in C
www.ThinkingIn.!et
3'3
classesH) C*ntainer# pr*vide #*phi#ticated !ay# t* h*ld and +anipulate y*ur *34ect#) C*ntainer# *pen the d**r t* the !*rld *9 c*+puting !ith data #tructure#, !here a+a7ing re#ult# can 3e achieved 3y +anipulating the a3#tract ge*+etry *9 tree#, vect*r #pace#, and hyperplane#) ,hile data #tructure pr*gra++ing lie# *ut#ide *9 the !*rkaday !*rld *9 +*#t pr*gra++er#, it i# very i+p*rtant in #cienti9ic, graphic, and ga+e pr*gra++ing)
)rra5s
A*#t *9 the nece##ary intr*ducti*n t* array# !a# c*vered in Chapter #initiali7ati*n and cleanup#, !hich #h*!ed h*! y*u de9ine and initiali7e an array) H*lding *34ect# i# the 9*cu# *9 thi# chapter, and an array i# 4u#t *ne !ay t* h*ld *34ect#) But there are a nu+3er *9 *ther !ay# t* h*ld *34ect#, #* !hat +ake# an array #pecialF There are t!* i##ue# that di#tingui#h array# 9r*+ *ther type# *9 c*ntainer#1 e99iciency and type) The array i# the +*#t e99icient !ay that C# pr*vide# t* #t*re and rand*+ly acce## a #eDuence *9 *34ect# Gactually, *34ect re9erence#H) The array i# a #i+ple linear #eDuence, !hich +ake# ele+ent acce## 9a#t, 3ut y*u pay 9*r thi# #peed1 !hen y*u create an array *34ect, it# #i7e i# 9i;ed and cann*t 3e changed 9*r the li9eti+e *9 that array *34ect) :*u +ight #ugge#t creating an array *9 a particular #i7e and then, i9 y*u run *ut *9 #pace, creating a ne! *ne and +*ving all the re9erence# 9r*+ the *ld *ne t* the ne! *ne) Thi# i# the 3ehavi*r *9 the 'rrayList
3'4
cla##, !hich !ill 3e #tudied later in thi# chapter) H*!ever, 3ecau#e *9 the *verhead *9 thi# #i7e 9le;i3ility, an 'rrayList i# +ea#ura3ly le## e99icient than an array) The vector c*ntainer cla## in C@@ does kn*! the type *9 *34ect# it h*ld#, 3ut it ha# a di99erent dra!3ack !hen c*+pared !ith array# in C#1 the C@@ vector# operator<> d*e#nt d* 3*und# checking, #* y*u can run pa#t the end0) -n C#, y*u get 3*und# checking regardle## *9 !hether y*ure u#ing an array *r a c*ntainerRy*ull get an Bndex1ut1f*ange&xception i9 y*u e;ceed the 3*und#) =# y*ull learn in Chapter #E;cepti*n##, thi# type *9 e;cepti*n indicate# a pr*gra++er err*r, and thu# y*u d*nt need t* check 9*r it in y*ur c*de) =# an a#ide, the rea#*n the C@@ vector d*e#nt check 3*und# !ith every acce## i# #peedRin C# y*u have the per9*r+ance *verhead *9 3*und# checking all the ti+e 9*r 3*th array# and c*ntainer#) The *ther generic c*ntainer cla##e# that !ill 3e #tudied in thi# chapter, BCollection3 BList and B$ictionary, all deal !ith *34ect# a# i9 they had n* #peci9ic type) That i#, they treat the+ a# type ob)ect, the r**t cla## *9 all cla##e# in C#) Thi# !*rk# 9ine 9r*+ *ne #tandp*int1 y*u need t* 3uild *nly *ne c*ntainer, and any C# *34ect !ill g* int* that c*ntainer) Thi# i# the #ec*nd place !here an array i# #uperi*r t* the generic c*ntainer#1 !hen y*u create an array, y*u create it t* h*ld a #peci9ic type) Thi# +ean# that y*u get c*+pileEti+e type checking t* prevent y*u 9r*+ putting the !r*ng type in, *r +i#taking the type that y*ure e;tracting) O9 c*ur#e, C# !ill prevent y*u 9r*+ #ending an inappr*priate +e##age t* an *34ect, either at c*+pileEti+e *r at runEti+e) S* it# n*t +uch ri#kier *ne !ay *r the *ther, it# 4u#t nicer i9 the c*+piler p*int# it *ut t* y*u, 9a#ter at runE ti+e, and there# le## likelih**d that the end u#er !ill get #urpri#ed 3y an e;cepti*n) Typed generic cla##e# G#*+eti+e# called Ipara+eteri7ed type#J and #*+eti+e# 4u#t Igeneric#JH are n*t part *9 the initial ) ET 9ra+e!*rk 3ut !ill 3e) Unlike C@@# te+plate# *r "ava# pr*p*#ed e;ten#i*n#, Aicr*#*9t !i#he# t* i+ple+ent #upp*rt 9*r Ipara+etric p*ly+*rphi#+J !ithin the C*++*n Language Runti+e it#el9) ?*n Sy+e and =ndre! Nennedy *9 Aicr*#*9t# Ca+3ridge GEnglandH Re#earch La3 pu3li#hed paper# in
0 -t# p*##i3le, h*!ever, t* a#k h*! 3ig the vector i#, and the at( ) +eth*d does per9*r+
3*und# checking)
3'5
Spring 2$$0 *n a pr*p*#ed #trategy and =nder# H4el#3erg hinted at C## Spring 2$$2 launch that i+ple+entati*n !a# !ell under !ay) 5*r the +*+ent, th*ugh, e99iciency and type checking #ugge#t u#ing an array i9 y*u can) H*!ever, !hen y*ure trying t* #*lve a +*re general pr*3le+ array# can 3e t** re#trictive) =9ter l**king at array#, the re#t *9 thi# chapter !ill 3e dev*ted t* the c*ntainer cla##e# pr*vided 3y C#)
pu$ ic c a## )rraySiMe ; pu$ ic #tatic *oid Gain01 ; // )rray# of o$Dect#: Vee$ eJK a3 // Cu reference Vee$ eJK $ 9 ne. Vee$ eJPK3 // Cu reference# Vee$ eJ2K c 9 ne. Vee$ eJ22 TK3 //Rectangu ar array
3'6
Thinking in C
www.ThinkingIn.!et
Vee$ eJK d 9 ne. Vee$ eJEK3 for0int index 9 03 index W d.Length3 indexRR1 dJindexK 9 ne. Vee$ e013 // )ggregate initia iMation: Vee$ eJK e 9 ; ne. Vee$ e012 ne. Vee$ e012 ne. Vee$ e01 <3 // :yna!ic aggregate initia iMation: a 9 ne. Vee$ eJK ; ne. Vee$ e012 ne. Vee$ e01 <3 // S7uare dyna!ic aggregate initia iMation: c 9 ne. Vee$ eJ2K ; ; ne. Vee$ e012 ne. Vee$ e012 ne. Vee$ e01 <2 ; ne. Vee$ e012 ne. Vee$ e012 ne. Vee$ e01 < <3 Sy#te!.Con#o e.VriteLine0&a.Length9& R a.Length13 Sy#te!.Con#o e.VriteLine0&$.Length 9 & R $.Length13 Sy#te!.Con#o e.VriteLine0&c.Length 9 & R c.Length13 for0int ran% 9 03 ran% W c.Ran%3 ran%RR1; Sy#te!.Con#o e.VriteLine0 &c.LengthJ;0<K 9 ;"<&2 ran%2 c._etLength0ran%113 < // 'he reference# in#ide the array are // auto!atica y initia iMed to nu : for0int index 9 03 index W $.Length3 indexRR1 Sy#te!.Con#o e.VriteLine0&$J& R index R &K9& R $JindexK13 Sy#te!.Con#o e.VriteLine0&d.Length 9 & R d.Length13 Sy#te!.Con#o e.VriteLine0&d.Length 9 & R d.Length13 a 9 d3 Sy#te!.Con#o e.VriteLine0&a.Length 9 & R a.Length13 // )rray# of pri!iti*e#:
3'#
intJK f3 // Cu reference intJK g 9 ne. intJPK3 intJK h 9 ne. intJEK3 for0int index 9 03 index W h.Length3 indexRR1 hJindexK 9 index=index3 intJK i 9 ; ""2 EF2 >T <3 // Co!pi e error: O#e of una##igned oca *aria$ e 'f' //!Sy#te!.Con#o e.VriteLine0&f.Length9& R f.Length13 Sy#te!.Con#o e.VriteLine0&g.Length 9 & R g.Length13 // 'he pri!iti*e# in#ide the array are // auto!atica y initia iMed to Mero: for0int index 9 03 index W g.Length3 indexRR1 Sy#te!.Con#o e.VriteLine0&gJ& R index R &K9& R gJindexK13 Sy#te!.Con#o e.VriteLine0&h.Length 9 & R h.Length13 Sy#te!.Con#o e.VriteLine0&i.Length 9 & R i.Length13 f 9 i3 Sy#te!.Con#o e.VriteLine0&f.Length 9 & R f.Length13 f 9 ne. intJK ; "2 2 <3 Sy#te!.Con#o e.VriteLine0&f.Length 9 & R f.Length13 < < ///:8 Here# the *utput 9r*+ the pr*gra+1 a.Length92 $.Length 9 P c.Length 9 ? c.LengthJ0K 9 2 c.LengthJ"K 9 T $J0K9 $J"K9 $J2K9 $JTK9 $JEK9
3'&
Thinking in C
www.ThinkingIn.!et
d.Length 9 E d.Length 9 E a.Length 9 E g.Length 9 P gJ0K90 gJ"K90 gJ2K90 gJTK90 gJEK90 h.Length 9 E i.Length 9 T f.Length 9 T f.Length 9 2 The array a i# initially 4u#t a null re9erence, and the c*+piler prevent# y*u 9r*+ d*ing anything !ith thi# re9erence until y*uve pr*perly initiali7ed it) The array b i# initiali7ed t* p*int t* an array *9 =eeble re9erence#, 3ut n* actual =eeble *34ect# are ever placed in that array) H*!ever, y*u can #till a#k !hat the #i7e *9 the array i#, #ince b i# p*inting t* a legiti+ate *34ect) Thi# 3ring# up a #light dra!3ack1 y*u cant 9ind *ut h*! +any ele+ent# are actually in the array, #ince Length tell# y*u *nly h*! +any ele+ent# can 3e placed in the arrayQ that i#, the #i7e *9 the array *34ect, n*t the nu+3er *9 ele+ent# it actually h*ld#) H*!ever, !hen an array *34ect i# created it# re9erence# are aut*+atically initiali7ed t* null, #* y*u can #ee !hether a particular array #l*t ha# an *34ect in it 3y checking t* #ee !hether it# null) Si+ilarly, an array *9 pri+itive# i# aut*+atically initiali7ed t* 7er* 9*r nu+eric type#, (char)4 9*r char, and false 9*r bool) =rray c #h*!# the creati*n *9 the array *34ect 9*ll*!ed 3y the a##ign+ent *9 =eeble *34ect# t* all the #l*t# in the array) =rray d #h*!# the Iaggregate initiali7ati*nJ #ynta; that cau#e# the array *34ect t* 3e created Gi+plicitly !ith new *n the heap, 4u#t like 9*r array cH and initiali7ed !ith =eeble *34ect#, all in *ne #tate+ent) The ne;t array initiali7ati*n c*uld 3e th*ught *9 a# a Idyna+ic aggregate initiali7ati*n)J The aggregate initiali7ati*n u#ed 3y d +u#t 3e u#ed at the p*int *9 d# de9initi*n, 3ut !ith the #ec*nd #ynta; y*u can create and initiali7e an array *34ect any!here) 5*r e;a+ple, #upp*#e "ide() i# a +eth*d that take# an array *9 =eeble *34ect#) :*u c*uld call it 3y #aying1
3''
Uide0d13 3ut y*u can al#* dyna+ically create the array y*u !ant t* pa## a# the argu+ent1 Uide0ne. Vee$ eJK ; ne. Vee$ e012 ne. Vee$ e01 <13 -n #*+e #ituati*n# thi# ne! #ynta; pr*vide# a +*re c*nvenient !ay t* !rite c*de) Rectangular array# are initiali7ed u#ing ne#ted array#) =lth*ugh a rectangular array i# c*ntigu*u# in +e+*ry, C## c*+piler !ill n*t all*! y*u t* ign*re the di+en#i*n#Q y*u cann*t ca#t a 9lat array int* a rectangular array *r initiali7e a rectangular array in a I9latJ +anner) The e;pre##i*n1 a 9 d3 #h*!# h*! y*u can take a re9erence that# attached t* *ne array *34ect and a##ign it t* an*ther array *34ect, 4u#t a# y*u can d* !ith any *ther type *9 *34ect re9erence) *! 3*th a and d are p*inting t* the #a+e array *34ect *n the heap) The #ec*nd part *9 'rray#iTe6cs #h*!# that pri+itive array# !*rk 4u#t like *34ect array# e%ce"t that pri+itive array# h*ld the pri+itive value# directly)
4((
Thinking in C
www.ThinkingIn.!et
IEnumerable ICloneable
ICollection
IList
Array
The 'rray cla## ha# #*+e pr*pertie# inherited 9r*+ BCollection that are the #a+e 9*r all in#tance#1 Bs:ixed#iTe i# al!ay# true, Bs*ead1nly and Bs#ynchroniTed are al!ay# false6
4(1
< < c a## )rrayStatic# ; #tatic #tringJK dayLi#t 9 ne. #tringJK; &#unday&2 &!onday&2 &tue#day&2 &.edne#day&2 &thur#day&2 &friday&2 &#aturday& <3 #tatic #tringJ2K fa!ou#Coup e# 9 ne. #tringJ2K; ; &_eorge&2 &Gartha&<2 ; &Capo ean&2 &`o#ephine&<2 ; &Ve#t ey&2&Buttercup&< <3 #tatic Vee$ eJK .ee$ eLi#t 9 ne. Vee$ eJK; ne. Vee$ e0&-i ot&12 ne. Vee$ e0&Hirefighter&1 <3 pu$ ic #tatic *oid Gain01 ; //Copying array# Vee$ eJK ne.Li#t 9 ne. Vee$ eJ.ee$ eLi#t.LengthK3 )rray.Copy0.ee$ eLi#t2 ne.Li#t2 .ee$ eLi#t.Length13 ne.Li#tJ0K 9 ne. Vee$ e0&Cur#e&13 $oo ne.Reference# 9 ne.Li#tJ0K !9 .ee$ eLi#tJ0K3 Sy#te!.Con#o e.VriteLine0&Ce. reference# 99 R ne.Reference#13 //Copying a rectangu ar array .or%# #tringJ2K ne.S7uare)rray 9 ne. #tringJfa!ou#Coup e#._etLength0012 fa!ou#Coup e#._etLength0"1K3 )rray.Copy0fa!ou#Coup e#2 ne.S7uare)rray2 fa!ou#Coup e#.Length13 //5n6p ace #orting #tringJK #orted:ay# 9 ne. #tringJdayLi#t.LengthK3 )rray.Copy0dayLi#t2 #orted:ay#2 dayLi#t.Length13 )rray.Sort0#orted:ay#13
&
4()
Thinking in C
www.ThinkingIn.!et
for 0int i 9 03 i W #orted:ay#.Length3 iRR1 ; Sy#te!.Con#o e.VriteLine0&#orted:ay#J;0<K 9 ;"<&2 i2 #orted:ay#JiK13 < //Binary #earch of #orted "6: )rray int tue#day5ndex 9 )rray.BinarySearch0#orted:ay#2 &tue#day&13 Sy#te!.Con#o e.VriteLine0&dayLi#tJ;0<K 99 ^&tue#day^&&2 tue#day5ndex13 //! int george5ndex 9 )rray.BinarySearch0fa!ou#Coup e#2 &_eorge&<3 W6 Co!pi e error //Re*er#e )rray.Re*er#e0#orted:ay#13 for 0int i 9 03 i W #orted:ay#.Length3 iRR1 ; Sy#te!.Con#o e.VriteLine0&Re*er#ed #orted:ay#J;0<K 9 ;"<&2 i2 #orted:ay#JiK13 < //Quic% y era#ing an array #ection2 e*en if !u tidi!en#iona )rray.C ear0fa!ou#Coup e#2 22 T13 for 0int x 9 03 x W fa!ou#Coup e#._etLength0013 xRR1 for 0int y 9 03 y W fa!ou#Coup e#._etLength0"13 yRR1 Sy#te!.Con#o e.VriteLine0&Ha!ou#Coup e#J;0<2;"<K 9 ;2<&2 x2 y2 fa!ou#Coup e#Jx2yK13 < <///:8 =9ter declaring a ,ee3le cla## Gthi# ti+e !ith a a+e pr*perty t* +ake the+ ea#ier t* di#tingui#hH, the 'rray#tatics cla## declare# #everal #tatic array# P dayList and weebleList, !hich are 3*th *neEdi+en#i*nal, and the #Duare famousCouples array) 'rray6CopyGH pr*vide# a 9a#t !ay t* c*py an array G*r a p*rti*n *9 itH) The ne! array c*ntain# all ne! re9erence#, #* changing a value in y*ur ne! li#t !ill n*t change the value in y*ur *riginal, a# !*uld 3e the ca#e i9 y*u did1
4(3
Vee$ eJK ne.Li#t 9 .ee$ eLi#t3 ne.Li#tJ0K 9 ne. Vee$ e0&Cur#e&13 'rray6Copy() !*rk# !ith +ultidi+en#i*nal array#, t**) The pr*gra+ u#e# the etLength(int) +eth*d t* all*cate #u99icient #t*rage 9*r the new#%uare'rray, 3ut then u#e# the famousCouples6Length pr*perty t* #peci9y the #i7e *9 the c*py) =lth*ugh Copy() #ee+# t* I9lattenJ +ultidi+en#i*nal array#, u#ing array# *9 di99erent rank !ill thr*! a runti+e *an(&xception) The #tatic +eth*d 'rray6#ort() d*e# an inEplace #*rt *9 the array# c*ntent# and Binary#earch() pr*vide# an e99icient #earch *n a #*rted array) 'rray6*everse() i# #el9Ee;planat*ry, 3ut 'rray6Clear() ha# the perhap# #urpri#ing 3ehavi*r *9 #licing acr*## +ultidi+en#i*nal array#) -n the pr*gra+, 'rray6Clear(famousCouples, 8, 9) treat# the +ultidi+en#i*nal famousCouples array a# a 9lat array, #etting t* null the value# *9 indice# Z0,$\, Z0,0\, and Z2,$\)
4(4
Thinking in C
www.ThinkingIn.!et
-n C#, c*+pari#*n# are d*ne 3y calling 3ack t* the Compare+o() +eth*d *9 the BComparable inter9ace) Thi# +eth*d take# an*ther ob)ect a# an argu+ent, and pr*duce# a negative value i9 the current *34ect i# le## than the argu+ent, 7er* i9 the argu+ent i# eDual, and a p*#itive value i9 the current *34ect i# greater than the argu+ent) Here# a cla## that i+ple+ent# BComparable and de+*n#trate# the c*+para3ility 3y u#ing 'rray6#ort( )1 //:c0>:Co!p'ype.c# // 5!p e!enting 5Co!para$ e in a c a##. u#ing Sy#te!3 pu$ ic c a## Co!p'ype: 5Co!para$ e ; int i3 int D3 pu$ ic Co!p'ype0int n"2 int n21 ; i 9 n"3 D 9 n23 < pu$ ic o*erride #tring 'oString01 ; return &Ji 9 & R i R &2 D 9 & R D R &K&3 < pu$ ic int Co!pare'o0O$Dect r*1 ; int r*i 9 00Co!p'ype1r*1.i3 return 0i W r*i Y 6" : 0i 99 r*i Y 0 : "113 < pri*ate #tatic Rando! r 9 ne. Rando!013 pri*ate #tatic *oid )rray-rint0String #2 )rray a1; Sy#te!.Con#o e.Vrite0#13 foreach0O$Dect o in a1; Sy#te!.Con#o e.Vrite0o R &2&13 < Sy#te!.Con#o e.VriteLine013 < pu$ ic #tatic *oid Gain01 ; Co!p'ypeJK a 9 ne. Co!p'ypeJ"0K3
4(5
for0int i 9 03 i W "03 iRR1; aJiK 9 ne. Co!p'ype0r.Cext0"0012 r.Cext0"00113 < )rray-rint0&Before #orting2 a 9 &2 a13 )rray.Sort0a13 )rray-rint0&)fter #orting2 a 9 &2 a13 < < ///:8 ,hen y*u de9ine the c*+pari#*n 9uncti*n, y*u are re#p*n#i3le 9*r deciding !hat it +ean# t* c*+pare *ne *9 y*ur *34ect# t* an*ther) Here, *nly the i value# are u#ed in the c*+pari#*n, and the ) value# are ign*red) The .ain() +eth*d create# a 3unch *9 Comp+ype *34ect# that are initiali7ed !ith rand*+ value# and then #*rted) -9 Comparable hadnt 3een i+ple+ented, then y*ud get an -nvalidOperati*nE;cepti*n thr*!n at runti+e !hen y*u tried t* call 'rray6#ort( ))
What< (o +u++les<
-n the n*tE#*Edi#tant pa#t, the #*rt and #earch +eth*d# u#ed in a pr*gra+ !ere a +atter *9 c*n#tant de3ate and angui#h) -n the g**d *ld day#, even the +*#t trivial data#et# had a g**d chance *9 3eing larger than R=A G*r Ic*reJ a# !e u#ed t* #ayH and reDuired inter+ediate read# and !rite# t* #t*rage device# that c*uld take, ye#, #ec*nd# t* acce## G*r, i9 the tape# needed t* 3e #!apped, +inute#H) S* there !a# an en*r+*u# a+*unt *9 energy put int* !*rrying a3*ut internal GinE+e+*ryH ver#u# e;ternal #*rt#, the #ta3ility *9 #*rt#, the i+p*rtance *9 +aintaining the input tape until the *utput tape !a# veri9ied, the I*perat*r di#+*unt ti+e,J and #* 9*rth) *!aday#, 66^ *9 the ti+e y*u can ign*re the particular# *9 #*rting and #earching) -n *rder t* get a decent idea *9 #*rting #peed, thi# pr*gra+ reDuire# an array *9 0,$$$,$$$ ele+ent#, and #till it e;ecute# in a +atter *9 #ec*nd#1 //:c0>:Ha#tSort.c# u#ing Sy#te!3
4(6
Thinking in C
www.ThinkingIn.!et
c a## Sorta$ e : 5Co!para$ e ; int i3 interna Sorta$ e0int i1 ; thi#.i 9 i3 < pu$ ic int Co!pare'o0O$Dect o1 ; try ; Sorta$ e # 9 0Sorta$ e1 o3 return i 9 #.i3 < catch 05n*a idCa#t+xception1 ; thro. ne. )rgu!ent+xception013 < < < c a## Sorting'e#ter ; #tatic 'i!eSpan 'i!edSort05Co!para$ eJK #1; :ate'i!e #tart 9 :ate'i!e.Co.3 )rray.Sort0#13 'i!eSpan duration 9 :ate'i!e.Co. 6 #tart3 return duration3 < pu$ ic #tatic *oid Gain01 ; for 0int ti!e# 9 03 ti!e# W "03 ti!e#RR1 ; Sorta$ eJK # 9 ne. Sorta$ eJ"000000K3 for 0int i 9 03 i W #.Length3 iRR1 ; #JiK 9 ne. Sorta$ e0i13 < Sy#te!.Con#o e.VriteLine0&'i!e to #ort a ready #orted array: & R 'i!edSort0#113 Rando! rand 9 ne. Rando!013 for 0int i 9 03 i W #.Length3 iRR1 ; #JiK 9 ne. Sorta$ e0rand.Cext0113 < Sy#te!.Con#o e.VriteLine0&'i!e to #ort !ixed up array: & R 'i!edSort0#113 < < <///:8
4(#
The re#ult# #h*! that #ort() !*rk# 9a#ter *n an already #*rted array, !hich indicate# that 3ehind the #cene#, it# pr*3a3ly u#ing a +erge #*rt in#tead *9 MuickS*rt) But the #*rting alg*rith+ i# certainly le## i+p*rtant than the 9act that a c*+puter that c*#t# le## than a th*u#and d*llar# can per9*r+ an inE+e+*ry #*rt *9 a +illi*nEite+ arrayK A**re# La! ha# +ade anachr*ni#tic an entire 9ield *9 kn*!ledge and de3ate that #ee+ed, n*t that l*ng ag*, 9unda+ental t* c*+puter pr*gra++ing) Thi# i# an i+p*rtant le##*n 9*r th*#e !h* !i#h t* have l*ng career# in pr*gra++ing1 never c*n9u#e the +a#tery *9 t*day# 9act# !ith preparati*n 9*r t*+*rr*!# change#) ,ithin a decade, !e !ill have +ultiEtera3yte #t*rage *n the de#kt*p, trivial acce## t* di#tri3uted tera9l*p pr*ce##ing, and pr*3a3ly #peciali7ed acce## t* Duantu+ c*+puter# *9 #igni9icant capa3ility) Eventually, alth*ugh - d*u3t !ithin a decade, there !ill 3e 3reakthr*ugh# in u#er inter9ace# and !ell a3and*n the key3*ard and the +*nit*r 9*r v*ice and ge#ture input and Iaug+ented realityJ gla##e#) =l+*#t all the pr*gra++ing 9act# that h*ld t*day !ill 3e a# u#ele## a# the kn*!ledge *9 h*! t* d* an *#cillating #*rt !ith cri##Ecr*## di#tri3uti*n) = pr*gra++er +u#t never #tand #till)
>nsa0e )rra5s
?e#pite the preceding di#cu##i*n *9 the #teady +arch *9 technical *3#*le#cence, the 9act# *n the gr*und *9ten agitate t*!ard# thr*!ing a!ay the 3ene9it# *9 #a9ety and a3#tracti*n and getting cl*#er t* the hard!are in *rder t* 3**#t per9*r+ance) O9ten, the c*rrect #*luti*n in thi# ca#e !ill 3e t* +*ve *ut *9 C# alt*gether and int* C@@, a language !hich !ill c*ntinue 9*r #*+e ti+e t* 3e the 3e#t 9*r the creati*n *9 device driver# and *ther cl*#eEt*EtheE+etal c*+p*nent#) H*!ever, +anipulating array# can #*+eti+e# intr*duce 3*ttleneck# in higherElevel applicati*n#, #uch a# +ulti+edia applicati*n#) -n #uch #ituati*n#, un#a9e c*de +ay 3e !*rth!hile) The 3a#ic i+petu# 9*r u#ing un#a9e array# i# that y*u !i#h t* +anipulate the array a# a c*ntigu*u# 3l*ck *9 +e+*ry, 9*reg*ing 3*und# checking) ,avelet tran#9*r+# are 9a#cinating and their utility ha# hardly 3een #cratched) The #i+ple#t tran#9*r+ i# pr*3a3ly the t!*Edi+en#i*nal Haar tran#9*r+ *n a +atri; *9 d*u3le#) The Haar tran#9*r+ c*nvert# a li#t *9
4(&
Thinking in C
www.ThinkingIn.!et
value# int* the li#t# average and di99erence#, #* the li#t c2, &] i# tran#9*r+ed int* c/, 0] XX cG2 @ &H < 2, G2 @ &H < 2 P 2H]) = t!*E di+en#i*nal tran#9*r+ 4u#t tran#9*r+# the r*!# and then the c*lu+n#, #* cc2, &],c',.]] 3ec*+e# cc&)2', )%'],c0)2', E$)2']]1
,avelet# have +any intere#ting characteri#tic#, including 3eing the 3a#i# 9*r #*+e e;cellent c*+pre##i*n r*utine#, 3ut are e;pen#ive t* c*+pute 9*r array# that are typical *9 +ulti+edia applicati*n#, e#pecially 3ecau#e t* 3e u#e9ul they are u#ually c*+puted l*g2GA- Gdi+en#i*n #i7eHH ti+e# per arrayK The 9*ll*!ing pr*gra+ d*e# #uch a tran#9*r+ in t!* di99erent !ay#, *ne a #a9e +eth*d that u#e# typical C# c*de and the *ther u#ing un#a9e c*de) //:c0>:Ha#tBit!apper".c# u#ing Sy#te!3 u#ing Sy#te!.5O3 na!e#pace Ha#tBit!apper; pu$ ic interface 'ran#for!; *oid UoriMonta 'ran#for!0dou$ eJ2K !atrix13 *oid Nertica 'ran#for!0dou$ eJ2K !atrix13 < pu$ ic c a## Va*e et ; pu$ ic *oid 'ran#for!2:0dou$ eJ2K !atrix2 'ran#for! t1 ; int !in:i!en#ion 9 !atrix._etLength0013 if 0!atrix._etLength0"1 W !in:i!en#ion1 !in:i!en#ion 9 !atrix._etLength0"13
4('
int e*e # 9 0int1 Gath.H oor0Gath.Log0!in:i!en#ion2 2113 'ran#for!2:0!atrix2 e*e #2 t13 < pu$ ic *oid 'ran#for!2:0dou$ eJ2K !atrix2 int #tep#2 'ran#for! tStrategy1 ; for 0int i 9 03 i W #tep#3 iRR1 ; tStrategy.UoriMonta 'ran#for!0!atrix13 tStrategy.Nertica 'ran#for!0!atrix13 < < pu$ ic *oid 'e#tSpeed0'ran#for! t1 ; Rando! rand 9 ne. Rando!013 dou$ eJ2K !atrix 9 ne. dou$ eJ200022000K3 for 0int i 9 03 i W !atrix._etLength0013 iRR1 for 0int D 9 03 D W !atrix._etLength0"13 DRR1 ; !atrixJi2DK 9 rand.Cext:ou$ e013 < :ate'i!e #tart 9 :ate'i!e.Co.3 thi#.'ran#for!2:0!atrix2 t13 'i!eSpan dur 9 :ate'i!e.Co. 6 #tart3 Sy#te!.Con#o e.VriteLine0&'ran#for!ation .ith ;0< too% ;"< &2 t._et'ype01.Ca!e2 dur13 < pu$ ic #tatic *oid Gain01 ; Va*e et . 9 ne. Va*e et013 for 0int i 9 03 i W "03 iRR1 ; //_et thing# right fir#t ..'e#tSpeed0ne. Safe'ran#for!0113 ..'e#tSpeed0ne. On#afe'ran#for!0113 < < <
41(
Thinking in C
www.ThinkingIn.!et
interna c a## Safe'ran#for! : 'ran#for! ; pri*ate *oid 'ran#for!0dou$ eJK array1 ; int ha fLength 9 array.Length ZZ "3 dou$ eJK a*g 9 ne. dou$ eJha fLengthK3 dou$ eJK diff 9 ne. dou$ eJha fLengthK3 for 0int pair 9 03 pair W ha fLength3 pairRR1 ; dou$ e fir#t 9 arrayJpair = 2K3 dou$ e next 9 arrayJpair = 2 R "K3 a*gJpairK 9 0fir#t R next1 / 23 diffJpairK 9 a*gJpairK 6 fir#t3 < for 0int pair 9 03 pair W ha fLength3 pairRR1 ; arrayJpairK 9 a*gJpairK3 arrayJpair R ha fLengthK 9 diffJpairK3 < < pu$ ic *oid UoriMonta 'ran#for!0dou$ eJ2K !atrix1 ; int height 9 !atrix._etLength0013 int .idth 9 !atrix._etLength0"13 dou$ eJK ro. 9 ne. dou$ eJ.idthK3 for 0int i 9 03 i W height3 iRR1 ; for 0int D 9 03 D W .idth3 DRR1 ; ro.JDK 9 !atrixJi2 DK3 < 'ran#for!0ro.13 for 0int D 9 03 D W .idth3 DRR1 ; !atrixJi2DK 9 ro.JDK3 < < < pu$ ic *oid Nertica 'ran#for!0dou$ eJ2K !atrix1 ; int height 9 !atrix._etLength0013 int ength 9 !atrix._etLength0"13 dou$ eJK co :ata 9 ne. dou$ eJheightK3 for 0int co 9 03 co W ength3 co RR1 ;
411
for 0int ro. 9 03 ro. W height3 ro.RR1 ; co :ataJro.K 9 !atrixJro.2 co K3 < 'ran#for!0co :ata13 for 0int ro. 9 03 ro. W height3 ro.RR1 ; !atrixJro.2 co K 9 co :ataJro.K3 < < < < <///:8
The +ransform inter9ace c*ntain# t!* +eth*d#, each *9 !hich take# a rectangular array a# a para+eter and per9*r+# an inEplace tran#9*r+ati*nQ "oriTontal+ransform() c*nvert# a r*! *9 value# int* a r*! c*ntaining the average# and di99erence# *9 the r*!, and Hertical+ransform() per9*r+# a #i+ilar tran#9*r+ati*n *n the c*lu+n# *9 the array)
41)
Thinking in C
www.ThinkingIn.!et
The =avelet cla## c*ntain# t!* +ransform8$() +eth*d#, the 9ir#t *9 !hich take# a rectangular array and a +ransform) The nu+3er *9 #tep# reDuired t* per9*r+ a 9ull !avelet tran#9*r+ i# calculated 3y 9ir#t deter+ining the +ini+u+ di+en#i*n *9 the pa##edEin +atri; and then u#ing the .ath6Log() 9uncti*n t* deter+ine the 3a#eE2 +agnitude *9 that di+en#i*n) .ath6:loor() r*und# that +agnitude d*!n and the re#ult i# ca#t t* the integer nu+3er *9 #tep# that !ill 3e applied t* the +atri;) GThu#, an array !ith a +ini+u+ di+en#i*n *9 & !*uld have 2 #tep#, an array !ith 0$2& !*uld have 6)H The c*n#truct*r then call# the #ec*nd c*n#truct*r, !hich take# the #a+e para+eter# a# the 9ir#t plu# the nu+3er *9 ti+e# t* apply the !avelet Gthi# i# a #eparate c*n#truct*r 3ecau#e during de3ugging a #ingle !avelet #tep i# +uch ea#ier t* c*+prehend than a 9ully pr*ce##ed *ne, a# 5igure # #h*!#H
413
The +ransform8$() +eth*d iterate# steps ti+e# *ver the +atri;, 9ir#t per9*r+ing a h*ri7*ntal tran#9*r+ and then per9*r+ing a vertical tran#9*r+) =lternating 3et!een h*ri7*ntal and vertical tran#9*r+# i# called the nonstandard wa-elet decom"osition) The standard decom"osition per9*r+# steps h*ri7*ntal tran#9*r+# and then per9*r+# steps vertical tran#9*r+#) ,ith graphic# any!ay, the n*n#tandard dec*+p*#iti*n all*!# 9*r ea#ier appreciati*n *9 the !avelet 3ehavi*rQ in 5igure #, the upperEle9t Duadrant i# a hal9Ere#*luti*n duplicate *9 the *riginal, the upperEright a +ap *9 0Epi;el h*ri7*ntal 9eature#, the l*!erE le9t a #i+ilar +ap *9 vertical 9eature#, and the l*!erEright a c*+plete +ap *9 0Epi;el 9eature#) ,hen the re#ult i# tran#9*r+ed again and again, the re#ult ha# +any intere#ting 9eature#, including 3eing highly c*+pre##i3le !ith 3*th l*##le## and l*##y techniDue#)
414
Thinking in C
www.ThinkingIn.!et
The +est#peed() +eth*d in =avelet create# a &,$$$,$$$Eele+ent #Duare array, 9ill# it !ith rand*+ d*u3le#, and then calculate# and print# the ti+e nece##ary t* per9*r+ a 9ull !avelet tran#9*r+ *n the re#ult) The .ain() +eth*d call# thi# +est#peed() +eth*d 0$ ti+e# in *rder t* en#ure that any tran#ient *perating #y#te+ event# d*nt #ke! the re#ult#) Thi# 9ir#t ver#i*n *9 the c*de call# +est#peed() !ith a #afe+ransform P get thing# right and then get the+ 9a#t) The #afe+ransform cla## ha# a private +ransform() +eth*d !hich take# a *neEdi+en#i*nal array *9 d*u3le#) -t create# t!* array#, avg and diff *9 hal9 the !idth *9 the *riginal) The 9ir#t l**p in +ransform() +*ve# acr*## the #*urce array, reading value pair#) -t calculate# and placed the#e pair# average and di99erence in the avg and diff array#) =9ter thi# l**p 9ini#hed, the value# in avg are c*pied t* the 9ir#t hal9 *9 the input array and the value# in diff t* the #ec*nd hal9) =9ter +ransform() 9ini#he#, the input array n*! c*ntain# the value# *9 a *neE#tep, *neE di+en#i*nal Haar tran#9*r+ati*n) G *te that the tran#9*r+ i# 9ully rever#i3le EE the *riginal data can 3e re#t*red 3y 9ir#t adding and then #u3tracting a diff value t* a c*rre#p*nding avg value)H #afe+ransform6"oriTontal+ransform() deter+ine# the height *9 the pa##edEin +atri; and, c*pie# the value# *9 each r*! int* a *neE di+en#i*nal array *9 d*u3le# called row) Then the c*de call# the previ*u#ly de#cri3ed +ransform() +eth*d and c*pie# the re#ult 3ack int* the *riginal t!*Edi+en#i*nal +atri;) ,hen "oriTontal+ransform() i# 9ini#hed, the input +atri; a# a !h*le n*! c*ntain# a *neE#tep, h*ri7*ntal Haar tran#9*r+ati*n) #afe+ransform6Hertical+ransform() u#e# a #i+ilar #et *9 l**p# a# "oriTontal+ransform(), 3ut in#tead *9 c*pying r*!# 9r*+ the input +atri;, it c*pie# the value# in a c*lu+n int* a d*u3le array called col$ata, tran#9*r+# that !ith +ransform(), and c*pie# the re#ult 3ack int* the input +atri;) ,hen thi# 9ini#hed, c*ntr*l return# t* =avelet6+ransform8$(), and *ne #tep *9 the !avelet dec*+p*#iti*n ha# 3een per9*r+ed)
415
416
Thinking in C
www.ThinkingIn.!et
for 0int ro. 9 03 ro. W height3 ro.RR1 ; 'ran#for!0pOff#et2 .idth13 pOff#et R9 .idth3 < < < un#afe pu$ ic *oid Nertica 'ran#for!0dou$ eJ2K !atrix1 ; fixed0dou$ e= pGatrix 9 !atrix1 ; int height 9 !atrix._etLength0013 int ength 9 !atrix._etLength0"13 dou$ eJK co :ata 9 ne. dou$ eJheightK3 for 0int co 9 03 co W ength3 co RR1 ; for 0int ro. 9 03 ro. W height3 ro.RR1 ; co :ataJro.K 9 pGatrixJco R ength = ro.K3 < fixed0dou$ e= pCo :ata 9 co :ata1 ; 'ran#for!0pCo :ata2 height13 < for 0int ro. 9 03 ro. W height3 ro.RR1 ; pGatrixJco R ength = ro.K 9 co :ataJro.K3 < < < < <///:8 5ir#t, n*tice that Vnsafe+ransform ha# the #a+e #tructure a# #afe+ransform, a private +ransform() 9uncti*n in additi*n t* the pu3lic +eth*d# !hich i+ple+ent +ransform) Thi# i# 3y n* +ean# nece##ary, 3ut it# a g**d #tarting place 9*r *pti+i7ati*n) Vnsafe+ransform6+ransform() ha# a #ignature unlike any C# #ignature di#cu##ed 3e9*re1 unsafe private void +ransform(double;
41#
array, int length)F ,hen a +eth*d i# declared un#a9e, C# all*!# a ne! type *9 varia3le, called a p*inter) = p*inter c*ntain# a +e+*ry addre## at !hich a value *9 the #peci9ied type i# l*cated) S* the varia3le array c*ntain# n*t a d*u3le value #uch a# $)2 *r 2/&)2(, 3ut a +e+*ry l*cati*n #*+eplace in the runti+e, the c*ntent# *9 !hich are interpreted a# a d*u3le) =dding 0 t* array d*e# n*t change it t* 0)2 *r 2/')2( 3ut rather change# the +e+*ry l*cati*n t* p*int t* the ne;t l*cati*n in +e+*ry that# 3ig en*ugh t* h*ld a double) Such Ip*inter arith+eticJ i# +arginally +*re e99icient than u#ing a C# array, 3ut even #+all di99erence# add up !hen applied t* a &,$$$,$$$ ite+ arrayK The 9ir#t line in Vnsafe+ransform6+ransform() initiali7e# an*ther p*inter varia3le p1riginal'rray !ith the *riginal value in array, !h*#e value i# g*ing t* change) The declarati*n *9 the avg and diff array# and the 9ir#t l**p are identical !ith !hat !a# d*ne in #afe+ransform6+ransform(), e;cept that thi# ti+e !e u#e the value *9 the pa##edEin length varia3le t* calculate the value *9 halfLength Gin #afe+ransform6+ransform(), !e u#ed the Length pr*perty *9 the pa##edEin array, 3ut p*inter# d*nt have #uch a pr*perty, #* !e need the e;tra para+eter) The ne;t line#, th*ugh, are Duite di99erent1 dou$ e fir#t 9 =array3 RRarray3 dou$ e next 9 =array3 RRarray3 ,hen applied t* a p*inter varia3le, the b *perat*r retrieve# the value that i# #t*red at that addre## Gthe +ne+*nic i# I#tar X #t*redJH) S* the first d*u3le i# a##igned the value *9 the d*u3le at array# addre## value) Then, !e u#e p*inter arith+etic *n array #* that it #kip# *ver a d*u3le# !*rth *9 +e+*ry, read the value there a# a d*u3le and a##ign it t* next and incre+ent array again) The value# *9 avg and diff are calculated 4u#t a# they !ere in #afe+ransform6+ransform()) S* the 3ig di99erence in thi# l**p i# that in#tead *9 inde;ing in t* an array *9 double# *9 a certain length, !eve incre+ented a p*inter t* double# length ti+e#, and interpreted the +e+*ry *9 !here !e !ere p*inting at a# a #erie# *9 double#) There# 3een n* 3*und# *r type checking *n the value *9 *ur array p*inter, #* i9 thi# +eth*d !ere called !ith either
41&
Thinking in C
www.ThinkingIn.!et
array #et inc*rrectly *r !ith a !r*ng length, thi# l**p !*uld 3lithely read !hatever it happened t* 3e p*inting at) Such a #ituati*n +ight 3e hard t* track d*!n, 3ut the 9inal l**p in Vnsafe6+ransform() !*uld pr*3a3ly n*t g* undetected) = 9eature *9 p*inter# i# that y*u can u#e array n*tati*n t* indicate an *99#et in +e+*ry) Thu#, in thi# l**p, !e !rite 3ack int* the regi*n *9 +e+*ry at p1riginal'rray large en*ugh t* c*ntain length d*u3le#) ,riting int* an invalid regi*n *9 +e+*ry i# a pretty #ure !ay t* cau#e a cra#h) S* it 3eh**ve# u# t* +ake #ure that Vnsafe6+ransform() i# *nly called pr*perly) Vnsafe6"oriTontal+ransform() take# a t!*Edi+en#i*nal rectangular array *9 d*u3le# called matrix) Be9*re calling Vnsafe6+ransform(), !hich take# a p*inter t* a d*u3le, the matrix +u#t 3e IpinnedJ in +e+*ry) The ) ET gar3age c*llect*r i# n*r+ally 9ree t* +*ve *34ect# a3*ut, 3ecau#e the gar3age c*llect*r ha# the nece##ary data t* deter+ine every re9erence t* that *34ect Gindeed, tracking th*#e re9erence# i# the very e##ence *9 gar3age c*llecti*nKH) But !hen a p*inter i# inv*lved, it# n*t #a9e t* +*ve re9erence#Q in *ur ca#e, the l**p# in +ransform 3*th read and !rite a large 3l*ck *9 +e+*ry 3a#ed *n the *riginal pa##edEin addre##) The line fixed(double; p.atrix I matrix) pin# the rectangular array matrix in +e+*ry and initiali7e# a p*inter t* the 3eginning *9 that +e+*ry) P*inter# initiali7ed in a fixed declarati*n are readE*nly and 9*r the purp*#e# *9 p*inter arith+etic, !e need the ne;t line t* declare an*ther p*inter varia3le p1ffset and initiali7e it t* the value *9 p.atrix) *tice that unlike #afe+ransform6"oriTontal+ransform(), !e d* n*t have a te+p*rary *neEdi+en#i*nal row array !hich !e l*ad 3e9*re calling +ransform() and c*py 9r*+ a9ter) -n#tead, the +ain l**p in "oriTontal+ransform() call# +ransform() !ith it# p*inter *9 p1ffset and it# length #et t* the previ*u#ly calculated !idth *9 the input matrix) Then, !e u#e p*inter arith+etic t* 4u+p width !*rth *9 double# in +e+*ry) -n thi# !ay, !e are e;pl*iting the 9act that !e kn*! that a rectangular array i#, 3ehindEtheE#cene#, a c*ntigu*u# chunk *9
41'
+e+*ry) The line p1ffset CI widthF i# #igni9icantly 9a#ter than the ( line# *9 #a9e c*de it replace#) -n Vnsafe+ransform6Hertical+ransform(), th*ugh, n* #i+ilar #h*rtcut c*+e# t* +ind and the c*de i# virtually identical t* that in #afe+ransform6Hertical+ransform() e;cept that !e #till need t* pin matrix in *rder t* get the p.atrix p*inter t* pa## t* +ransform()) -9 !e g* 3ack t* ,avelet)AainGH and unc*++ent the line that call# +est#peed() !ith a new Vnsafe+ransform(), !ere al+*#t ready t* g*) H*!ever, the C# c*+piler reDuire# a #pecial 9lag in *rder t* c*+pile #*urce that c*ntain# un#a9e c*de) On the c*++andEline, thi# 9lag i# <un#a9e , !hile in Ci#ual Studi* ) ET, the *pti*n i# 9*und 3y rightEclicking *n the Pr*4ect in the S*luti*n E;pl*rer and ch**#ing Pr*pertie# < C*n9igurati*n Pr*pertie# < Build and #etting I=ll*! un#a9e c*de 3l*ck#J t* true) On +y +achine#, Vnsafe+ransform run# a3*ut '$^ 9a#ter than #afe+ransform in de3ugging +*de, and i# a3*ut 2$^ #uperi*r !hen *pti+i7ati*n# are turned *n) Hardly the #tu99 *9 legend#, 3ut in a c*re alg*rith+, perhap# !*rth the e99*rt) There# *nly *ne pr*3le+) Thi# +anaged c*de i+ple+entati*n run# &$^ 9a#ter than Vnsafe+ransformK Can y*u rea#*n !hyF1 //:c0>:5n- ace.c# interna c a## 5n- ace : 'ran#for! ; int ength3 int height3 int ha fLength3 int ha fUeight3 //Ua f the ength of onger di!en#ion dou$ eJK diff 9 nu 3 pri*ate *oid LaMy5nit0dou$ eJ2K !atrix1 ; height 9 !atrix._etLength0013 ength 9 !atrix._etLength0"13 ha fLength 9 ength ZZ "3 ha fUeight 9 height ZZ "3 if 0ha fUeight W ha fLength1 ; diff 9 ne. dou$ eJha fLengthK3
4)(
Thinking in C
www.ThinkingIn.!et
< e #e ; diff 9 ne. dou$ eJha fUeightK3 < < pu$ ic *oid UoriMonta 'ran#for!0dou$ eJ2 K !atrix1 ; if 0diff 99 nu 1 ; LaMy5nit0!atrix13 < for 0int i 9 03 i W height3 iRR1 ; U'ran#for!0!atrix2 i13 < < pu$ ic *oid Nertica 'ran#for!0dou$ eJ2 K !atrix1 ; if 0diff 99 nu 1 ; LaMy5nit0!atrix13 < for 0int co 9 03 co W ength3 co RR1 ; N'ran#for!0!atrix2 co 13 < < pri*ate *oid U'ran#for!0dou$ eJ2K !atrix2 int ro.1 ; for 0int pair 9 03 pair W ha fLength3 pairRR1 ; dou$ e fir#t 9 !atrixJro.2 pair = 2K3 dou$ e next 9 !atrixJro.2 pair = 2 R "K3 dou$ e a*g 9 0fir#t R next1 / 23 !atrixJro.2 pair = 2K 9 a*g3 diffJpairK 9 a*g 6 fir#t3 < for 0int pair 9 03 pair W ha fLength3 pairRR1 ;
4)1
!atrixJro.2 pair R ha fLengthK 9 diffJpairK3 < < pri*ate *oid N'ran#for!0dou$ eJ2K !atrix2 int co 1 ; for 0int pair 9 03 pair W ha fUeight3 pairRR1 ; dou$ e fir#t 9 !atrixJpair = 22 co K3 dou$ e next 9 !atrixJpair = 2 R "2 co K3 dou$ e a*g 9 0fir#t R next1 / 23 !atrixJpair = 22 co K 9 a*g3 diffJpairK 9 a*g 6 fir#t3 < for 0int pair 9 03 pair W ha fUeight3 pairRR1 ; !atrixJpair R ha fUeight2 co K 9 diffJpairK3 < < <///:8 Bn!lace re+*ve# l**p# and all*cati*n# *9 te+p*rary *34ect# Glike the avg and diff array#H at the c*#t *9 clarity) -n #afe+ransform, the Haar alg*rith+ *9 repeated averaging and di99erencing i# pretty ea#y t* 9*ll*! 4u#t 9r*+ the c*deQ - dare#ay that a 9ir#tEti+e reader *9 Bn!lace +ight n*t intuit, 9*r in#tance, that the c*ntent# *9 the diff array are #trictly 9*r te+p*rary #t*rage) *tice that 3*th "oriTontal+ransform() and Hertical+ransform() check t* #ee i9 diff i# null and call LaTyBnit() i9 it i# n*t) S*+e +ight #ay I,ell, !e kn*! that "oriTontal+ransform() i# called 9ir#t, #* the check in Hertical+ransform() i# #uper9lu*u#)J But i9 !e !ere t* re+*ve the check 9r*+ Hertical+ransform(), !e !*uld 3e changing the de#ign c*ntract *9 the +ransform() inter9ace t* include I:*u +u#t call "oriTontal+ransform() 3e9*re calling Hertical+ransform())J Changing a de#ign c*ntract i# n*t the end *9 the !*rld, 3ut it #h*uld al!ay# 3e given #*+e th*ught) ,hen a c*ntract reDuire# that +eth*d '()
4))
Thinking in C
www.ThinkingIn.!et
3e called 3e9*re +eth*d B(), the t!* +eth*d# are #aid t* 3e I#eDuence c*upled)J SeDuence c*upling i# u#ually accepta3le Gunlike, #ay, Iinternal data c*uplingJ !here *ne cla## directly !rite# t* an*ther cla### varia3le# !ith*ut u#ing pr*pertie# *r +eth*d# t* acce## the varia3le#H) >iven that the check in Hertical+ransformGH i# n*t !ithin a l**p, changing the c*ntract d*e#nt #ee+ !*rth !hat !ill certainly 3e an un+ea#ura3ly #+all di99erence in per9*r+ance)
)rra5 su##ar5
T* #u++ari7e !hat y*uve #een #* 9ar, the 9ir#t and ea#ie#t ch*ice t* h*ld a gr*up *9 *34ect# *9 a kn*!n #i7e i# an array) =rray# are al#* the natural data #tructure t* u#e i9 the !ay y*u !i#h t* acce## the data i# 3y a #i+ple inde;, *r i9 the data i# naturally IrectangularJ in it# 9*r+) -n the re+ainder *9 thi# chapter !ell l**k at the +*re general ca#e, !hen y*u d*nt kn*! at the ti+e y*ure !riting the pr*gra+ h*! +any *34ect# y*ure g*ing t* need, *r i9 y*u need a +*re #*phi#ticated !ay t* #t*re y*ur *34ect#) C# pr*vide# a li3rary *9 collection classes t* #*lve thi# pr*3le+, the 3a#ic type# *9 !hich are BList and B$ictionary) :*u can #*lve a #urpri#ing nu+3er *9 pr*3le+# u#ing the#e t**l#K =+*ng their *ther characteri#tic#, the C# c*llecti*n cla##e# !ill aut*+atically re#i7e the+#elve#) S*, unlike array#, y*u can put in any nu+3er *9 *34ect# and y*u d*nt need t* !*rry a3*ut h*! 3ig t* +ake the c*ntainer !hile y*ure !riting the pr*gra+)
4)3
The ) ET Sy#te+)C*llecti*n# na+e#pace take# the i##ue *9 Ih*lding y*ur *34ect#J and divide# it int* t!* di#tinct c*ncept#1 0) BList1 a gr*up *9 individual ele+ent#, *9ten !ith #*+e rule applied t* the+) =n BList +u#t h*ld the ele+ent# in a particular #eDuence) , and a #et cann*t have any duplicate ele+ent#) G *te that the ) ET 5ra+e!*rk d*e# n*t #upply either a set, !hich i# a C*llecti*n !ith*ut duplicate#, n*r a 2ag, !hich i# an und*rdered C*llecti*n)H 2) B$ictionary1 a gr*up *9 keyEvalue *34ect pair# Gal#* called .a"sH) Strictly #peaking, an B$ictionary c*ntain# $ictionary&ntry #tructure#, !hich the+#elve# c*ntain the t!* re9erence# Gin the Eey and Halue pr*pertie#H) The Eey pr*perty cann*t 3e null and +u#t 3e uniDue, !hile the Halue entry +ay 3e null *r +ay p*int t* a previ*u#ly re9erenced *34ect) :*u can acce## any *9 the#e part# *9 the B$ictionary #tructure P y*u can get the $ictionary&ntry value#, the #et *9 Eey# *r the c*llecti*n *9 Halue#) ?icti*narie#, like array#, can ea#ily 3e e;panded t* +ultiple di+en#i*n# !ith*ut adding ne! c*ncept#1 y*u #i+ply +ake an B$ictionary !h*#e value# are *9 type B$ictionary Gand the value# *9 those dicti*narie# can 3e dicti*narie#, etc)H
4)4
Thinking in C
www.ThinkingIn.!et
c a## Cu#to!er; #tring na!e3 pu$ ic #tring Ca!e; get; return na!e3 < < - ate:i#pen#er p3 interna Cu#to!er0String na!e2 - ate:i#pen#er p1; thi#.na!e 9 na!e3 thi#.p 9 p3 < interna *oid _et- ate01; #tring p ate 9 p._et- ate013 Sy#te!.Con#o e.VriteLine0 na!e R & got & R p ate13 < < c a## - ate:i#pen#er; Stac% di#pen#er 9 ne. Stac%013 interna *oid Hi 0int i'o-u#h1; for0int i 9 03 i W i'o-u#h3 iRR1; #tring p 9 &- ate (& R i3 Sy#te!.Con#o e.VriteLine0&Loading & R p13 di#pen#er.-u#h0p13 < < interna #tring _et- ate01; return 0#tring1 di#pen#er.-op013 < < c a## 'e er; Queue ine 9 ne. Queue013 interna *oid +nterLine0Cu#to!er c1; ine.+n7ueue0c13 < interna *oid Chec%out01; Cu#to!er c 9 0Cu#to!er1 ine.:e7ueue013
4)5
Sy#te!.Con#o e.VriteLine0 &Chec%ing out: & R c.Ca!e13 < < c a## Cafeteria; - ate:i#pen#er pd 9 ne. - ate:i#pen#er013 'e er t 9 ne. 'e er013 pu$ ic #tatic *oid Gain01; ne. Cafeteria013 < pu$ ic Cafeteria01; pd.Hi 0E13 Cu#to!erJK c 9 ne. Cu#to!erJEK3 for0int i 9 03 i W E3 iRR1; cJiK 9 ne. Cu#to!er0&Cu#to!er (& R i2 pd13 cJiK._et- ate013 < for0int i 9 03 i W E3 iRR1; t.+nterLine0cJiK13 < for0int i 9 03 i W E3 iRR1; t.Chec%out013 < < <///:8 5ir#t, the c*de #peci9ie# that it !ill 3e u#ing type# 9r*+ the Sy#te+ and Sy#te+)C*llecti*n na+e#pace#) Then, the Customer cla## ha# a na+e and a re9erence t* a !late$ispenser *34ect) The#e re9erence# are pa##ed in the Customer c*n#truct*r) 5inally, Customer6 et!late() retrieve# a plate 9r*+ the !late$ispenser and print# *ut the na+e *9 the cu#t*+er and the identi9ier *9 the plate) The !late$ispenser *34ect c*ntain# an internal re9erence t* a #tac() ,hen !late$ispenser6:ill() i# called, a uniDue #tring i# created and #tac(6!ush() place# it *n the t*p G*r 9r*ntH *9 the #tack) Si+ilarly, !late$ispenser6 et!late() u#e# #tac(6!op() t* get the *34ect at the #tack# t*p)
4)6
Thinking in C
www.ThinkingIn.!et
The +eller cla## ha# a re9erence t* a _ueue *34ect) +eller6&nterLine() call# _ueue6&n%ueue() and +eller6Chec(out() call# _ueue6$e%ueue()) Since the *nly *34ect# placed in the Dueue are *9 type Customer, it# #a9e 9*r the re9erence returned 3y _ueue6$e%ueue() t* 3e ca#t t* a Customer, and the na+e printed t* the C*n#*le) 5inally, the Cafeteria cla## 3ring# it all t*gether) -t c*ntain# a !late$ispenser and a +eller) The c*n#truct*r 9ill# the plate di#pen#er and create# #*+e cu#t*+er#, !h* get plate#, get in line 9*r the teller, and check *ut) The *utput l**k# like thi#1 Loading - ate (0 Loading - ate (" Loading - ate (2 Loading - ate (T Cu#to!er (0 got - ate (T Cu#to!er (" got - ate (2 Cu#to!er (2 got - ate (" Cu#to!er (T got - ate (0 Chec%ing out: Cu#to!er (0 Chec%ing out: Cu#to!er (" Chec%ing out: Cu#to!er (2 Chec%ing out: Cu#to!er (T =# y*u can #ee, the *rder in !hich the plate# are di#pen#ed i# the rever#e *9 the *rder in !hich they !ere placed in the !late$ispenser# #tac() ,hat happen# i9 y*u call !op() *r $e%ueue() *n an e+pty c*llecti*nF -n 3*th #ituati*n# y*ull get an Bnvalid1peration&xception !ith an e;plicit +e##age that the #tack *r Dueue i# e+pty) Stack# and Dueue# are 4u#t the thing 9*r #cheduling pr*3le+#, 3ut i9 y*u need t* ch**#e acce## *n +*re than a ti+eE*9Earrival 3a#i#, y*ull need an*ther data #tructure)
)rra5List
-9 a nu+eric inde; i# all y*u need, the 9ir#t thing that y*ull c*n#ider i# an =rray, *9 c*ur#e) But i9 y*u d*nt kn*! the e;act nu+3er *9 *34ect# that y*ull need t* #t*re, c*n#ider =rrayLi#t)
4)#
Like the *ther c*llecti*n cla##e#, =rrayLi#t ha# #*+e very handy #tatic +eth*d# y*u can u#e !hen y*u !ant t* en#ure certain characteri#tic# *9 the underlying c*llecti*n) The #tatic +eth*d# 'rrayList6:ixed#iTe() and 'rrayList6*ead1nly() return their 'rrayList argu+ent# !rapped in #peciali7ed handle# that en9*rce the#e re#tricti*n#) H*!ever, care +u#t 3e taken t* di#card any re9erence# t* the *riginal argu+ent t* the#e +eth*d#, 3ecau#e the inner =rrayLi#t can get ar*und the re#tricti*n#, a# thi# e;a+ple #h*!#1 //:c0>:)rrayLi#tStatic#.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 pu$ ic c a## )rrayLi#tStatic#; pu$ ic #tatic *oid Gain01; )rrayLi#t a 9 ne. )rrayLi#t013 Rando! rand 9 ne. Rando!013 int i'o)dd 9 P0 R rand.Cext0P013 for0int i 9 03 i W i'o)dd3 iRR1; #tring # 9 &String (& R i3 a .)dd0#13 < )rrayLi#t noGore 9 )rrayLi#t.HixedSiMe0a 13 try; noGore.)dd0&'hi# .on't .or%&13 <catch0+xception ex1; Sy#te!.Con#o e.VriteLine0ex13 < )rrayLi#t untoucha$ e 9 )rrayLi#t.ReadOn y0a 13 try; untoucha$ eJ0K 9 &'hi# .on't .or%&3 <catch0+xception ex1; Sy#te!.Con#o e.VriteLine0ex13 < //But re#triction# do not app y to origina a J0K 9 &Godified&3 Sy#te!.Con#o e.VriteLine0 &Ontoucha$ eJ0K 9 & R untoucha$ eJ0K13 int origina Count 9 noGore.Count3 Sy#te!.Con#o e.VriteLine0
4)&
Thinking in C
www.ThinkingIn.!et
&SiMe of noGore ;0< !9 ;"<&2 origina Count2 noGore.Count13 < <///:8 ,hile the *perati*n# *n the !rapped array# !ill rai#e ,ot#upported&xceptions G!hich are caught and printed t* the c*n#*leH, a change t* the *riginal al =rrayLi#t i# re9lected in Vntouchable and the #i7e *9 no.ore can 3e increa#edK =n*ther intere#ting #tatic +eth*d *9 =rrayLi#t i# #ynchroniTed, !hich !ill 3e di#cu##ed in Chapter #threading#)
3it)rra5
= Bit'rray i# u#ed i9 y*u !ant t* e99iciently #t*re a l*t *9 *nE*99 *r trueE 9al#e in9*r+ati*n) -t# e99icient *nly 9r*+ the #tandp*int *9 #i7eQ i9 y*ure l**king 9*r e99icient acce##, it i# #lightly #l*!er than u#ing an array *9 #*+e native type) = n*r+al c*ntainer e;pand# a# y*u add +*re ele+ent#, 3ut !ith Bit'rray, y*u +u#t #et the Length pr*perty t* 3e #u99icient t* h*ld a# +any a# y*u need) The c*n#truct*r t* Bit'rray take# an integer !hich #peci9ie# the initial capacity Gthere are al#* c*n#truct*r# !hich c*py 9r*+ an e;i#ting Bit'rray, 9r*+ an array *9 3**l#, *r 9r*+ the 3itEvalue# *9 an array *9 3yte# *r int#H) The 9*ll*!ing e;a+ple #h*!# h*! the Bit'rray !*rk#1 //:c0>:Bit#.c# // :e!on#tration of BitSet. u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 pu$ ic c a## Bit# ; #tatic *oid -rintBit)rray0Bit)rray $1 ; Sy#te!.Con#o e.VriteLine0&$it#: & R $13 #tring $$it# 9 &&3 for 0int D 9 03 D W $.Length 3 DRR1 $$it# R9 0$JDK Y &"& : &0&13 Sy#te!.Con#o e.VriteLine0 &$it pattern: & R $$it#13
4)'
< pu$ ic #tatic *oid Gain01 ; Rando! rand 9 ne. Rando!013 // 'a%e the LSB of Cext01: $yte $t 9 0$yte1rand.Cext013 Bit)rray $$ 9 ne. Bit)rray0I13 for 0int i 9 F3 i Z903 i661 if 000" WW i1 @ $t1 !9 01 $$.Set0i2 true13 e #e $$.Set0i2 fa #e13 Sy#te!.Con#o e.VriteLine0&$yte *a ue: & R $t13 -rintBit)rray0$$13 #hort #t 9 0#hort1rand.Cext013 Bit)rray $# 9 ne. Bit)rray0"?13 for 0int i 9 "P3 i Z903 i661 if 000" WW i1 @ #t1 !9 01 $#.Set0i2 true13 e #e $#.Set0i2 fa #e13 Sy#te!.Con#o e.VriteLine0&#hort *a ue: & R #t13 -rintBit)rray0$#13 int it 9 rand.Cext013 Bit)rray $i 9 ne. Bit)rray0T213 for 0int i 9 T"3 i Z903 i661 if 000" WW i1 @ it1 !9 01 $i.Set0i2 true13 e #e $i.Set0i2 fa #e13 Sy#te!.Con#o e.VriteLine0&int *a ue: & R it13 -rintBit)rray0$i13 // 'e#t Bit)rray# that gro.: Bit)rray $"2F 9 ne. Bit)rray0?E13 //! Vou d thro. )rgu!entOutOfRange+xception //! $"2F.Set0"2F2 true13 //Gu#t !anua y expand the Length $"2F.Length 9 "2I3 $"2F.Set0"2F2 true13
43(
Thinking in C
www.ThinkingIn.!et
Sy#te!.Con#o e.VriteLine0 &#et $it "2F: & R $"2F13 < < ///:8
4ictionaries
?icti*narie# all*! y*u t* rapidly l**k up a value 3a#ed *n a uniDue n*nE nu+eric key and are a+*ng the +*#t handy *9 the c*llecti*n cla##e#)
9ashta+le
The "ashtable i# #* c*++*nly u#ed that +any pr*gra++er# u#e the phra#e interchangea3ly !ith the c*ncept *9 a dicti*naryK The Ha#hta3le, th*ugh, i# an i+ple+entati*n *9 B$ictionary that ha# all type# *9 intere#ting i+ple+entati*n detail#) Be9*re !e get t* th*#e, here# a #i+ple e;a+ple *9 u#ing a "ashtable1 //:c0>:Si!p eUa#h.c# u#ing Sy#te!.Co ection#3 pu$ ic c a## Larry#-et# ; #tatic 5:ictionary Hi 05:ictionary d1 ; d.)dd0&dog&2 &Cheyenne&13 // Con6uni7ue %ey cau#e# exception //! d.)dd0&dog&2 &Bette&13 d.)dd0&cat&2 &Uarry&13 d.)dd0&go dfi#h&2 nu 13 return d3 < pu$ ic #tatic *oid Gain01 ; 5:ictionary pet# 9 ne. Ua#hta$ e013 Hi 0pet#13 foreach0:ictionary+ntry pet in pet#1; Sy#te!.Con#o e.VriteLine0 &Larry ha# a ;0< na!ed ;"<&2 pet.aey2 pet.Na ue13 < < < ///:8
431
pr*duce# *utput *91 Larry ha# a dog na!ed Cheyenne Larry ha# a go dfi#h na!ed Larry ha# a cat na!ed Uarry *te that atte+pting t* add a n*nEuniDue key t* a "ashtable rai#e# an 'rgument&xception6 Thi# d*e# n*t +ean that *ne cann*t change the value *9 a Ha#hta3le at a given key, th*ugh1 //:c0>:ChangeUa#hta$ eNa ue.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 c a## ChangeUa#hta$ eNa ue; pu$ ic #tatic *oid Gain01; Ua#hta$ e h 9 ne. Ua#hta$ e013 h.)dd0&Hoo&2&Bar&13 O$Dect o 9 hJ&Hoo&K3 hJ&Hoo&K 9 &Godified&3 Sy#te!.Con#o e.VriteLine0&Na ue i#: & R hJ&Hoo&K13 hJ&BaM&K 9 &BoMo&3 < <///:8 Thi# e;a+ple #h*!# the u#e *9 C## custom inde%ers) = cu#t*+ inde;er all*!# *ne t* acce## an B$ictionary u#ing n*r+al array n*tati*n) =lth*ugh here !e u#e *nly string# a# the key#, the key# in an B$ictionary can 3e *9 any type and can 3e +i;ed and +atch a# nece##ary) =9ter I5**J i# #et a# the key t* the IBarJ value, array n*tati*n can 3e u#ed t* acce## the value, 9*r 3*th reading and !riting) =# #h*!n in the la#t line *9 .ain(), the #a+e array n*tati*n can 3e u#ed t* add ne! keyEvalue pair# t* the Ha#hta3le) The +*#t intere#ting Ha#hta3le i+ple+entati*n detail ha# t* d* !ith the calculati*n *9 the ha#hc*de, a uniDue integer !hich I#*+eh*!J identi9ie# the key# uniDue value) The ha#hc*de i# returned 3y ob)ect6 et"ashCode(), a +eth*d that need# t* 3e 9a#t and t* return integer# that are I#pread *utJ a# +uch a# p*##i3le) =dditi*nally, the +eth*d +u#t al!ay# return the #a+e value 9*r a given *34ect, #* y*u cant
43)
Thinking in C
www.ThinkingIn.!et
3a#e y*ur ha#hc*de *n thing# like #y#te+ ti+e) -n thi# e;a+ple, the ha#hc*de and the related ob)ect6&%uals() +eth*d are u#ed t* e;pre## the idea that the #*le deter+inant *9 a circle# identity i# it# center and radiu# 1 //:c0>:O*erridingUa#h.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 c a## Circ e; int x2 y2 radiu#3 interna Circ e0int x2 int y2 int radiu#1; thi#.x 9 x3 thi#.y 9 y3 thi#.radiu# 9 radiu#3 < interna Circ e0int top,2 int top/2 int o.er,2 int o.er/1; thi#.x 9 top, R 0 o.er, 6 top,1 / 23 thi#.y 9 top/ R 0 o.er/ 6 top/1 / 23 thi#.radiu# 9 0 o.er, 6 top,1 / 23 < pu$ ic o*erride int _etUa#hCode01; Sy#te!.Con#o e.VriteLine0 &Returning ;0<&2 x R y R radiu#13 return x R y R radiu#3 < pu$ ic o*erride $oo +7ua #0O$Dect o1; if0o i# Circ e1; Circ e that 9 0Circ e1 o3 Sy#te!.Con#o e.VriteLine0 &Co!paring ;0<2;"<2;2< .ith & R &;T<2;E<2;P<&2 x2 y2 radiu#2 that.x2 that.y2 that.radiu#13 return 0thi#.x 99 that.x1 @@ 0thi#.y 99 that.y1 @@ 0thi#.radiu# 99 that.radiu#13 < return fa #e3
433
< pu$ ic #tatic *oid Gain01; Circ e c 9 ne. Circ e0"P2 "P2 P13 Circ e un i%e 9 ne. Circ e0"P2 "P2 ?13 Circ e #o!e.hatLi%e 9 ne. Circ e0T02 "2 E13 5:ictionary d 9 ne. Ua#hta$ e013 d.)dd0c2 &) circ e&13 d.)dd0un i%e2 &)nother circ e&13 try; Circ e i%e 9 ne. Circ e0"02 "02 202 2013 d.)dd0 i%e2 &`u#t i%e c&13 <catch0+xception ex1; Sy#te!.Con#o e.VriteLine0ex13 < < <///:8 ,hen a Circle i# added t* a "ashtable, the Ha#hta3le call# 3ack t* Circle6 et"ashCode() !hich return# the #u+ *9 the center c**rdinate# and radiu# *9 the circle) Thi# i# n* pr*3le+ 9*r the 9ir#t t!* circle#, c and unli(e, 3ecau#e they have di99erent ha#hc*de#) Circle somewhatLi(e th*ugh, cau#e# !hat i# called a Iha#h c*lli#i*nJ P the #a+e ha#hc*de i# returned 9*r t!* di99erent *34ect# Gin thi# ca#e, 3*th circle# ele+ent# add up t* /'H) ,hen a ha#h c*lli#i*n take# place, "ashtable cau#e# ob)ect6&%uals() t* #ee i9 the *34ect# are, in 9act, the #a+e *34ect) Becau#e the#e t!* circle# have di99erent center# and radii, they can 3*th 3e added t* the "ashtable) Ha#h c*lli#i*n# #eri*u#ly inter9ere !ith the e99iciency *9 the "ashtable, #* 9reDuent c*lli#i*n# #h*uld +ake y*u revi#it y*ur ha#hc*de alg*rith+) -n the try 3l*ck, !e create an*ther ne! Circle, thi# ti+e u#ing an alternate c*n#truct*r) ,hen it# added t* the "ashtable, thi# ti+e there# an*ther c*lli#i*n, 3ut thi# ti+e Circle6&%uals() reveal# that ye#, c and li(e are l*gically eDuivalent and there9*re "ashtable thr*!# an 'rgument&xception)
List4ictionar5
-9 y*u have *nly a d*7en *r 9e!er *34ect# t* #t*re in y*ur ?icti*nary, List$ictionary !ill have 3etter per9*r+ance than a "ashtable) On the
434
Thinking in C
www.ThinkingIn.!et
*ther hand, *n larger a+*unt# *9 *34ect#, List$ictionary ha# +uch, much !*r#e per9*r+ance and the per9*r+ance *9 a c*llecti*n cla## !ith a #+all nu+3er *9 ele+ent# i# unlikely t* 3e a h*t#p*t in an applicati*n) -t# n*t i+p*##i3le, th*ughK S* i9 y*uve g*t a dicti*nary !ith a #+all a+*unt *9 *34ect# and it# 3uried in the central l**p in y*ur applicati*n, List$ictionary +ight c*+e in handy) Other!i#e, g* !ith "ashtable)
'ortedList
S*+eti+e#, y*u need t* acce## a C*llecti*n in t!* di99erent !ay#1 keyE 3a#ed l**kup 9*r *ne purp*#e, and inde;E3a#ed l**kup 9*r an*ther) The S*rtedLi#t pr*vide# thi# dualE+*de capa3ility1 //:c0>:Sho.SortedLi#t.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 c a## Sho.SortedLi#t; SortedLi#t !onthLi#t 9 ne. SortedLi#t013 Sho.SortedLi#t01; !onthLi#t.)dd0&`anuary&2 T"13 !onthLi#t.)dd0&He$ruary&22I.2P13 !onthLi#t.)dd0&Garch&2 T"13 !onthLi#t.)dd0&)pri &2 T013 !onthLi#t.)dd0&Gay&2 T"13 !onthLi#t.)dd0&`une&2 T013 !onthLi#t.)dd0&`u y&2 T"13 !onthLi#t.)dd0&)ugu#t&2 T"13 !onthLi#t.)dd0&Septe!$er&2T013 !onthLi#t.)dd0&Octo$er&2T"13 !onthLi#t.)dd0&Co*e!$er&2T013 !onthLi#t.)dd0&:ece!$er&2T"13 Sy#te!.Con#o e.VriteLine0 &`une ha# ;0< day#&2 !onthLi#tJ&`une&K13 Sy#te!.Con#o e.VriteLine0 &'he eighth !onth ha# ;0< day#&2 !onthLi#t._etBy5ndex0F113 < pu$ ic #tatic *oid Gain01;
435
Sho.SortedLi#t ## 9 ne. Sho.SortedLi#t013 < <///:8 The #ortedList can 3e acce##ed u#ing any *34ect *9 the key type, in thi# ca#e string#) Or, etByBndexGH can 3e u#ed t* retrieve a value 3a#ed *n a nu+eric inde;)
'tring s$ecialists
String# are certainly the +*#t u#ed type 9*r key# and value#, and the ) ET 5ra+e!*rk pr*vide# a nu+3er *9 #peciali7ed c*llecti*n# that !*rk e;clu#ively !ith #tring#) The#e c*llecti*n# can 3e 9*und in the #ystem6Collections6#pecialiTed na+e#pace)
436
Thinking in C
www.ThinkingIn.!et
< < < <///:8 The *utput *9 the pr*gra+ i# #h*!n here1 aey: Vinter CSN: `anuary2He$ruary2:ece!$er Na ue: `anuary Na ue: He$ruary Na ue: :ece!$er aey: Spring CSN: Garch2)pri 2Gay Na ue: Garch Na ue: )pri Na ue: Gay -n a rather #trange de#ign deci#i*n, the cu#t*+ inde;er and the et() +eth*d return the value# a# a #ingle c*++aE#eparated #tring rather than a# an array) -9 y*u !ant t* acce## the value# a# a #tring array, y*u have t* u#e the etHalues() +eth*d)
43#
ection#3
c a## +*enOddCo!parer : 5Co!parer; pu$ ic int Co!pare0O$Dect x2 O$Dect y1; //On y co!pare integer# if 0x i# 5ntT2 99 fa #e SS y i# 5ntT2 99 fa #e1; thro. ne. )rgu!ent+xception0 &Can't co!pare non65ntT2'#&13 < //On$ox input# int xNa ue 9 0int1 x3 int yNa ue 9 0int1 y3 if 0xNa ue [ 2 99 yNa ue [ 21 ; return 03 < return 6"3 < < c a## +*enOddUa#hCode-ro*ider : 5Ua#hCode-ro*ider; pu$ ic int _etUa#hCode0O$Dect intO$D1; //On y ha#h integer# if0intO$D i# 5ntT2 99 fa #e1; thro. ne. )rgu!ent+xception0 &Can't ha#h non65ntT2'#&13 < //On$ox input int x 9 0int1 intO$D3 return x [ 23 < < c a## +*enOdd; #tatic +*enOddCo!parer c 9 ne. +*enOddCo!parer013 #tatic +*enOddUa#hCode-ro*ider p 9 ne. +*enOddUa#hCode-ro*ider013 //Ua#hta$ e %ey# #tatic readon y int +N+CXa+/ 9 23
43&
Thinking in C
www.ThinkingIn.!et
#tatic readon y int O::Xa+/ 9 T3 //Cu#to! 5Co!parer @ 5Ua#hCode-ro*ider #trategie# Ua#hta$ e e*enOdd 9 ne. Ua#hta$ e0p2 c13 pu$ ic *oid 'e#t01; e*enOddJ+N+CXa+/K 9 23 e*enOddJO::Xa+/K 9 T3 e*enOddJ+N+CXa+/K 9 E3 Sy#te!.Con#o e.VriteLine0 &'he a#t e*en nu!$er added .a#: & R e*enOddJ+N+CXa+/K13 Sy#te!.Con#o e.VriteLine0 &'he a#t odd nu!$er added .a#: & R e*enOddJO::Xa+/K13 < pu$ ic #tatic *oid Gain01; +*enOdd eo 9 ne. +*enOdd013 eo.'e#t013 < <
43'
u#ing Sy#te!.Co
ection#.Specia iMed3
c a## Ve$#ter#)$ridged; #tatic String:ictionary #d 9 ne. String:ictionary013 #tatic Ve$#ter#)$ridged01; #dJ&aa!&K 9 &) !ea#ure of i7uid# a!ong the :utch&3 #dJ&Mythu!&K 9 &Ga t $e*erage $re.ed $y ancient +gyptian#&3 < pu$ ic #tatic *oid Gain0#tringJK arg#1; foreach0#tring arg in arg#1; if0#d.Contain#aey0arg11; Sy#te!.Con#o e.VriteLine0#dJargK13 <e #e; Sy#te!.Con#o e.VriteLine0 &5 don't %no. that .ord&13 < < < < The pr*gra+ iterate# *ver the c*++andEline argu+ent# and either return# the de9initi*n *r ad+it# de9eat) Becau#e the #tring$ictionary i# ca#eEin#en#itive, thi# pr*gra+ i# highly u#e9ul even !hen the C=PS LOCN key *n the key3*ard i# le9t turned *n)
44(
Thinking in C
www.ThinkingIn.!et
h*ld# re9erence# t* ob)ect, !hich i# the r**t *9 all the cla##e# #* it h*ld# any type) Thi# i# a great #*luti*n, e;cept1 0) Since the type in9*r+ati*n i# *3#cured !hen y*u put an *34ect re9erence int* a c*ntainer, there# n* re#tricti*n *n the type *9 *34ect that can 3e put int* y*ur c*ntainer, even i9 y*u +ean it t* h*ld *nly, #ay, cat#) S*+e*ne c*uld 4u#t a# ea#ily put a d*g int* the c*ntainer) 2) Since the type in9*r+ati*n i# *3#cured, the *nly thing the c*ntainer kn*!# that it h*ld# i# a re9erence t* an ob)ect) :*u +u#t per9*r+ a ca#t t* the c*rrect type 3e9*re y*u u#e it) On the up #ide, C# !*nt let y*u misuse the *34ect# that y*u put int* a c*ntainer) -9 y*u thr*! a d*g int* a c*ntainer *9 cat# and then try t* treat everything in the c*ntainer a# a cat, y*ull get a runEti+e e;cepti*n !hen y*u pull the d*g re9erence *ut *9 the cat c*ntainer and try t* ca#t it t* a cat) Here# an e;a+ple u#ing the 3a#ic !*rkh*r#e c*ntainer, 'rrayList) 5ir#t, Cat and $og cla##e# are created1 //: c0>:Cat.c# na!e#pace pet#; pu$ ic c a## Cat ; pri*ate int catCu!$er3 interna Cat0int i1 ; catCu!$er 9 i3< interna *oid -rint01 ; Sy#te!.Con#o e.VriteLine0 &Cat (& R catCu!$er13 < < < ///:8 //: c0>::og.c# na!e#pace pet#; pu$ ic c a## :og ; pri*ate int dogCu!$er3 interna :og0int i1 ; dogCu!$er 9 i3< interna *oid -rint01 ; Sy#te!.Con#o e.VriteLine0 &:og (& R dogCu!$er13
441
< < < ///:8 Cat# and $og# are placed int* the c*ntainer, then pulled *ut1 //: c0>:Cat#)nd:og#.c# // Co!pi e .ith: c#c Cat.c# :og.c# Cat#)nd:og#.c# // Si!p e container exa!p e. u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 na!e#pace pet#; pu$ ic c a## Cat#)nd:og# ; pu$ ic #tatic *oid Gain01 ; )rrayLi#t cat# 9 ne. )rrayLi#t013 for 0int i 9 03 i W F3 iRR1 cat#.)dd0ne. Cat0i113 // Cot a pro$ e! to add a dog to cat#: cat#.)dd0ne. :og0F113 for 0int i 9 03 i W cat#.Count3 iRR1 00Cat1cat#JiK1.-rint013 // :og i# detected on y at run6ti!e < < <///:8 The cla##e# Cat and $og are di#tinctRthey have n*thing in c*++*n e;cept that they are ob)ect#) G-9 y*u d*nt e;plicitly #ay !hat cla## y*ure inheriting 9r*+, y*u aut*+atically inherit 9r*+ ob)ect)H Since 'rrayList h*ld# ob)ect#, y*u can n*t *nly put Cat *34ect# int* thi# c*ntainer u#ing the 'rrayList +eth*d 'dd( ), 3ut y*u can al#* add $og *34ect# !ith*ut c*+plaint at either c*+pileEti+e *r runEti+e) ,hen y*u g* t* 9etch *ut !hat y*u think are Cat *34ect# u#ing the 'rrayList inde;er, y*u get 3ack a re9erence t* an ob)ect) Since the intent !a# that cats #h*uld *nly c*ntain 9eline#, there i# n* check +ade 3e9*re ca#ting the returned value t* a Cat) Since !e !ant t* call the !rint() +eth*d *9 Cat, !e have t* 9*rce the evaluati*n *9 the ca#t t* happen 9ir#t, #* !e #urr*und the e;pre##i*n in parenthe#e# 3e9*re calling !rint( )) =t runE
44)
Thinking in C
www.ThinkingIn.!et
ti+e, th*ugh, !hen the l**p trie# t* ca#t the $og *34ect t* a Cat, it thr*!# a ClassCast&xception) Thi# i# +*re than 4u#t an ann*yance) -t# #*+ething that can create di99icultEt*E9ind 3ug#) -9 *ne part G*r #everal part#H *9 a pr*gra+ in#ert# *34ect# int* a c*ntainer, and y*u di#c*ver *nly in a #eparate part *9 the pr*gra+ thr*ugh an e;cepti*n that a 3ad *34ect !a# placed in the c*ntainer, then y*u +u#t 9ind *ut !here the 3ad in#ert *ccurred) On the up#ide, it# c*nvenient t* #tart !ith #*+e #tandardi7ed c*ntainer cla##e# 9*r pr*gra++ing, de#pite the #carcity and a!k!ardne##)
443
< pu$ ic int )dd0Cat fe ine1; return Li#t.)dd0fe ine13 < pu$ ic *oid 5n#ert0int index2 Cat fe ine1; Li#t.5n#ert0index2 fe ine13 < pu$ ic int 5ndexOf0Cat fe ine1; return Li#t.5ndexOf0fe ine13 < pu$ ic $oo Contain#0Cat fe ine1; return Li#t.Contain#0fe ine13 < pu$ ic *oid Re!o*e0Cat fe ine1; Li#t.Re!o*e0fe ine13 < pu$ ic *oid Copy'o0CatJK array2 int index1; Li#t.Copy'o0array2 index13 < pu$ ic #tatic *oid Gain01; CatLi#t c 9 ne. CatLi#t013 for 0int i 9 03 i W T3 iRR1 ; c .)dd0ne. Cat0i113 < //! Can't )dd0dog13 //! c .)dd0ne. :og0E113 < < <///:8 *te that i9 CatList had inherited directly 9r*+ 'rrayList, the +eth*d# that take re9erence# t* Cat#, #uch a# 'dd(Cat) !*uld #i+ply *verl*ad Gn*t *verrideH the ob)ectEaccepting +eth*d# Ge)g), 'dd( ob)ect) !*uld #till 3e availa3leH) Thu#, the CatList 3ec*+e# a surrogate t* the 'rrayList, per9*r+ing #*+e activitie# 3e9*re pa##ing *n the
444
Thinking in C
www.ThinkingIn.!et
re#p*n#i3ility G#ee Thinking in /atterns with ,a-a, d*!nl*ada3le at www.BruceEckel.comH) Becau#e a CatList !ill accept *nly a Cat, the line1 c .add0ne. :og0E113 !ill generate an err*r +e##age at com"ile9time) Thi# appr*ach, !hile +*re tedi*u# 9r*+ a c*ding #tandp*int, !ill tell y*u i++ediately i9 y*ure u#ing a type i+pr*perly) *te that n* ca#t i# nece##ary !hen u#ing it# al!ay# a Cat) et( ) *r the cu#t*+ inde;er R
I%nu#erators
-n any c*ntainer cla##, y*u +u#t have a !ay t* put thing# in and a !ay t* get thing# *ut) =9ter all, that# the pri+ary 4*3 *9 a c*ntainerRt* h*ld thing#) -n the 'rrayList, 'dd( ) and et( ) are *ne #et *9 !ay# t* in#ert and retrieve *34ect#) 'rrayList i# Duite 9le;i3leRy*u can #elect anything at any ti+e, and #elect +ultiple ele+ent# at *nce u#ing di99erent inde;e#) -9 y*u !ant t* #tart thinking at a higher level, there# a dra!3ack1 y*u need t* kn*! the e;act type *9 the c*ntainer in *rder t* u#e it) Thi# +ight n*t #ee+ 3ad at 9ir#t, 3ut !hat i9 y*u #tart *ut u#ing an 'rrayList, and later *n in y*ur pr*gra+ y*u decide that 3ecau#e *9 the !ay y*u are u#ing the c*ntainer, y*ud like t* #!itch y*ur c*de t* u#e a typed c*llecti*n de#cending 9r*+ CollectionBaseF Or #upp*#e y*ud like t* !rite a piece *9 generic c*de that d*e#nt kn*! *r care !hat type *9 c*ntainer it# !*rking !ith, #* that it c*uld 3e u#ed *n di99erent type# *9 c*ntainer# !ith*ut re!riting that c*deF The c*ncept *9 an enumerator G*r iteratorH can 3e u#ed t* achieve thi# a3#tracti*n) =n enu+erat*r i# an *34ect !h*#e 4*3 i# t* +*ve thr*ugh a #eDuence *9 *34ect# and #elect each *34ect in that #eDuence !ith*ut the client pr*gra++er kn*!ing *r caring a3*ut the underlying #tructure *9 that #eDuence) -n additi*n, an enu+erat*r i# u#ually !hat# called a IlightE !eightJ *34ect1 *ne that# cheap t* create) 5*r that rea#*n, y*ull *9ten
445
9ind #ee+ingly #trange c*n#traint# 9*r enu+erat*r#Q 9*r e;a+ple, #*+e iterat*r# can +*ve in *nly *ne directi*n) The ) ET B&numerator inter9ace i# an e;a+ple *9 the#e kind# *9 c*n#traint#) There# n*t +uch y*u can d* !ith *ne e;cept1 0) =#k a c*llecti*n G*r any *ther type that i+ple+ent# -Enu+era3leH t* hand y*u an B&numerator u#ing a +eth*d called et&numerator( )) Thi# B&numerator !ill 3e ready t* +*ve t* the 9ir#t ele+ent in the #eDuence *n y*ur 9ir#t call t* it# .ove,ext( ) +eth*d) 2) >et the current *34ect in the #eDuence !ith the Current pr*perty) /) =tte+pt t* +*ve t* the ne;t *34ect in #eDuence !ith the .ove,ext() +eth*d) -9 the enu+erat*r ha# reached the end *9 the #eDuence, thi# +eth*d return# false) &) Re#et t* it# initial #tate, !hich i# "rior t* the 9ir#t ele+ent Ge)g), y*u +u#t call .ove,ext() *nce 3e9*re reading the Current pr*pertyH) That# all) -t# a #i+ple i+ple+entati*n *9 an iterat*r, 3ut #till p*!er9ul) T* #ee h*! it !*rk#, let# revi#it the Cats'nd$ogs6cs pr*gra+ 9r*+ earlier in thi# chapter) -n the 9*ll*!ing +*di9ied ver#i*n, !eve re+*ved the errant d*g and u#e an B&numerator t* iterate *ver the li#t# c*ntent#1 //: c0>:Cat#)nd:og#2.c# // O#ing an exp icit 5+nu!erator u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 na!e#pace pet#; pu$ ic c a## Cat#)nd:og# ; pu$ ic #tatic *oid Gain01 ; )rrayLi#t cat# 9 ne. )rrayLi#t013 for 0int i 9 03 i W F3 iRR1 cat#.)dd0ne. Cat0i113 5+nu!erator e 9 cat#._et+nu!erator013 .hi e0e.Go*eCext01 !9 fa #e1; O$Dect c 9 e.Current3 00Cat1 c1.-rint013
446
Thinking in C
www.ThinkingIn.!et
< < < <///:8 :*u can #ee that the la#t 9e! line# n*! u#e an B&numerator t* #tep thr*ugh the #eDuence in#tead *9 a for l**p) ,ith the B&numerator, y*u d*nt need t* !*rry a3*ut the nu+3er *9 ele+ent# in the c*ntainer) Behind the #cene#, C## foreach() 3l*ck# d* an even 3etter 4*3 *9 iterating *ver an B&numerable type, #ince the foreach atte+pt# t* ca#t the ob)ect re9erence returned 9r*+ the enu+erat*r t* a #peci9ic type) -t d*e#nt +ake a l*t *9 #en#e t* u#e an B&numerator !hen y*u can u#e1 foreach0Cat c in cat#1; c.-rint013 <
Custo# Inde&ers
Previ*u#ly, !e #a! h*! B$ictionary type# all*! *ne t* u#e inde; n*tati*n t* acce## keyEvalue pair# u#ing n*nEnu+eric indice#) Thi# i# d*ne 3y u#ing *perat*r *verl*ading t* create a cu#t*+ inde;er) The typeE#a9e CatList c*llecti*n #h*!n in the di#cu##i*n *9 CollectionBase #h*!ed a cu#t*+ inde;er that t**k a nu+eric inde;, 3ut returned a Cat in#tead *9 an ob)ect re9erence) :*u can +anipulate 3*th inde; and return type# in a cu#t*+ inde;er, 4u#t a# !ith any *ther C# +eth*d) 5*r in#tance, i+agine a Aa7e !hich c*n#i#t# *9 R**+# c*nnected 3y C*rrid*r# in the R**+# !all#) -n #uch a #ituati*n, it +ight +ake #en#e t* have the C*rrid*r# 3e inde;ed 3y directi*n in the r**+1 //:c0>:Roo!.c# u#ing Sy#te!3 u#ing Sy#te!.Co
ection#3
44#
<3 c a## Roo! ; #tatic int counter 9 03 protected #tring na!e3 interna #tring Ca!e; get; return na!e3< < pu$ ic o*erride #tring 'oString01; return thi#.Ca!e3 < interna Roo!01; na!e 9 &Roo! (:& R counterRR3 < CorridorJK c 9 ne. CorridorJ +nu!._etNa ue#0typeof0:irection11.LengthK3 pu$ ic Corridor thi#J:irection dK; get ; return cJ0int1 dK3< #et ; cJ0int1 dK 9 *a ue3< < < c a## RegenSpot : Roo! ; interna RegenSpot01 : $a#e01; na!e 9 &Regen Spot&3 < < c a## -o.erOp : Roo! ; interna -o.erOp01 : $a#e01; na!e 9 &-o.er Op&3 < < <///:8 5ir#t, !e declare a $irection enu+erati*n c*rre#p*nding t* the cardinal p*int#) Then !e declare a R**+ cla## !ith an internal #tatic c*unter u#ed t* give each r**+ a uniDue na+e) The na+e i# +ade int* a pr*perty and i# al#* u#ed t* *verride the +o#tring() +eth*d t* 3e a little +*re #peci9ic a# t* the e;act r**+ !ere dealing !ith)
44&
Thinking in C
www.ThinkingIn.!et
Every *oom ha# an array called c that !ill h*ld re9erence# t* it# *ut3*und Corridors) =lth*ugh it !*uld 3e #h*rter t* 4u#t declare thi# array a# #i7e & G#ince !e kn*! that# h*! +any $irection# there areH, in#tead !e deter+ine the length *9 $irection 3y 9ir#t u#ing the #tatic +eth*d &num6 etHalues(), pa##ing it the $irection enu+erati*n# type, and then u#ing the Length pr*perty *9 the re#ulting array Gthi# !ay, !e c*uld acc*++*date *ctag*nal r**+# 3y #i+ply adding value# #uch a# ,orth=est t* $irectionH) The cu#t*+ inde;er i# ne;t and l**k# like thi#1 pu$ ic Corridor thi#J:irection dK; get ; return cJ0int1 dK3< #et ; cJ0int1 dK 9 *a ue3< < The 9ir#t line 3egin# !ith !hat l**k# like a n*r+al declarati*n *9 a pu3lic Pr*perty *9 type Corridor, 3ut the this<+ype t> that end# the line indicate# that it i# an cu#t*+er inde;er, in thi# ca#e *ne that take# a $irection value a# it# key and return# a Corridor) Since enu+# are value type# that de9ault t* 3eing repre#ented 3y integer c*n#tant# that #tart !ith 7er*, !e can #a9ely u#e the ca#t t* int t* create a nu+eric inde; t* the c array *9 Corridor#) Like a Pr*perty, a cu#t*+ inde;er# set +eth*d ha# a hidden para+eter called value) That 9ini#he# up the *oom cla##, 3ut !e declare t!* additi*nal type# t* inherit 9r*+ it P a *egen#pot and a !owerVp) They each di99er 9r*+ the 3a#e cla## #*lely in the !ay they #et up their ,ame pr*perty) The Corridor cla## re9erenced in *oom ha# *ne duty P +aintain re9erence# t* t!* di99erent *ooms and #upply a +raverse() 9uncti*n !hich return# !hichever *9 the t!* r**+# i#nt pa##ed in a# an argu+ent1 //:c0>:Corridor.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 na!e#pace La$yrinth; c a## Corridor ; Roo! x2 y3
44'
interna Corridor0 Roo! x2 :irection xVa Roo! y2 :irection yVa thi#.x 9 x3 thi#.y 9 y3 xJxVa K 9 thi#3 yJyVa K 9 thi#3 <
2 1;
pu$ ic Roo! 'ra*er#e0 Roo! origin2 :irection .a 1; Sy#te!.Con#o e.VriteLine0 &Lea*ing ;0< $y it# ;"< corridor&2 origin2 .a 13 if 0origin 99 x1 return y3 e #e return x3 < pu$ ic Roo! 'ra*er#e0Roo! origin1; Sy#te!.Con#o e.VriteLine0 &Retreating fro! & R origin13 if 0origin 99 x1 return y3 e #e return x3 < < <///:8 The Corridor() c*n#truct*r u#e# *oom# cu#t*+ inde;er# Ge)g), x<x=all> I thisFH) *te that there# n* pr*3le+ in re9erring t* this in#ide a c*n#truct*r)
45(
Thinking in C
www.ThinkingIn.!et
,hile !e called the+ r**+# and c*rrid*r#, !hat !eve really g*t here i# a non9directed gra"h) Here, IgraphJ i# 3eing u#ed in it# +athe+atical #en#e *9 Ia #et C *9 Certice# and a #et E *9 Edge# that c*nnect ele+ent# in C)J ,hat !eve de#igned in In*nEdirectedJ 3ecau#e *ur Corridor# can 3e traver#ed in either directi*n) = l*t *9 very intere#ting pr*3le+# can 3e +apped int* graph the*ry G*99 the t*p *9 the head, pr*3le+# #uch a#1 !inning a ga+e *9 che##, h*! 3e#t t* pack a c*ntainer, the +*#t e99icient !ay t* #chedule a 3unch *9 4*3#, and every*ne# 9av*rite, !hich i# the cheape#t r*ute 9*r a traveling #ale#per#*n t* vi#it a 3unch *9 citie#H) ,riting a cu#t*+ enu+erat*r G*r perhap# +*re than *ne, t* try *ut di99erent alg*rith+#H i# an elegant !ay t* traver#e a c*+ple; graph) -n thi# e;a+ple, !e create a #i+ple Aa7e that c*n#i#t# *9 *ne *egen#pot and *ne !owerVp, and #everal n*r+al r**+# Gthe na+e# are taken 9r*+ vide*ga+e# 9*r !hich *ne can pr*gra+ I3*t#J P 4u#t think *9 the+ a# the #tart and #t*p p*int#H1 //:c0>:GaMe.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 na!e#pace La$yrinth; c a## GaMe :5+nu!era$ e ; Roo!JK roo!#3 Roo! regenRoo!3
451
interna Roo! RegenSpot; get ; return regenRoo!3< < GaMe01; regenRoo! 9 ne. RegenSpot013 roo!# 9 ne. Roo!JK; ne. Roo!012 ne. Roo!012 ne. Roo!012 regenRoo!2 ne. Roo!012 ne. Roo!012 ne. -o.erOp01 <3 ne. Corridor0roo!#J0K2 :irection.ea#t2 roo!#JEK2 :irection.north13 ne. Corridor0roo!#J0K2 :irection.#outh2 roo!#J"K2 :irection.north13 ne. Corridor0roo!#J"K2 :irection.#outh2 roo!#JTK2 :irection.north13 ne. Corridor0roo!#J2K2 :irection.ea#t2 roo!#JTK2 :irection..e#t13 ne. Corridor0roo!#JTK2 :irection.ea#t2 roo!#JEK2 :irection..e#t13 ne. Corridor0roo!#JTK2 :irection.#outh2 roo!#JPK2 :irection.#outh13 ne. Corridor0roo!#JPK2 :irection.#outh2 roo!#J?K2 :irection.north13 < pu$ ic #tatic *oid Gain01; GaMe ! 9 ne. GaMe013 foreach0Roo! r in !1; Sy#te!.Con#o e.VriteLine0 &Roo!Runner in & R r.Ca!e13 < < pu$ ic 5+nu!erator _et+nu!erator01; return ne. :epthHir#t0thi#13 < < <///:8
45)
Thinking in C
www.ThinkingIn.!et
Cla## .aTe i# declared t* i+ple+ent the B&numerable inter9ace, !hich !ell u#e t* return a cu#t*+i7ed enu+erat*r !hich run# the +a7e) *te that 9*r *ur purp*#e#, !e d*nt care i9 the enu+erat*r vi#it# every verte; *n the graph Gevery r**+ in the +a7eHQ a# a +atter *9 9act, !ere pr*3a3ly +*#t intere#ted in an enu+erat*r !hich vi#it# a# 9e! vertice# a# p*##i3leK Thi# i# a di99erent intenti*n 9r*+ the generic enu+erat*r# *9 the ) ET c*llecti*n cla##e#, !hich *9 c*ur#e do need t* vi#it every ele+ent in the data #tructure) The .aTe c*ntain# an array rooms and a re9erence t* the #tarting *egen*oom) The +a7e# dyna+ic #tructure i# 3uilt in the .aTe() c*n#truct*r and c*n#i#t# *9 % *oom# and % Corridor#) The .ain() +eth*d c*n#truct# a .aTe and then u#e# a foreach 3l*ck t* #h*! the traver#al *9 the +a7e) Behind the #cene#, the foreach 3l*ck deter+ine# that .aTe i# an B&numerable type and #ilently call# et&numerator()) .aTe# i+ple+entati*n *9 B&numerable6 et&numerator() i# the 9inal +eth*d in .aTe) = ne! *34ect *9 type $epth:irst Gdi#cu##ed #h*rtlyH i# created !ith a re9erence t* the current .aTe) There are #everal di99erent !ay# t* traver#e a +a7e) -t i# pr*3a3le that !hen !riting a pr*gra+ t* run +a7e#, y*u !*uld !ant t* try #everal di99erent alg*rith+#, *ne that ru#hed headl*ng d*!n the 9ir#t une;pl*red c*rrid*r, an*ther that +eth*dically e;pl*red all the r*ute# 9r*+ a #ingle r**+, etc) H*!ever, each *9 the#e alg*rith+# ha# a l*t *9 thing# in c*++*n1 they +u#t all i+ple+ent the B&numerator inter9ace, they all have re9erence# t* the .aTe and a current *oom, they all 3egin at the regen #p*t and end at the p*!er up) Really, the *nly !ay they di99er i# in their i+ple+entati*n *9 B&numerator6.ove,ext() !hen theyre Il*#tJ in the +a7e) Thi# i# a 4*3 9*r the ITe+plate Aeth*dJ pattern1 //:c0>:Roo!Runner.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 na!e#pace La$yrinth; a$#tract c a## Roo!Runner:5+nu!erator ; GaMe !3 protected Roo!Runner0GaMe !1;
453
thi#.! 9 !3 < protected Roo! currentRoo! 9 nu pu$ ic O$Dect Current; get ; return currentRoo!3< < pu$ ic *irtua *oid Re#et01; currentRoo! 9 nu 3 < pu$ ic $oo Go*eCext01; if 0currentRoo! 99 nu 1 ; Sy#te!.Con#o e.VriteLine0 &;0< #tarting the !aMe&2 thi#._et'ype0113 currentRoo! 9 !.RegenSpot3 return true3 < if 0currentRoo! i# -o.erOp1 ; Sy#te!.Con#o e.VriteLine0 &;0< ha# found -o.erOp!&2 thi#._et'ype0113 return fa #e3 < return thi#.ConcreteGo*eCext013 < protected a$#tract $oo < <///:8 Here, an abstract cla## called *oom*unner i+ple+ent# the +eth*d# *9 the B&numerator inter9ace, 3ut leave# *ne tiny 3it t* it# #u3cla##e# t* i+ple+ent) The R**+RunnerGH c*n#truct*r 4u#t #t*re# a re9erence t* the .aTe that create# it and initiali7e# the current*oom Ge;p*#ed t* the *ut#ide !*rld a# B&numerator# Current Pr*pertyH t* null) *eset() al#* #et# the ConcreteGo*eCext013 3
454
Thinking in C
www.ThinkingIn.!et
current*oom t* null P re+e+3er that B&numerator6.ove,ext() i# al!ay# called *nce 2e$ore the 9ir#t read *9 the Current pr*perty) The 9ir#t ti+e *oom*unner6.ove,ext() i# called, current*oom !ill 3e null) Becau#e *oom*unner i# an a3#tract type that +ay 3e i+ple+ented 3y +any di99erent #u3type#, *ur c*n#*le +e##age can u#e this6 et+ype() t* deter+ine the e;act runti+e type *9 *oom*unner) GThe trick at the r**t *9 the Ite+plate +eth*dJ pattern)H =9ter printing a +e##age t* the #creen ann*uncing the *oom*unner# readine## t* #tart traver#ing the .aTe, the current r**+ i# #et t* the .aTe# *egen#pot and the +eth*d return# true t* indicate that the B&numerator i# at the 3eginning *9 the data #tructure) Si+ilarly, i9 the current*oom i# *9 type !owerVp, the +a7e running i#, 3y *ur de9initi*n, c*+plete and .ove,ext() return# 9al#e) -9, h*!ever, the currentR**+ i# neither null n*r a P*!erUp r**+, e;ecuti*n g*e# t* this6Concrete.ove,ext()) Thi# i# the te+plate +eth*d) "u#t a# this6 et+ype() !ill return the e;act runti+e type, this6Concrete.ove,ext() !ill e;ecute the Concrete.ove,ext() +eth*d *9 the runti+e type) 5*r thi# t* !*rk, *9 c*ur#e, *oom*unner6Concrete.ove,ext() +u#t 3e declared a# virtual *r, a# in thi# ca#e, abstract) .aTe6 et&numerator() returned an *34ect *9 type $epth:irst, !hich i+ple+ent# *oom*unner# te+plate +eth*d Concrete.ove,ext()1 //:c0>::epthHir#t.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 na!e#pace La$yrinth; c a## :epthHir#t : Roo!Runner ; pu$ ic :epthHir#t0GaMe !1 : $a#e0!1;< )rrayLi#t *i#itedCorridor# 9 ne. )rrayLi#t013 Corridor a#tCorridor 9 nu 3 protected o*erride $oo ConcreteGo*eCext01; foreach0:irection d in +nu!._etNa ue#0typeof0:irection111;
455
if 0currentRoo!JdK !9 nu 1 ; Corridor c 9 currentRoo!JdK3 if 0*i#itedCorridor#.Contain#0c1 99 fa #e1 ; *i#itedCorridor#.)dd0c13 a#tCorridor 9 c3 currentRoo! 9 c.'ra*er#e0currentRoo!2 d13 return true3 < < < //Co un*i#ited corridor#! Retreat! a#tCorridor.'ra*er#e0currentRoo!13 return true3 < < <///:8 ?epth5ir#t inherit# 9r*+ Ba#eRunner, a# it# cla## declarati*n and c*n#truct*r #h*!) Thi# particular +a7e runner e##entially g*e# d*!n the 9ir#t c*rrid*r it #ee# that it ha#nt yet g*ne thr*ugh) -9 there are n*ne it ha#nt 3een d*!n, it 3acktrack# t* the previ*u# r**+) UhE*h P !hat i9 it 3acktrack# int* a r**+ and that r**+ d*e#nt have any unvi#ited c*rrid*r#F L**k# like a de9ectK But *n *ur +a7e, the ?epth5ir#t !*rk# like a cha+p1
456
Thinking in C
www.ThinkingIn.!et
45#
for 0int i 9 03 i W 2P3 iRR1 ; char c 9 0char1 0')' R i13 i#t.)dd0c13 < < pri*ate #tatic *oid -rint0)rrayLi#t i#t1; foreach0O$Dect o in i#t1; Sy#te!.Con#o e.Vrite0o R &2 &13 < Sy#te!.Con#o e.VriteLine013 < pri*ate #tatic *oid Shuff e0)rrayLi#t int en 9 i#t.Count3 for 0int i 9 03 i W en3 iRR1 ; int % 9 rand.Cext0 en13 O$Dect te!p 9 i#tJiK3 i#tJiK 9 i#tJ%K3 i#tJ%K 9 te!p3 < < #tatic Rando! rand 9 ne. Rando!013 pu$ ic #tatic *oid Gain01 ; )rrayLi#t i#t 9 ne. )rrayLi#t013 Hi 0 i#t13 -rint0 i#t13 Shuff e0 i#t13 Sy#te!.Con#o e.VriteLine0&)fter #huff ing: &13 -rint0 i#t13 i#t.Re*er#e013 Sy#te!.Con#o e.VriteLine0&Re*er#ed: &13 -rint0 i#t13 i#t.Sort013 Sy#te!.Con#o e.VriteLine0&)fter #orting: &13 -rint0 i#t13 O$Dect %ey 9 i#tJ"2K3 int index 9 i#t.BinarySearch0%ey13 Sy#te!.Con#o e.VriteLine0 i#t1;
45&
Thinking in C
www.ThinkingIn.!et
&Location of ;0< i# ;"<2 i#tJ;2<K 9 ;T<&2 %ey2 index2 index2 i#tJindexK13 < < ///:8 The u#e *9 the#e +eth*d# i# identical t* the static *ne# in 'rray, 3ut are in#tance +eth*d# *9 'rrayList) Thi# pr*gra+ al#* c*ntain# an i+ple+entati*n *9 ?*nald Nnuth# #hu99ling alg*rith+ t* rand*+i7e the *rder *9 a List)
45'
< < <///:8 =9ter initiali7ing an 'rrayList, !e u#e a rand*+ nu+3er generat*r t* ch**#e t* add 3et!een 0$ and 06 ite+#) ,e l**p, u#ing list6'dd() t* add rand*+ nu+3er# 3et!een $ and 66) Then, !e ch**#e a rand*+ nu+3er t* indicate !here in the array !e !i#h t* 3egin c*pying) ,e then declare and initiali7e the array, !hich +u#t 3e #i7ed t* acc*++*date index:orCopy#tart e+pty integer# G#ince it# an array *9 int#, the#e !ill 3e initiali7ed t* $H and list6Count integer# 9r*+ the 'rrayList) The Copy+o() +eth*d take# t!* para+eter# P the re9erence t* the de#tinati*n array and the #tarting inde; 9*r the c*py) ,e then l**p *ver the array, *utputting the c*ntent#) Since integer# are value type#, +*di9ying value# in the de#tinati*n array !ill n*t 3e re9lected in the 'rrayList list) H*!ever, re9erence type# !*uld naturally have the #a+e I#hall*! c*pyJ i##ue# that are di#cu##ed in #re9 t* #hall*! c*py di#cu##i*n)# Since B$ictionary inherit# 9r*+ BCollection, i+ple+enting type# +u#t #upp*rt Copy+o()) The re#ult# are an array *9 $ictionary&ntry ite+#1 //:c0>::ictionary'o)rray.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 c a## :ictionary'o)rray; pu$ ic #tatic *oid Gain01; 5:ictionary dict 9 ne. Ua#hta$ e013 Rando! r 9 ne. Rando!013 int iaey# 9 T R r.Cext0T13 for0int i 9 03 i W iaey#3 iRR1; dict.)dd0i2 r.Cext0"00113 < :ictionary+ntryJK a 9 ne. :ictionary+ntryJdict.CountK3 dict.Copy'o0a2 013 for0int i 9 03 i W a.Length3 iRR1; :ictionary+ntry de 9 aJiK3 Sy#te!.Con#o e.VriteLine0
46(
Thinking in C
www.ThinkingIn.!et
&aJ;0<K: .aey 9 ;"< .Na ue 9 ;2<&2 i2 de.aey2 de.Na ue13 < < <///:8 = typical run l**k# like1 aJ0K: .aey 9 E .Na ue 9 "" aJ"K: .aey 9 T .Na ue 9 P aJ2K: .aey 9 2 .Na ue 9 ? aJTK: .aey 9 " .Na ue 9 >T aJEK: .aey 9 0 .Na ue 9 E :*ull n*te that the re#ulting array i# n*t #*rted *n the value *9 the key, !hich +ight 3e de#ira3le, 3ecau#e B$ictionary d*e#nt reDuire key# t* 3e BComparable) H*!ever, they *9ten are and, i9 #*, it !*uld pr*3a3ly 3e nice i9 the re#ulting array !ere *rdered 3y key) Thi# pr*gra+ de+*n#trate# a techniDue t* get thi# re#ult1 //:c0>::ictionary'oSorted)rray.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 c a## :ictionary'o)rray; pu$ ic #tatic *oid Gain01; 5:ictionary dict 9 ne. Ua#hta$ e013 Rando! r 9 ne. Rando!013 int iaey# 9 T R r.Cext0T13 for0int i 9 03 i W iaey#3 iRR1; dict.)dd0i2 i13 < //Hir#t2 get array of %ey# 5Co ection %eyCo 9 dict.aey#3 5Co!para$ eJK %ey)rray 9 ne. 5Co!para$ eJ%eyCo .CountK3 //Vou d thro. exception if %ey# not 5Co!para$ e %eyCo .Copy'o0%ey)rray2 013 //Second2 get array of *a ue# 5Co ection *a Co 9 dict.Na ue#3 O$DectJK *a )rray 9 ne. O$DectJ*a Co .CountK3
461
*a Co .Copy'o0*a )rray2 013 )rray.Sort0%ey)rray2 *a )rray13 //5n#tantiate de#tination array :ictionary+ntryJK a 9 ne. :ictionary+ntryJ%eyCo .CountK3 //Retrie*e and #et in %ey6#orted order for0int i 9 03 i W a.Length3 iRR1; aJiK 9 ne. :ictionary+ntry013 aJiK.aey 9 %ey)rrayJiK3 aJiK.Na ue 9 *a )rrayJiK3 < //Output re#u t# for0int i 9 03 i W a.Length3 iRR1; :ictionary+ntry de 9 aJiK3 Sy#te!.Con#o e.VriteLine0 &aJ;0<K: .aey 9 ;"< .Na ue 9 ;2<&2 i2 de.aey2 de.Na ue13 < < <///:8 The pr*gra+ #tart# *99 #i+ilarly t* the previ*u# e;a+ple#, !ith a 9e! keyE value pair# 3eing in#erted int* a "ashtable) -n#tead *9 directly c*pying t* the de#tinati*n array, th*ugh, !e retrieve the BCollection *9 key#) BCollection d*e#nt have any #*rting capa3ilitie#, #* !e u#e Copy+o() t* +*ve the key# int* an BComparable<> array) -9 any *9 *ur key# did not i+ple+ent BComparable, thi# !*uld thr*! an BnvalidCast&xception) The ne;t #tep i# t* c*py the value# 9r*+ the "ashtable int* an*ther array, thi# ti+e *9 type ob)ect<>) ,e then u#e 'rray6#ort('rray, 'rray), !hich #*rt# 2oth it# input array# 3a#ed *n the c*+pari#*n# in the 9ir#t array, !hich in *ur ca#e i# the key array) -n general, *ne #h*uld av*id a #ituati*n !here *ne change# the #tate *9 *ne *34ect G#uch a# the array *9 value#H 3a#ed *n l*gic internal t* an*ther *34ect G#uch a# the #*rting *9 the array *9 key#HQ a #ituati*n that# called logical cohesion) ,e c*uld av*id u#ing 'rray6#ort('rray, 'rray) 3y #*rting (ey'rray and then u#ing a foreach( ob)ect (ey in (ey'rray) l**p t* retrieve the value# 9r*+ the
46)
Thinking in C
www.ThinkingIn.!et
Ha#hta3le, 3ut in thi# ca#e that# cl*#ing the 3arn d**r a9ter the h*r#e# have 9led P the ) ET 5ra+e!*rk d*e# n*t have an B$ictionary !hich +aintain# it# *34ect# in key *rder, !hich !*uld 3e the 3e#t #*luti*n 9*r the general de#ire t* +*ve 3et!een an B$ictionary and a #*rted array) -n keeping !ith it# #ingular nature, ,ameHalueCollection6Copy+o() d*e# n*t act like "ashtable6Copy+o()) ,here "ashtable6Copy+o() create# an array *9 $ictionary&ntry *34ect# that c*ntain 3*th the key and value, ,ameHalueCollection# Copy+o() +eth*d create# an array *9 string# !hich repre#ent the value# in a c*++aE#eparated 9*r+at, !ith n* re9erence t* the key#) -t# di99icult t* i+agine the utility *9 thi# 9*r+at) Thi# e;a+ple 3uild# a +*re rea#*na3le array 9r*+ a a+eCalueC*llecti*n1 //:c0>:CNa Co 'o)rray.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 u#ing Sy#te!.Co ection#.Specia iMed3 c a## Ca!eNa ueCo ection+ntry : 5Co!para$ e; #tring %ey3 pu$ ic #tring aey; get ; return %ey3 < < #tringJK *a ue#3 pu$ ic #tringJK Na ue#; get ; return *a ue#3 < < pu$ ic Ca!eNa ueCo ection+ntry0 #tring %ey2 #tringJK *a ue#1; thi#.%ey 9 %ey3 thi#.*a ue# 9 *a ue#3 < pu$ ic int Co!pare'o0O$Dect o1; if0o i# Ca!eNa ueCo ection+ntry1; Ca!eNa ueCo ection+ntry that 9
463
0Ca!eNa ueCo ection+ntry1 o3 return thi#.aey.Co!pare'o0that.aey13 < thro. ne. )rgu!ent+xception013 < pu$ ic #tatic Ca!eNa ueCo ection+ntryJK Hro!Ca!eNa ueCo ection0Ca!eNa ueCo ection #rc1; #tringJK %ey# 9 #rc.) aey#3 Ca!eNa ueCo ection+ntryJK re#u t# 9 ne. Ca!eNa ueCo ection+ntryJ%ey#.LengthK3 for0int i 9 03 i W %ey#.Length3 iRR1; #tring %ey 9 %ey#JiK3 #tringJK *a # 9 #rc._etNa ue#0%ey13 Ca!eNa ueCo ection+ntry entry 9 ne. Ca!eNa ueCo ection+ntry0%ey2 *a #13 re#u t#JiK 9 entry3 < return re#u t#3 < < c a## CNa Co 'o)rray; pu$ ic #tatic *oid Gain01; Ca!eNa ueCo ection dict 9 ne. Ca!eNa ueCo ection013 Rando! r 9 ne. Rando!013 int iaey# 9 T R r.Cext0T13 for0int i 9 03 i W iaey#3 iRR1; int iNa #'o)dd 9 P R r.Cext0P13 for0int D 9 03 D W iNa #'o)dd3 DRR1; dict.)dd0i.'oString012 r.Cext0"001.'oString0113 < < Ca!eNa ueCo ection+ntryJK a 9 Ca!eNa ueCo ection+ntry. Hro!Ca!eNa ueCo ection0dict13
464
Thinking in C
www.ThinkingIn.!et
)rray.Sort0a13 for0int i 9 03 i W a.Length3 iRR1; Sy#te!.Con#o e.VriteLine0 &aJ;0<K.aey 9 ;"<&2 i2 aJiK.aey13 foreach0#tring * in aJiK.Na ue#1; Sy#te!.Con#o e.VriteLine0 &^t Na ue: & R *13 < < < <///:8 ,e de9ine a ne! type, ,ameHalueCollection&ntry !hich c*rre#p*nd# t* the $ictionary&ntry *9 "ashtable) Like that type, *ur ne! type ha# a Eey and a Halue pr*perty, 3ut the#e are *9 type string and string<> re#pectively) Becau#e !e kn*! that the Eey i# al!ay# g*ing t* 3e a string, !e can declare ,ameHalueCollection&ntry t* i+ple+ent BComparable and i+ple+ent that #i+ply 3y c*+paring Eey pr*pertie# Gi9 the para+eter t* Compare+o() i# n*t a ,ameHalueCollection&ntry, !e thr*! an 'rgument&xceptionH) The #tatic :rom,ameHalueCollection() +eth*d i# !here !e c*nvert a ,ameHalueCollection int* an array *9 ,ameHalueCollection&ntry#) 5ir#t, !e get a string<> *9 key# 9r*+ the 'llEeys pr*perty *9 the input para+eter Gi9 !e had u#ed the Eeys pr*perty, !e !*uld have received the #a+e data, 3ut in an ob)ect arrayH) The Length pr*pery *9 the (eys all*!# u# t* #i7e the results array) The etHalues() +eth*d *9 ,ameHalueCollection return# a string array, !hich al*ng !ith the string key, i# !hat !e need t* in#tantiate a #ingle ,ameHalueCollection&ntry) Thi# entry i# added t* the results !hich are returned !hen the l**p end#) Cla## ,HalCol+o'rray de+*n#trate# the u#e *9 thi# ne! cla## !eve !ritten) = ,ameHalueCollection i# created and each entry i# 9illed !ith a rand*+ nu+3er *9 #tring#) = ,ameHalueCollection&ntry array called a i# generated u#ing the #tatic 9uncti*n 4u#t di#cu##ed) Since !e i+ple+ented BComparable in ,ameHalueCollection&ntry, !e can u#e 'rray6#ort() t* #*rt the re#ult# 3y the Eey string#) 5*r each ,ameHalueCollection&ntry, !e *utput the Eey, retrieve the string<>
465
Halues, and *utput the+ t* the c*n#*le) ,e c*uld, *9 c*ur#e, #*rt the Halues a# !ell, i9 that !a# de#ired)
Persistent 4ata With )4O.(%,hile c*llecti*n cla##e# and data #tructure# re+ain i+p*rtant t* inE +e+*ry +anipulati*n *9 data, *99line #t*rage i# d*+inated 3y thirdEparty vend*r# #upp*rting the relati*nal +*del *9 data #t*rage) O9 c*ur#e, Oracle# ep*ny+*u# pr*duct d*+inate# the highEend +arket, !hile Aicr*#*9t# SML Server and -BA# ?B2 are a3le c*+petit*r# 9*r enterpri#e data) There are hundred# *9 data3a#e# appr*priate 9*r #+aller pr*4ect#, the +*#t !ellEdi#tri3uted *9 !hich i# Aicr*#*9t# =cce##) Aean!hile, the #ucce## *9 the ,e3 +ade +any pe*ple c*+9*rta3le !ith the c*ncept that I4u#tJ te;tE3a#ed #trea+# +arked !ith hu+anEreada3le tag# !ere #u99iciently p*!er9ul t* create a l*t *9 endEu#er value) E;ten#i3le Aarkup Language GBALH ha# e;pl*ded in p*pularity in the ne! +illenniu+ and i# rapidly 3ec*+ing the pre9erred inE+e+*ry repre#entati*n *9 relati*nal data) Thi# !ill 3e di#cu##ed in depth in chapter #BAL#, 3ut #*+e di#cu##i*n *9 BAL i# relevant t* any di#cu##i*n *9 =ctive ?ata O34ect# 9*r ) ET G=?O) ETH) Like graphic# pr*gra++ing, the c*+plete ga+ut *9 data3a#e pr*gra++ing detail# cann*t 3e adeDuately c*vered in le## than an entire 3**k) H*!ever, al#* like graphic# pr*gra++ing, +*#t pr*gra++er# d* n*t need t* kn*! +*re than the 3a#ic#) -n the ca#e *9 data3a#e pr*gra++ing, 66^ *9 the !*rk 3*il# d*!n t* 3eing a3le t* Create, Read, Update, and ?elete data P the 9uncti*n# kn*!n a# ICRU?)J Thi# #ecti*n trie# t* deliver the minimum a+*unt *9 in9*r+ati*n y*u need t* 3e a3le t* u#e =?O) ET in a pr*9e##i*nal #etting) =lth*ugh CRU? +ay encap#ulate +any pr*gra++er# intent 9*r =?O) ET, there# an*ther I?J that i# 9unda+ental t* =?O) ET P I?i#c*nnected)J -r*nically, the +*re the ,*rld ,ide ,e3 3ec*+e# truly u3iDuit*u#, the +*re di99icult it i# t* create #*luti*n# 3a#ed *n c*ntinu*u# c*nnecti*n#) The client #*9t!are that i# running in a !idely di#tri3uted
466
Thinking in C
www.ThinkingIn.!et
applicati*n, i)e), an applicati*n that i# running *ver the -nternet, #i+ply cann*t 3e c*unted *n t* g* thr*ugh an *rderly, ti+ely li9ecycle *9 Ic*nnect, gain e;clu#ive acce## t* data, c*nduct tran#acti*n#, and di#c*nnect)J Si+ilarly, alth*ugh c*ntinu*u# net!*rk acce## +ay 3e the rule in c*rp*rate #etting#, the c*+ing year# are g*ing t* #ee an e;pl*#i*n in applicati*n# 9*r +*3ile device#, #uch a# handheld# and teleph*ne#, !hich have +etered c*#t#Q ec*n*+ic# dictate that #uch applicati*n# cann*t 3e c*n#tantly c*nnected) =?O) ET #eparate# the ta#k# *9 actually acce##ing the data #t*re 9r*+ the ta#k# *9 +anipulating the re#ulting #et *9 data) The 9*r+er *3vi*u#ly reDuire a c*nnecti*n t* the #t*re !hile the latter d* n*t) Thi# #eparati*n# *9 c*ncern# help# !hen c*nverting data 9r*+ *ne data #t*re t* an*ther G#uch a# c*nverting data 3et!een relati*nal ta3le data and BALH a# !ell a# +aking it +uch ea#ier t* pr*gra+ !idelyEdi#tri3uted data3a#e applicati*n#) H*!ever, thi# +*del increa#e# the p*##i3ility that t!* u#er# !ill +ake inc*+pati3le +*di9icati*n# t* related data P theyll 3*th re#erve the la#t #eat *n the 9light, *ne !ill +ark an i##ue a# re#*lved !hile the *ther !ill e;pand the #c*pe *9 the inve#tigati*n, etc) S* even a +ini+al intr*ducti*n t* =?O) ET reDuire# #*+e di#cu##i*n *9 the i##ue# *9 c*ncurrency vi*lati*n#)
46#
u#ing Sy#te!.:ata3 c a## Ba#ic:ataSetOperation# ; pu$ ic #tatic *oid Gain0#tringJK arg#1; :ataSet d# 9 Bui d:ataSet013 -rint:ataSetCharacteri#tic#0d#13 < pri*ate #tatic :ataSet Bui d:ataSet01 ; :ataSet d# 9 ne. :ataSet0&Goc%:ataSet&13 :ata'a$ e au'a$ e 9 ne. :ata'a$ e0&)uthor#&13 d#.'a$ e#.)dd0au'a$ e13 :ataCo u!n na!eCo 9 ne. :ataCo u!n0&Ca!e&2 typeof0#tring113 au'a$ e.Co u!n#.)dd0na!eCo 13 :ataRo. arryRo. 9 au'a$ e.Ce.Ro.013 arryRo.J&Ca!e&K 9 &Larry&3 au'a$ e.Ro.#.)dd0 arryRo.13 :ataRo. $ruceRo. 9 au'a$ e.Ce.Ro.013 $ruceRo.J&Ca!e&K 9 &Bruce&3 au'a$ e.Ro.#.)dd0$ruceRo.13 return d#3 < pri*ate #tatic *oid -rint:ataSetCharacteri#tic#0 :ataSet d#1; Sy#te!.Con#o e.VriteLine0 &:ataSet ^&;0<^& ha# ;"< ta$ e#&2 d#.:ataSetCa!e2 d#.'a$ e#.Count13 foreach0:ata'a$ e ta$ e in d#.'a$ e#1; Sy#te!.Con#o e.VriteLine0 &'a$ e ^&;0<^& ha# ;"< co u!n#&2 ta$ e.'a$ eCa!e2 ta$ e.Co u!n#.Count13 foreach0:ataCo u!n co in ta$ e.Co u!n#1; Sy#te!.Con#o e.VriteLine0 &Co u!n ^&;0<^& contain# data of type ;"<&2
46&
Thinking in C
www.ThinkingIn.!et
co .Co u!nCa!e2 co .:ata'ype13 < Sy#te!.Con#o e.VriteLine0 &'he ta$ e contain# ;0< ro.#&2 ta$ e.Ro.#.Count13 foreach0:ataRo. r in ta$ e.Ro.#1; Sy#te!.Con#o e.Vrite0&Ro. :ata: &13 foreach0:ataCo u!n co in ta$ e.Co u!n#1; #tring co Ca!e 9 co .Co u!nCa!e3 Sy#te!.Con#o e.Vrite0 &J;0<K 9 ;"<&2 co Ca!e2 rJco Ca!eK13 < Sy#te!.Con#o e.VriteLine013 < < < <///:8 The ) ET cla##e# related t* $ata#ets are in the #ystem6$ata na+e#pace, #* naturally !e have t* include a using #tate+ent at the 3eginning *9 the pr*gra+) The .ain() +eth*d i# #traight9*r!ard, it call# Build$ata#et() and pa##e# the *34ect returned 3y that +eth*d t* an*ther #tatic +eth*d called !rint$ata#etCharacteristics()) Build$ata#et() intr*duce# #everal ne! cla##e#) 5ir#t c*+e# a $ata#et, u#ing a c*n#truct*r that all*!# u# t* #i+ultane*u#ly na+e it IA*ck?ataSet)J Then, !e declare and initiali7e a $ata+able called I=uth*rJ !hich !e re9erence !ith the au+able varia3le) $ata#et *34ect# have a +ables pr*perty *9 type $ata+ableCollection, !hich i+ple+ent# BCollection) ,hile $ata+ableCollection d*e# n*t i+ple+ent BList, it c*ntain# #*+e #i+ilar +eth*d#, including 'dd, !hich i# u#ed here t* add the ne!ly created au+able t* ds# +ables) $ataColumn#, #uch a# the nameCol in#tantiated in the ne;t line, are a##*ciated !ith a particular $ata+ype) $ata+ype# are n*t nearly a# e;ten#ive *r e;ten#i3le a# n*r+al type#) Only the 9*ll*!ing can 3e #peci9ied a# a $ata+ype1
46'
B**lean Byte Char ?ateTi+e ?eci+al ?*u3le -nt0. -nt/2 -nt.& SByte Single String Ti+eSpan U-nt0. U-nt/2 U-nt.& -n thi# ca#e, !e #peci9y that the I a+eJ c*lu+n #h*uld #t*re #tring#) ,e add the c*lu+n t* the Columns c*llecti*n Ga $ataColumnCollectionH *9 *ur au+able) One cann*t create r*!# *9 data u#ing a #tandard c*n#truct*r, a# a r*!# #tructure +u#t c*rre#p*nd t* the Columns c*llecti*n *9 a particular $ata+able) -n#tead, $ata*ow# are c*n#tructed 3y u#ing the ,ew*ow() +eth*d *9 a particular $ata+able) Here, au+able6,ew*ow() return# a $ata*ow appr*priate t* *ur I=uth*rJ ta3le, !ith it# #ingle I a+eJ c*lu+n) $ata*ow d*e# n*t i+ple+ent BCollection, 3ut d*e# *verl*ad the inde;ing *perat*r, #* a##igning a
4#(
Thinking in C
www.ThinkingIn.!et
value t* a c*lu+n i# a# #i+ple a# #aying1 arryRo.J&Ca!e&K 9 &Larry&. The re9erence returned 3y ,ew*ow() i# not aut*+atically in#erted int* the $ata+able !hich generate# it, that i# d*ne 3y1 au'a$ e.Ro.#.)dd0 arryRo.13 =9ter creating an*ther r*! t* c*ntain Bruce# na+e, the $ata#et i# returned t* the .ain() +eth*d, !hich pr*+ptly pa##e# it t* !rint$ata#etCharacteristics()) The *utput i#1 :ataSet &Goc%:ataSet& ha# " ta$ e# 'a$ e &)uthor#& ha# " co u!n# Co u!n &Ca!e& contain# data of type Sy#te!.String 'he ta$ e contain# 2 ro.# Ro. :ata: JCa!eK 9 Larry Ro. :ata: JCa!eK 9 Bruce
Connecting to a data+ase
The ta#k *9 actually +*ving data in and *ut *9 a #t*re Geither a l*cal 9ile *r a data3a#e #erver *n the net!*rkH i# the ta#k *9 the B$bConnection inter9ace) Speci9ying !hich data G9r*+ all the ta3le# in the underlying data3a#eH i# the re#p*n#i3ility *9 *34ect# !hich i+ple+ent -?3C*++and) =nd 3ridging the gap 3et!een the#e c*ncern# and the c*ncern# *9 the $ata#et i# the re#p*n#i3ility *9 the B$b'dapter inter9ace) Thu#, !hile $ata#et and the cla##e# di#cu##ed in the previ*u# e;a+ple encap#ulate the I!hatJ *9 the relati*nal data, the B$ata'dapter, B$bCommand, and B$bConnection encap#ulate the IH*!J1
4#1
The ) ET 5ra+e!*rk currently #hip# !ith t!* managed "ro-iders that B$ata'dapter and it# related cla##e#) One i# highEper9*r+ance pr*vider *pti+i7ed 9*r Aicr*#*9t SML ServerQ it i# l*cated in the Sy#te+)?ata)SDlClient na+e#pace) The *ther pr*vider, in the Sy#te+)?ata)Ole?3 na+e#pace, i# 3a#ed *n the 3r*adly availa3le Aicr*#*9t "ET engine G!hich #hip# a# part *9 ,ind*!# BP and i# d*!nl*ada3le 9r*+ Aicr*#*9t# ,e3#iteH) =dditi*nally, y*u can d*!nl*ad an O?BCE#uppp*rting +anaged pr*vider 9r*+ +#dn)+icr*#*9t)c*+) One #u#pect# that highEper9*r+ance +anaged pr*vider# 9*r Oracle, ?B2, and *ther highEend data3a#e# !ill Duietly 3ec*+e availa3le a# ) ET 3egin# t* achieve #igni9icant +arket #hare) 5*r the #a+ple# in thi# chapter, !ere g*ing t* u#e the Ole?3 cla##e# t* read and !rite an =cce## data3a#e, 3ut !ere g*ing t* upca#t everything t* the =?O) ET inter9ace# #* that the c*de i# a# general a# p*##i3le) The I *rth!indJ data3a#e i# a #a+ple data3a#e 9r*+ Aicr*#*9t that y*u can d*!nl*ad 9r*+ http1<<+#dn)+icr*#*9t)c*+<d*!nl*ad# i9 y*u d*nt already have it *n y*ur hardEdrive 9r*+ in#talling Aicr*#*9t =cce##) The 9ile i# called In!ind)+d3J) Unlike !ith enterpri#e data3a#e#, there i# n* need t* run a data3a#e #erver t* c*nnect t* and +anipulate an =cce## data3a#e) Once y*u have the 9ile y*u can 3egin +anipulating it !ith ) ET c*de) Thi# 9ir#t e;a+ple #h*!# the 3a#ic #tep# *9 c*nnecting t* a data3a#e and 9illing a data#et1
4#)
Thinking in C
www.ThinkingIn.!et
//:c0>::BConnect.c# u#ing Sy#te!.:ata3 u#ing Sy#te!.:ata.O e:$3 c a## Ba#ic:ataSetOperation# ; pu$ ic #tatic *oid Gain0#tringJK arg#1; :ataSet d# 9 +!p oyee#0&C.ind.!d$&13 Sy#te!.Con#o e.VriteLine0 &:S fi ed .ith ;0< ro.#&2 d#.'a$ e#J0K.Ro.#.Count13 < pri*ate #tatic :ataSet +!p oyee#0 #tring fi eCa!e1; 5:$Connection cnctn 9 ne. O e:$Connection013 cnctn.ConnectionString9 &-ro*ider9Gicro#oft.`+'.OL+:B.E.03& R &data #ource9& R fi eCa!e3 try ; cnctn.Open013 #tring #e Str 9 &S+L+C' = HROG +G-LO/++S&3 5:ata)dapter adapter 9 ne. O e:$:ata)dapter0#e Str2 cnctn13 :ataSet d# 9 ne. :ataSet0&+!p oyee#&13 adapter.Hi 0d#13 < fina y ; cnctn.C o#e013 < return d#3 < <///:8 =9ter #peci9ying that !ell 3e u#ing the Sy#te+)?ata and Sy#te+)?ata)Ole?3 na+e#pace#, the .ain() initiali7e# a $ata#et !ith the re#ult# *9 a call t* the #tatic 9uncti*n &mployees()) The nu+3er *9 r*!# in the 9ir#t ta3le *9 the re#ult i# printed t* the c*n#*le) The +eth*d &mployees() take# a #tring a# it# para+eter in *rder t* clari9y the part *9 the c*nnecti*n #tring that i# varia3le) -n thi# ca#e, y*ull
4#3
*3vi*u#ly have t* +ake #ure that the 9ile I !ind)+d3J i# in the current direct*ry *r +*di9y the call appr*priately) -n *rder t* e+pha#i7e that =?O) ET pr*vide# a3#tract data type# 9*r data3a#e c*nnecti*n, a9ter initiali7ing an 1le$bConnection !e upca#t the re#ult t* the B$bConnection inter9ace) The Connection#tring pr*perty i# #et t* a 3are +ini+u+1 the na+e *9 the pr*vider !e intend t* u#e and the data #*urce) Thi# i# all !e need t* c*nnect t* the *rth!ind data3a#e, 3ut enterpri#e data3a#e# !ill *9ten have #igni9icantly +*re c*+ple; c*nnecti*n #tring#) The call t* cnctn61pen() #tart# the actual pr*ce## *9 c*nnecting t* the data3a#e, !hich in thi# ca#e i# a l*cal 9ile read 3ut !hich !*uld typically 3e *ver the net!*rk) Becau#e data3a#e c*nnecti*n# are the pr*t*typical Ivalua3le n*nE+e+*ry re#*urce,J a# di#cu##ed in Chapter #E;cepti*n##, !e put the c*de that interact# !ith the data3a#e in#ide a try`finally 3l*ck) =# !e #aid, the B$ata'dapter i# the 3ridge 3et!een the Ih*!J *9 c*nnecting t* a data3a#e and the I!hatJ *9 a particular relati*nal vie! int* that data) The 3ridge g*ing 9r*+ the data3a#e t* the $ata#et i# the :ill() +eth*d G!hile the 3ridge 9r*+ the $ata#et t* the data3a#e i# the Vpdate() +eth*d !hich !ell di#cu## in *ur ne;t e;a+pleH) H*! d*e# the B$ata'dapter kn*! !hat data t* put int* the $ata#etF The an#!er i# actually n*t de9ined at the level *9 B$ata'dapter) The 1le$b'dapter #upp*rt# #everal p*##i3ilitie#, including aut*+atically 9illing the $ata#et !ith all, *r a #peci9ied #u3#et, *9 rec*rd# in a given ta3le) The $BConnect e;a+ple #h*!# the u#e *9 Structured Muery Language GSMLH, !hich i# pr*3a3ly the +*#t general #*luti*n) -n thi# ca#e, the SML Duery S+L+C' = HROG +G-LO/++S retrieve# all the c*lu+n# and all the data in the EAPLO:EES ta3le *9 the data3a#e) The 1le$b$ata'dapter ha# a c*n#truct*r !hich accept# a #tring G!hich it interpret# a# a SML DueryH and an B$bConnection) Thi# i# the c*n#truct*r !e u#e and upca#t the re#ult t* B$ata'dapter) *! that !e have *ur *pen c*nnecti*n t* the data3a#e and an B$ata'dapter, !e create a ne! $ata#et !ith the na+e IE+pl*yee#)J Thi# e+pty $ata#et i# pa##ed in t* the B$ata'dapter6:ill() +eth*d,
4#4
Thinking in C
www.ThinkingIn.!et
!hich e;ecute# the Duery via the B$bConnection, add# t* the pa##edEin $ata#et the appr*priate $ata+able and $ataColumn *34ect# that repre#ent the #tructure *9 the re#p*n#e, and then create# and add# t* the $ata#et the $ata*ow *34ect# that repre#ent the re#ult#) The B$bConnection i# Closed !ithin a 9inally 3l*ck, 4u#t in ca#e an &xception !a# thr*!n #*+eti+e during the data3a#e *perati*n) 5inally, the 9illed $ata#et i# returned t* .ain(), !hich duti9ully rep*rt# the nu+3er *9 e+pl*yee# in the *rth!ind data3a#e)
4#5
cnctn.Open013 5:$Co!!and #e 9 ne. O e:$Co!!and0 &S+L+C' = HROG +G-LO/++S&2 cnctn13 rdr 9 #e .+xecuteReader013 .hi e 0rdr.Read011 ; Sy#te!.Con#o e.VriteLine0 rdrJ&Hir#tCa!e&K R & & R rdrJ&La#tCa!e&K13 < < fina y ; rdr.C o#e013 cnctn.C o#e013 < < <///:8 The &numerate&mployees() +eth*d #tart# like the c*de in the $BConnect e;a+ple, 3ut !e d* n*t upca#t the 1le$bConnection t* B$bConnection 9*r rea#*n# !ell di#cu## #h*rtly) The c*nnecti*n t* the data3a#e i# identical, 3ut !e declare an B$ata*eader rdr and initiali7e it t* null 3e9*re *pening the data3a#e c*nnecti*nQ thi# i# #* that !e can u#e the finally 3l*ck t* Close() the B$ata*eader a# !ell a# the 1le$bConnection) =9ter *pening the c*nnecti*n t* the data3a#e, !e create an 1le$bCommand !hich !e upca#t t* B$bCommand) -n the ca#e *9 the 1le$bCommand c*n#truct*r !e u#e, the para+eter# are a SML #tate+ent and an 1le$bConnection Gthu#, *ur ina3ility t* upca#t in the 9ir#t line *9 the +eth*dH) The ne;t line, rdr 9 #e .+xecuteReader01, e;ecute# the c*++and and return# a connected B$ata*eader) B$ata*eader6*ead() read# the ne;t line *9 the Duery# re#ult, returning false !hen it run# *ut *9 r*!#) Once all the data i# read, the +eth*d enter# a finally 3l*ck, !hich #ever# the B$ata*eader# c*nnecti*n !ith rdr6Close() and then cl*#e# the data3a#e c*nnecti*n entirely !ith cnctn6Close())
4#6
Thinking in C
www.ThinkingIn.!et
C6>4 With )4O.(%,ith $ata#et# and +anaged pr*vider# in hand, 3eing a3le t* create, read, update, and delete rec*rd# in =?O) ET i# near at hand) Creating data !a# c*vered in the Basic$ata#et1perations e;a+ple P u#e $ata+able6,ew*ow() t* generate an appr*priate $ata*ow, 9ill it !ith y*ur data, and u#e $ata+able6*ows6'dd() t* in#ert it int* the $ata#et) Reading data i# d*ne in a 9le;i3le di#c*nnected !ay !ith an B$ata'dapter *r in a 9a#t 3ut c*nnected +anner !ith an B$ata*eader)
*t *nly !*uld it plea#e the hard drive +anu9acturer#Q it !*uld pr*vide a !ay ar*und the #ec*nd la! *9 ther+*dyna+ic#)
4##
2) =nn and Ben 3*th #elect the 9light, and their client #*9t!are #h*!# . #eat# le9t) /) =nn #u3+it# the change t* the data3a#e and it c*+plete# 9ine) &) Charlie read# the data3a#e, #ee# . #eat# availa3le *n the 9light) ') Ben #u3+it# the change t* the data3a#e) Becau#e =nne# update happened 3e9*re Ben# update, Ben receive# a $BConcurrency&xception) The data3a#e d*e# not accept Ben# change) .) Charlie #elect# a 9light and #u3+it# the change) Becau#e the r*! ha#nt changed #ince Charlie read the data, Charlie# reDue#t #ucceed#) -t i# i+p*##i3le t* give even general advice a# t* !hat t* d* a9ter receiving a $BConcurrency&xception) S*+eti+e# y*ull !ant t* take the data and reEin#ert it int* the data3a#e a# a ne! rec*rd, #*+eti+e# y*ull di#card the change#, and #*+eti+e# y*ull read the ne! data and rec*ncile it !ith y*ur change#) There are even ti+e# !hen #uch an e;cepti*n indicate# a deep l*gical 9la! that call# 9*r a #y#te+ #hutd*!n) Thi# e;a+ple per9*r+# all *9 the CRU? *perati*n#, rereading the data3a#e a9ter the update #* that the #u3#eDuent deleti*n *9 the ne! rec*rd d*e# n*t thr*! a $BConcurrency&xception1 //:c0>:Crud.c# u#ing Sy#te!.:ata3 u#ing Sy#te!.:ata.O e:$3 c a## Crud ; pu$ ic #tatic *oid Gain0#tringJK arg#1; Crud !yCrud 9 ne. Crud013 !yCrud.Read+!p oyee#0&CVind.!d$&13 !yCrud.Create013 !yCrud.Opdate013 //Cece##ary to a*oid :BConcurrency+xception !yCrud.Reread013 !yCrud.:e ete013 < O e:$:ata)dapter adapter3
4#&
Thinking in C
www.ThinkingIn.!et
:ataSet e!p#3 pri*ate *oid Read+!p oyee#0 #tring path'o)cce##:B1; O e:$Connection cnctn 9 ne. O e:$Connection013 cnctn.ConnectionString9 &-ro*ider9Gicro#oft.`+'.OL+:B.E.03& R &data #ource9& R path'o)cce##:B3 cnctn.Open013 #tring #e Str 9 &S+L+C' = HROG +G-LO/++S&3 adapter 9 ne. O e:$:ata)dapter0#e Str2 cnctn13 ne. O e:$Co!!andBui der0adapter13 e!p# 9 ne. :ataSet0&+!p oyee#&13 adapter.Hi 0e!p#13 < pri*ate *oid Create01; :ataRo. r 9 e!p#.'a$ e#J&'a$ e&K.Ce.Ro.013 rJ&Hir#tCa!e&K 9 &Bo$&3 rJ&La#tCa!e&K 9 &:o$$#&3 e!p#.'a$ e#J&'a$ e&K.Ro.#.)dd0r13 adapter.Opdate0e!p#13 < pri*ate *oid Opdate01; :ataRo. aRo. 9 e!p#.'a$ e#J&'a$ e&K.Ro.#J0K3 Sy#te!.Con#o e.VriteLine0 &Hir#t Ca!e: & R aRo.J&Hir#tCa!e&K13 #tring ne.Ca!e 9 nu 3 if0aRo.J&Hir#tCa!e&K.+7ua #0&Cancy&11; ne.Ca!e 9 &)da!&3 <e #e; ne.Ca!e 9 &Cancy&3 < aRo..Begin+dit013 aRo.J&Hir#tCa!e&K 9 ne.Ca!e3 aRo..+nd+dit013 Sy#te!.Con#o e.VriteLine0 &Hir#t Ca!e: & R aRo.J&Hir#tCa!e&K13
4#'
//Opdate on y happen# no. int iChangedRo.# 9 adapter.Opdate0e!p#13 Sy#te!.Con#o e.VriteLine0&;0< ro.# updated&2 iChangedRo.#13 < pri*ate *oid Reread01; adapter.Hi 0e!p#13 < pri*ate *oid :e ete01; //See!# to return " greater than actua count int iRo. 9 e!p#.'a$ e#J&'a$ e&K.Ro.#.Count3 :ataRo. a#tRo. 9 e!p#.'a$ e#J&'a$ e&K.Ro.#JiRo. 6 "K3 Sy#te!.Con#o e.VriteLine0&:e eting: & R a#tRo.J&Hir#tCa!e&K13 a#tRo..:e ete013 int iChangedRo.# 9 adapter.Opdate0e!p#13 Sy#te!.Con#o e.VriteLine0&;0< ro.# updated&2 iChangedRo.#13 < <///:8 The .ain() +eth*d *utline# !hat !ere g*ing t* d*1 read the IE+pl*yee#J ta3le, create a ne! rec*rd, update a rec*rd, reread the ta3le Gy*u can c*++ent *ut the call t* *eread() i9 y*u !ant t* #ee a $BConcurrency&xceptionH, and delete the rec*rd !e created) The Crud cla## ha# in#tance varia3le# 9*r h*lding the 1le$b$ata'dapter and $ata#et that the vari*u# +eth*d# !ill u#e) *ead&mployees() *pen# the data3a#e c*nnecti*n and create# the adapter 4u#t a# !eve d*ne 3e9*re) The ne;t line1 ne. O e:$Co!!andBui der0adapter13 de+*n#trate# a utility cla## that aut*+atically generate# and #et# !ithin the 1le$b$ata'dapter the SML #tate+ent# that in#ert, update, and delete data in the #a+e ta3le acted *n 3y the #elect c*++and) 1le$bCommandBuilder i# very c*nvenient 9*r SML data adapter# that !*rk *n a #ingle ta3le Gthere# a c*rre#p*nding #%lCommandBuilder
4&(
Thinking in C
www.ThinkingIn.!et
9*r u#e !ith SML ServerH) 5*r +*re c*+ple; adapter# that inv*lve +ultiple ta3le#, y*u have t* #et the c*rre#p*nding BnsertCommand, $eleteCommand, and VpdateCommand pr*pertie# *9 the 1le$b$ata'dapter) The#e c*++and# are needed t* c*++it t* the data3a#e change# +ade in the $ata#et6 The 9ir#t 9*ur line# *9 +eth*d Create() #h*! *perati*n# *n the $ata#et emps that !eve #een 3e9*re P the u#e *9 +able6,ew*ow(), and $ata*owCollection6'dd() t* +anipulate the $ata#et) The 9inal line call# B$ata'dapter6Vpdate(), !hich atte+pt# t* c*++it the change# in the $ata#et t* the 3acking #t*re Git i# thi# +eth*d !hich reDuire# the SML c*++and# generated 3y the 1le$bCommandBuilderH) The +eth*d Vpdate() 3egin# 3y reading the 9ir#t r*! in the emps $ata#et) The call t* $ata*ow6Begin&dit() put# the $ata*ow in a IPr*p*#edJ #tate) Change# pr*p*#ed in a $ata*ow can either 3e accepted 3y a call t* $ata*ow6&nd&dit() *r the 'cceptChanges() +eth*d *9 either the $ata*ow, $ata+able, *r $ata#et) They can 3e cancelled 3y a call t* $ata*ow6Cancel&dit() *r the *e)ectChanges() +eth*d# *9 the cla##e#) =9ter printing the value *9 the 9ir#t r*!# I5ir#t a+eJ c*lu+n, !e put a*ow in a IPr*p*#edJ #tate and change the I5ir#t a+eJ t* I5red)J ,e call Cancel&dit() and #h*! *n the c*n#*le that I5redJ is not the value) -9 the 9ir#t na+e i# currently I ancyJ !ere g*ing t* change it t* I=da+J and vice ver#a) Thi# ti+e, a9ter calling Begin&dit() and +aking the change, !e call &nd&dit()) =t thi# p*int, the data i# changed in the $ata#et, 3ut n*t yet in the data3a#e) The data3a#e c*++it i# per9*r+ed in the ne;t line, !ith an*ther call t* adapter6Vpdate()) Thi# call t* Vpdate() #ucceed#, a# the r*!# *perated *n 3y the t!* call# t* Vpdate() are di99erent) -9, h*!ever, !e !ere t* atte+pt t* update either *9 the#e t!* r*!# !ith*ut rereading the data 9r*+ the data3a#e, !e !*uld get the dread $BConcurrency&xception) Since deleting the r*! !e added i# e;actly *ur intent, .ain() call# *eread() !hich in turn call# adapter6:ill() t* re9ill the emps $ata#et) 5inally, .ain() call# $elete()) The nu+3er *9 r*!# i# retrieved 9r*+ the *ows c*llecti*n) But 3ecau#e the inde; int* r*!# i# $E3a#ed, !e need t* #u3tract 0 9r*+ the t*tal c*unt t* get the inde; *9 the la#t r*! Ge)g), the
4&1
$ata*ow in a $ata+able !ith a Count *9 0 !*uld 3e acce##ed at *ows<4>H) Once !e have the la#t r*! in the ?ataSet G!hich !ill 3e the IB*3 ?*33#J rec*rd added 3y the Create() +eth*dH, a call t* $ata*ow6$elete() re+*ve# it 9r*+ the $ata#et and $ata'dapter6Vpdate() c*++it# it t* the data3a#e)
4&)
Thinking in C
www.ThinkingIn.!et
in +*re detail in Chapter #BAL# and revi#it =?O) ET in *ur di#cu##i*n *9 dataE3*und c*ntr*l# in Chapter #,ind*!##)
'u##ar5
T* revie! the t**l# in the ) ET 5ra+e!*rk that c*llect *34ect#1 0) =n array a##*ciate# nu+erical indice# t* *34ect#) -t h*ld# *34ect# *9 a kn*!n type #* that y*u d*nt have t* ca#t the re#ult !hen y*ure l**king up an *34ect) -t can 3e +ultidi+en#i*nal in t!* !ay# P rectangular *r 4agged) H*!ever, it# #i7e cann*t 3e changed *nce y*u create it) 2) =n BList h*ld# #ingle ele+ent#, an B$ictionary h*ld# keyEvalue pair#, and a ,ame1b)ectCollectionBase h*ld# #tringEC*llecti*n pair#) /) Like an array, an BList al#* a##*ciate# nu+erical indice# t* *34ect#R y*u can think *9 array# and BList# a# *rdered c*ntainer#) =n B$ictionary *verl*ad# the 3racket *perat*r *9 the array t* +ake it ea#y t* acce## value#, 3ut the underlying i+ple+entati*n i# n*t nece##arily *rdered) &) A*#t c*llecti*n# aut*+atically re#i7e the+#elve# a# y*u add ele+ent#, 3ut the Bit'rray need# t* 3e e;plicitly #i7ed) ') BCollection# h*ld *nly ob)ect re9erence#, #* pri+itive# are 3*;ed and un3*;ed !hen #t*red) ,ith the e;cepti*n *9 typeE#peci9ic c*ntainer# in Sy#te+)C*llecti*n#)Speciali7ed and th*#e y*u r*ll y*ur#el9, y*u +u#t al!ay# ca#t the re#ult !hen y*u pull an ob)ect re9erence *ut *9 a c*ntainer) TypeE#peci9ic c*ntainer cla##e# !ill 3e #upp*rted natively 3y the ) ET runEti+e #*+eti+e in the 9uture) .) ?ata #tructure# have inherent characteri#tic# di#tinct 9r*+ the data that i# #t*red in the+) S*rting, #earching, and traver#al have traditi*nally 3een +atter# *9 great dayEt*Eday i+p*rt) =dvance# in a3#tracti*n and c*+puter p*!er all*! +*#t pr*gra++er# t* ign*re +*#t *9 the#e i##ue# +*#t *9 the ti+e, 3ut *cca#i*nally pr*duce the +*#t challenging and re!arding *pp*rtunitie# in pr*gra++ing)
4&3
%) =?O) ET pr*vide# an a3#tracti*n *9 the relati*nal data3a#e +*del) $ata#et# repre#ent relati*nal data in +e+*ry, !hile B$ata'dapter# and related cla##e# +*ve the data in and *ut *9 data3a#e#) The c*llecti*n cla##e# are t**l# that y*u u#e *n a dayEt*Eday 3a#i# t* +ake y*ur pr*gra+# #i+pler, +*re p*!er9ul, and +*re e99ective) Th*r*ughly under#tanding the+ and e;tending and c*+3ining the+ t* rapidly #*lve #*luti*n# i# *ne +ark *9 #*9t!are pr*9e##i*nali#+)
%&ercises
4&4
Thinking in C
www.ThinkingIn.!et
Thi# chapter tie# C# t*gether !ith IE;tre+e Pr*gra++ing,J the #et *9 #*9t!are engineering di#cipline# that have gained !ide#pread attenti*n thr*ugh*ut the devel*p+ent !*rld) The critical c*ncept *9 Ite#tE9ir#t c*dingJ !ill 3e intr*duced, a# !ell a# t**l# 9*r aut*+ating BPE#tyle 3uild# in C#)
4&5
Every pr*gra+ i# 3a#ed *n a va#t array *9 e;pectati*n#) S*+e e;pectati*n# are #* 3a#ic that it d*e#nt +ake #en#e t* !*rry a3*ut the+ P d*e# the current c*+puter have a hardEdrive, #u99icient R=A t* l*ad the pr*gra+, and #* 9*rth) Other e;pectati*n# are e;plicit in the c*de and vi*lati*n# can 3e di#c*vered at c*+pileEti+e P thi# +eth*d take# an integer a# a para+eter, n*t a #tring, that +eth*d return# a 5i#h n*t a 5*!l) The +a4*rity *9 e;pectati*n#, th*ugh, are i+plicit c*ntract# 3et!een +eth*d# and the client c*de that call# the+) ,hen the reality at runti+e i# #uch that an e;pectati*n g*e# un9ul9illed, C# u#e# E;cepti*n# t* #ignal the di#rupti*n *9 the pr*gra+# e;pected 3ehavi*r)
,hen an *34ect can rec*gni7e a pr*3le+ 3ut d*e# n*t have the c*nte;t t* intelligently deal !ith the pr*3le+, rec*very +ay 3e p*##i3le) 5*r in#tance, !hen a net!*rk +e##age i# n*t ackn*!ledged, perhap# a retry i# in *rder, 3ut that deci#i*n #h*uldnt 3e +ade at the l*!e#t level Gnet!*rk ga+e#, 9*r in#tance, *9ten have data *9 varying i+p*rtance, #*+e *9 !hich +u#t 3e ackn*!ledged and #*+e !hich !*uld 3e !*rthle## 3y the ti+e a retry c*uld 3e +adeH) On the *ther hand, a +eth*d +ay have a pr*3le+ 3ecau#e #*+ething i# a!ry !ith the !ay it i# 3eing u#ed P perhap# a pa##ed in para+eter ha# an invalid value Ga !rintCalendar +eth*d i# called 9*r the +*nth IElevente+3erJH *r perhap# the +eth*d can *nly 3e
4&#
+eaning9ully called !hen the *34ect i# in a di99erent #tate G9*r in#tance, a Cancel +eth*d i# called !hen an Btinerary *34ect i# n*t in a I3**kedJ #tateH) The#e +i#u#e #ituati*n# are tricky 3ecau#e there i# n* !ay in C# t* #peci9y a +eth*d# prec*nditi*n# and p*#tc*nditi*n# a# an e;plicit c*ntract P a !ay in #*urce c*de t* #ay Ii9 y*u call +e !ith ;, y, and 7 #ati#9ied, - !ill guarantee that !hen - return c*nditi*n a, 3, and c !ill 3e #ati#9ied Ga##u+ing *9 c*ur#e that all the +eth*d# - call 9ul9ill their c*ntractual *3ligati*n# !ith +eH)J 5*r in#tance, ) ET# Aath cla## ha# a #Duare r**t 9uncti*n that take# a d*u3le a# it# para+eter) Since ) ET d*e# n*t have a cla## t* repre#ent i+aginary nu+3er#, thi# 9uncti*n can *nly return a +eaning9ul an#!er i9 pa##ed a p*#itive value) -9 thi# +eth*d i# called !ith a negative value, i# that an e;cepti*nal c*nditi*n *r a di#app*inting, 3ut predicta3le, #ituati*nF There# n* !ay t* tell 9r*+ the +eth*d# #ignature1 dou$ e Gath.S7rt0dou$ e d13 =lth*ugh prec*nditi*n# and p*#tc*nditi*n# are n*t e;plicit in C# c*de, y*u #h*uld al!ay# think in ter+# *9 c*ntract# !hile pr*gra++ing and d*cu+ent preE and p*#tEc*nditi*n# in y*ur +eth*d# para+ and return# BAL d*cu+entati*n) The ) ET li3rary !riter# 9*ll*!ed thi# advice and the d*cu+entati*n 9*r Aath)SDrtGH e;plain that it !ill return a a G *t = u+3erH value i9 pa##ed a negative para+eter) There i# n* hardEandE9a#t rule t* deter+ine !hat i# an e;cepti*nal c*nditi*n and !hat i# rea#*na3ly 9*re#eea3le) Returning a #pecial Iinvalid
4&&
valueJ #uch a# d*e# Aath)SDrtGH i# de3ata3le, e#pecially i9 the prec*nditi*n i# n*t a# *3vi*u# a# I#Duare r**t# can *nly 3e taken *n p*#itive nu+3er#)J ,hen an e;cepti*nal c*nditi*n *ccur# #uch that a +eth*d cann*t 9ul9ill it# p*#tEc*nditi*n#, there are *nly t!* valid thing# t* d*1 atte+pt t* change the c*nditi*n# that led t* the pr*3le+ and retry the +eth*d, *r I*rgani7ed panicJ P put *34ect# int* c*n#i#tent #tate#, cl*#e *r relea#e n*nE+e+*ry re#*urce#, and +*ve c*ntr*l t* a +uch di99erent c*nte;t that can either per9*r+ a rec*very *r l*g a# +uch in9*r+ati*n a# p*##i3le a3*ut the c*nditi*n leading t* the 9ailure t* help in de3ugging e99*rt#) S*+e pe*ple e+pha#i7e rec*very 9ar t** earlyQ until late in the devel*p+ent *9 a highE availa3ility #y#te+ it# 3etter t* have y*ur #y#te+ 3reak and trigger a de9ectE9i;ing c*ding #e##i*n than t* cleanupEandErec*ver and all*! the de9ect t* c*ntinue) B*th *9 the#e valid ch*ice# Gretrying *r cleanupH u#ually cann*t 3e 9ully d*ne at the p*int !here the e;cepti*nal c*nditi*n *ccurred) ,ith a net!*rk err*r #*+eti+e# 4u#t !aiting a hal9E#ec*nd *r #* and retrying +ay 3e appr*priate, 3ut u#ually a retry reDuire# changing *pti*n# at a higher level *9 a3#tracti*n G9*r in#tance, a 9ileE!riting related err*r +ight 3e retried a9ter giving the u#er a chance t* ch**#e a di99erent l*cati*nH) Si+ilarly, cleanup leading t* either rec*very *r an *rderly #hutd*!n +ay very !ell reDuire 3ehavi*r 9r*+ all the *34ect# in y*ur #y#te+, n*t 4u#t th*#e *34ect# re9erenced 3y the cla## e;periencing the pr*3le+) ,hen an e;cepti*nal c*nditi*n *ccur#, it i# up t* the tr*u3led +eth*d t* create an *34ect *9 a type derived 9r*+ E;cepti*n) Such *34ect# can 3e thrown #* that c*ntr*l +*ve#, n*t t* the ne;t line *9 c*de *r int* a +eth*d call a# i# n*r+ally the ca#e, 3ut rather pr*pagate# t* 3l*ck# *9 c*de that are dedicated t* the ta#k# *9 either rec*very *r cleanup) The *rderly !ay in !hich E;cepti*n# pr*pagate 9r*+ the p*int *9 tr*u3le ha# t!* 3ene9it#) 5ir#t, it +ake# err*rEhandling c*de hierarchical, like a chain *9 c*++and) Perhap# *ne level *9 c*de can g* thr*ugh a #eDuence *9 *pti*n# and retry, 3ut i9 th*#e 9ail, can give up and pr*pagate the c*de t* a higher level *9 a3#tracti*n, !hich +ay per9*r+ a clean #hutd*!n) Sec*nd, e;cepti*n# clean up err*r handling c*de) -n#tead *9 checking 9*r a particular rare 9ailure and dealing !ith it at +ultiple place# in y*ur
4&'
pr*gra+, y*u n* l*nger need t* check at the p*int *9 the +eth*d call G#ince the e;cepti*n !ill pr*pagate right *ut *9 the pr*3le+ area t* a 3l*ck dedicated t* catching itH) =nd, y*u need t* handle the pr*3le+ in *nly *ne place, the #*Ecalled e%ce"tion handler) Thi# #ave# y*u c*de, and it #eparate# the c*de that de#cri3e# !hat y*u !ant t* d* 9r*+ the c*de that i# e;ecuted !hen thing# g* a!ry) -n general, reading, !riting, and de3ugging c*de 3ec*+e# +uch clearer !ith e;cepti*n# than !ith alternative !ay# *9 err*r handling) Thi# chapter intr*duce# y*u t* the c*de y*u need t* !rite t* pr*perly handle e;cepti*n#, and the !ay y*u can generate y*ur *!n e;cepti*n# i9 *ne *9 y*ur +eth*d# get# int* tr*u3le)
3asic e&ce$tions
,hen y*u thr*! an e;cepti*n, #everal thing# happen) 5ir#t, the e;cepti*n *34ect i# created in the #a+e !ay that any C# *34ect i# created1 *n the heap, !ith new) Then the current path *9 e;ecuti*n Gthe *ne y*u c*uldnt c*ntinueH i# #t*pped and the re9erence 9*r the e;cepti*n *34ect i# e4ected 9r*+ the current c*nte;t) =t thi# p*int the e;cepti*n handling +echani#+ take# *ver and 3egin# t* l**k 9*r an appr*priate place t* c*ntinue e;ecuting the pr*gra+) Thi# appr*priate place i# the e%ce"tion handler6 !h*#e 4*3 i# t* rec*ver 9r*+ the pr*3le+ #* the pr*gra+ can either retry the ta#k *r cleanup and pr*pagate either the *riginal E;cepti*n *r, 3etter, a higherEa3#tracti*n E;cepti*n) =# a #i+ple e;a+ple *9 thr*!ing an e;cepti*n, c*n#ider an *34ect re9erence called t that i# pa##ed in a# a para+eter t* y*ur +eth*d) :*ur de#ign c*ntract +ight reDuire a# a prec*nditi*n that t re9er t* a valid, initiali7ed *34ect) Since C# ha# n* #ynta; 9*r en9*rcing prec*nditi*n#, #*+e *ther piece *9 c*de +ay pa## y*ur +eth*d a null re9erence and c*+pile !ith n* pr*3le+) Thi# i# an ea#y prec*nditi*n vi*lati*n t* di#c*ver and there# n* #pecial in9*r+ati*n a3*ut the pr*3le+ that y*u think !*uld 3e help9ul 9*r it# handler#) :*u can #end in9*r+ati*n a3*ut the err*r int* a larger c*nte;t 3y creating an *34ect repre#enting the pr*3le+ and it# c*nte;t and Ithr*!ingJ it *ut *9 y*ur current c*nte;t) Thi# i# called throwing an e%ce"tion. Here# !hat it l**k# like1 if0t 99 nu 1
4'(
Thinking in C
www.ThinkingIn.!et
+xception013
Thi# thr*!# the e;cepti*n, !hich all*!# y*uRin the current c*nte;tRt* a3dicate re#p*n#i3ility 9*r thinking a3*ut the i##ue 9urther) -t# 4u#t +agically handled #*+e!here el#e) Preci#ely where !ill 3e #h*!n #h*rtly)
%&ce$tion argu#ents
Like any *34ect in C#, y*u al!ay# create e;cepti*n# *n the heap u#ing new, !hich all*cate# #t*rage and call# a c*n#truct*r) There are 9*ur c*n#truct*r# in all #tandard e;cepti*n#1 The de9ault, n* argu+ent c*n#truct*r = c*n#truct*r that take# a #tring a# a +e##age1 thro. ne. )rgu!entCu +xception0&t&13 = c*n#truct*r that take# a +e##age and an inner, l*!erElevel E;cepti*n1 thro. ne. -reconditionNio ation+xception0&in*a id t&2 ne. )rgu!entCu +xception0&t&11 =nd a c*n#truct*r that all*!# 9*r a l*t *9 9le;i3ility Ot*d* 9*r!ard re9erence t* #ecti*n dealing !ith Seriali7ati*n-n9*, Strea+ingC*nte;t c*n#truct*r The key!*rd throw cau#e# a nu+3er *9 relatively +agical thing# t* happen) Typically, y*ull 9ir#t u#e new t* create an *34ect that repre#ent# the err*r c*nditi*n) :*u give the re#ulting re9erence t* throw) The *34ect i#, in e99ect, IreturnedJ 9r*+ the +eth*d, even th*ugh that *34ect type i#nt n*r+ally !hat the +eth*d i# de#igned t* return) = #i+pli#tic !ay t* think a3*ut e;cepti*n handling i# a# an alternate return +echani#+, alth*ugh y*u get int* tr*u3le i9 y*u take that anal*gy t** 9ar) :*u can al#* e;it 9r*+ *rdinary #c*pe# 3y thr*!ing an e;cepti*n) But a value i# returned, and the +eth*d *r #c*pe e;it#) =ny #i+ilarity t* an *rdinary return 9r*+ a +eth*d end# here, 3ecau#e where y*u return i# #*+eplace c*+pletely di99erent 9r*+ !here y*u return 9*r a n*r+al +eth*d call) G:*u end up in an appr*priate e;cepti*n handler that +ight 3e +ile# a!ayR+any level# l*!er *n the call #tackR 9r*+ !here the e;cepti*n !a# thr*!n)H
4'1
Typically, y*ull thr*! a di99erent cla## *9 e;cepti*n 9*r each di99erent type *9 err*r) The in9*r+ati*n a3*ut the err*r i# repre#ented 3*th in#ide the e;cepti*n *34ect and i+plicitly in the type *9 e;cepti*n *34ect ch*#en, #* #*+e*ne in the 3igger c*nte;t can 9igure *ut !hat t* d* !ith y*ur e;cepti*n) GO9ten, it# 9ine that the *nly in9*r+ati*n i# the type *9 e;cepti*n *34ect, and n*thing +eaning9ul i# #t*red !ithin the e;cepti*n *34ect)H
Catching an e&ce$tion
-9 a +eth*d thr*!# an e;cepti*n, it +u#t a##u+e that e;cepti*n i# IcaughtJ and dealt !ith) One *9 the advantage# *9 C## e;cepti*n handling i# that it all*!# y*u t* c*ncentrate *n the pr*3le+ y*ure trying t* #*lve in *ne place, and then deal !ith the err*r# 9r*+ that c*de in an*ther place) T* #ee h*! an e;cepti*n i# caught, y*u +u#t 9ir#t under#tand the c*ncept *9 a guarded region6 !hich i# a #ecti*n *9 c*de that +ight pr*duce e;cepti*n#, and !hich i# 9*ll*!ed 3y the c*de t* handle th*#e e;cepti*n#)
4')
Thinking in C
www.ThinkingIn.!et
and capture all the e;cepti*n# in *ne place) Thi# +ean# y*ur c*de i# a l*t ea#ier t* !rite and ea#ier t* read 3ecau#e the g*al *9 the c*de i# n*t c*n9u#ed !ith the err*r checking)
%&ce$tion handlers
O9 c*ur#e, the thr*!n e;cepti*n +u#t end up #*+eplace) Thi# IplaceJ i# the e%ce"tion handler6 and there# *ne 9*r every e;cepti*n type y*u !ant t* catch) E;cepti*n handler# i++ediately 9*ll*! the try 3l*ck and are den*ted 3y the key!*rd catch1 try ; // Code that !ight generate exception# < catch0'ype" id"1 ; // Uand e exception# of 'ype" < catch0'ype2 id21 ; // Uand e exception# of 'ype2 < catch0'ypeT idT1 ; // Uand e exception# of 'ypeT < // etc... Each catch clau#e Ge;cepti*n handlerH i# like a little +eth*d that take# *ne and *nly *ne argu+ent *9 a particular type) The identi9ier Gid7, id8, and #* *nH can 3e u#ed in#ide the handler, 4u#t like a +eth*d argu+ent) S*+eti+e# y*u never u#e the identi9ier 3ecau#e the type *9 the e;cepti*n give# y*u en*ugh in9*r+ati*n t* deal !ith the e;cepti*n, 3ut the identi9ier +u#t #till 3e there) The handler# +u#t appear directly a9ter the try 3l*ck) -9 an e;cepti*n i# thr*!n, the e;cepti*n handling +echani#+ g*e# hunting 9*r the 9ir#t handler !ith an argu+ent that +atche# the type *9 the e;cepti*n) Then it enter# that catch clau#e, and the e;cepti*n i# c*n#idered handled) The #earch 9*r handler# #t*p# *nce the catch clau#e i# 9ini#hed) Only the +atching catch clau#e e;ecute#Q it# n*t like a switch #tate+ent in !hich y*u need a brea( a9ter each case) *te that, !ithin the try 3l*ck, a nu+3er *9 di99erent +eth*d call# +ight generate the #a+e e;cepti*n, 3ut y*u need *nly *ne handler)
4'3
4'4
Thinking in C
www.ThinkingIn.!et
Sy#te!.Con#o e.+rror.VriteLine0&Caught it!&13 < < < ///:8 ,hen the c*+piler create# the de9ault c*n#truct*r, it !hich aut*+atically Gand invi#i3lyH call# the 3a#eEcla## de9ault c*n#truct*r) =# y*ull #ee, the +*#t i+p*rtant thing a3*ut an e;cepti*n i# the cla## na+e, #* +*#t *9 the ti+e an e;cepti*n like the *ne #h*!n a3*ve i# #ati#9act*ry) Here, the re#ult i# printed t* the c*n#*le standard error #trea+ 3y !riting t* #ystem6Console6&rror) Thi# #trea+ can 3e redirected t* any *ther +ext=riter 3y calling #ystem6Console6#et&rror() Gn*te that thi# i# Ta#y++etricJ P the &rror pr*perty d*e#nt #upp*rt a##ign+ent, 3ut there# a #et&rror()) ,hy !*uld thi# 3eFH Creating an e;cepti*n cla## that *verride# the #tandard c*n#truct*r# i# al#* Duite #i+ple1 //:c0>:Hu Con#tructor#.c# u#ing Sy#te!3 c a## Gy+xception : +xception ; pu$ ic Gy+xception01 : $a#e01 ;< pu$ ic Gy+xception0#tring !#g1 : $a#e0!#g1 ;< pu$ ic Gy+xception0#tring !#g2 +xception inner1 : $a#e0!#g2 inner1;< < pu$ ic c a## Hu Con#tructor# ; pu$ ic #tatic *oid H01 ; Sy#te!.Con#o e.VriteLine0 &'hro.ing Gy+xception fro! H01&13 thro. ne. Gy+xception013 < pu$ ic #tatic *oid _01 ; Sy#te!.Con#o e.VriteLine0 &'hro.ing Gy+xception fro! _01&13 thro. ne. Gy+xception0&Originated in _01&13 <
4'5
pu$ ic #tatic *oid U01; try; 5013 <catch0:i*ideBybero+xception e1; Sy#te!.Con#o e.VriteLine0&5ncrea#ing a$#traction e*e &13 thro. ne. Gy+xception0&Originated in U01&2 e13 < < pu$ ic #tatic *oid 501; Sy#te!.Con#o e.VriteLine0&'hi#' trou$ e&13 int y 9 03 int x 9 " / y3 < cau#e
pu$ ic #tatic *oid Gain01 ; try ; H013 < catch0Gy+xception e1 ; Sy#te!.Con#o e.+rror.VriteLine0e.Stac%'race13 < try ; _013 < catch0Gy+xception e1 ; Sy#te!.Con#o e.+rror.VriteLine0e.Ge##age13 < try; U013 <catch0Gy+xception e1; Sy#te!.Con#o e.+rror.VriteLine0e.Ge##age13 Sy#te!.Con#o e.+rror.VriteLine0&5nner exception: & R e.5nner+xception13 Sy#te!.Con#o e.+rror.VriteLine0&Source: & R e.Source13 Sy#te!.Con#o e.+rror.VriteLine0&'argetSite: & R e.'argetSite13 < < < ///:8
4'6
Thinking in C
www.ThinkingIn.!et
The c*de added t* .y&xception i# #+allRthe additi*n *9 three c*n#truct*r# that de9ine the !ay .y&xception i# created) The 3a#eEcla## c*n#truct*r i# e;plicitly inv*ked 3y u#ing the D base key!*rd) The *utput *9 the pr*gra+ i#1 'hro.ing Gy+xception fro! H01 at Hu Con#tructor#.H01 at Hu Con#tructor#.Gain01 'hro.ing Gy+xception fro! _01 Originated in _01 'hi#' cau#e trou$ e 5ncrea#ing a$#traction e*e Originated in U01 5nner exception: Sy#te!.:i*ideBybero+xception: )tte!pted to di*ide $y Mero. at Hu Con#tructor#.501 at Hu Con#tructor#.U01 Source: Hu Con#tructor# 'argetSite: Noid U01 :*u can #ee the a3#ence *9 the detail +e##age in the .y&xception thr*!n 9r*+ :( )) The 3l*ck that catche# the e;cepti*n thr*!n 9r*+ :() #h*!# the #tack trace all the !ay t* the *rigin *9 the e;cepti*n) Thi# i# pr*3a3ly the +*#t help9ul pr*perty in E;cepti*n and i# a great aid t* de3ugging) ,hen "() e;ecute#, it call# B(), !hich atte+pt# an illegal arith+etic *perati*n) The atte+pt t* divide 3y 7er* thr*!# a $ivideBy\ero&xception Gde+*n#trating the truth *9 the previ*u# #tate+ent a3*ut the type na+e 3eing the +*#t i+p*rtant thingH) "() catche# the $ivideBy\ero&xception, 3ut increa#e# the a3#tracti*n level 3y !rapping it in a .y&xception) Then, !hen the .y&xception i# caught in .ain(), !e can #ee the inner e;cepti*n and it# *rigin in B()) The #ource pr*perty c*ntain# the na+e *9 the a##e+3ly that thre! the e;cepti*n, !hile the +arget#ite pr*perty return# a handle t* the +eth*d that thre! the e;cepti*n) +arget#ite i# appr*priate 9*r #*phi#ticated re9lecti*nE3a#ed e;cepti*n diagn*#tic# and handling)
4'#
The pr*ce## *9 creating y*ur *!n e;cepti*n# can 3e taken 9urther) :*u can add e;tra c*n#truct*r# and +e+3er#1 //:c0>:+xtraHeature#.c# // Hurther e!$e i#h!ent of exception c a##e#. u#ing Sy#te!3 c a## Gy+xception2 : +xception ; int errorCode3 pu$ ic int +rrorCode; get ; return errorCode3 < < pu$ ic Gy+xception201 : $a#e01;< pu$ ic Gy+xception20#tring !#g1 : $a#e0!#g1 ;< pu$ ic Gy+xception20#tring !#g2 int errorCode1 : $a#e0!#g1 ; thi#.errorCode 9 errorCode3 < < pu$ ic c a## +xtraHeature# ; pu$ ic #tatic *oid H01 ; Sy#te!.Con#o e.VriteLine0 &'hro.ing Gy+xception2 fro! H01&13 thro. ne. Gy+xception2013 < pu$ ic #tatic *oid _01 ; Sy#te!.Con#o e.VriteLine0 &'hro.ing Gy+xception2 fro! _01&13 thro. ne. Gy+xception20&Originated in _01&13 < pu$ ic #tatic *oid U01 ; Sy#te!.Con#o e.VriteLine0 &'hro.ing Gy+xception2 fro! U01&13 thro. ne. Gy+xception20 &Originated in U01&2 EF13 < pu$ ic #tatic *oid Gain0StringJK arg#1 ;
4'&
Thinking in C
www.ThinkingIn.!et
try ; H013 < catch0Gy+xception2 e1 ; Sy#te!.Con#o e.+rror.VriteLine0e.Stac%'race13 < try ; _013 < catch0Gy+xception2 e1 ; Sy#te!.Con#o e.+rror.VriteLine0e.Stac%'race13 < try ; U013 < catch0Gy+xception2 e1 ; Sy#te!.Con#o e.+rror.VriteLine0e.Stac%'race13 Sy#te!.Con#o e.+rror.VriteLine0&e.+rrorCode 9 & R e.+rrorCode13 < < < ///:8 = pr*perty &rrorCode ha# 3een added, al*ng !ith an additi*nal c*n#truct*r that #et# it) The *utput i#1 'hro.ing Gy+xception2 fro! H01 at +xtraHeature#.H01 in ::^tic^exception#^+xtraHeature#.c#: ine at +xtraHeature#.Gain0StringJK arg#1 C:^:ocu!ent# and Setting#^ arry^Gy :ocu!ent#^+xtraHeature#.c#: ine TI 'hro.ing Gy+xception2 fro! _01 at +xtraHeature#._01 in ::^tic^exception#^+xtraHeature#.c#: ine at +xtraHeature#.Gain0StringJK arg#1 ::^tic^exception#^+xtraHeature#.c#: ine 'hro.ing Gy+xception2 fro! U01 at +xtraHeature#.U01 in ::^tic^exception#^+xtraHeature#.c#: ine
2T in
2I in ET
TT
4''
at +xtraHeature#.Gain0StringJK arg#1 in C:^:ocu!ent# and Setting#^ arry^Gy :ocu!ent#^+xtraHeature#.c#: ine EI e.+rrorCode 9 EF Since an e;cepti*n i# 4u#t an*ther kind *9 *34ect, y*u can c*ntinue thi# pr*ce## *9 e+3elli#hing the p*!er *9 y*ur e;cepti*n cla##e#) =n err*r c*de, a# illu#trated here, i# pr*3a3ly n*t very u#e9ul, #ince the type *9 the E;cepti*n give# y*u a g**d idea *9 the I!hatJ *9 the pr*3le+) A*re intere#ting !*uld 3e t* e+3ed a clue a# t* the Ih*!J *9 retrying *r cleanup P #*+e kind *9 *34ect that encap#ulated the c*nte;t *9 the 3r*ken c*ntract) Neep in +ind, h*!ever, that the 3e#t de#ign i# the *ne that thr*!# e;cepti*n# rarely and that the 3e#t pr*gra++er i# the *ne !h*#e !*rk deliver# the +*#t 3ene9it t* the cu#t*+er, n*t the *ne !h* c*+e# up !ith the clevere#t #*luti*n t* !hat t* d* !hen thing# g* !r*ngK
5((
Thinking in C
www.ThinkingIn.!et
int and return# a #tring i# n*t pa##ed a d*u3le *r u#ed t* a##ign t* a 9l*at #* t** d*e# the c*+piler en9*rce the E;cepti*n #peci9icati*n) Checked e;cepti*n# #uch a# in "ava are n*t intended t* deal !ith prec*nditi*n vi*lati*n#, !hich are 3y 9ar the +*#t c*++*n cau#e *9 e;cepti*nal c*nditi*n#) = prec*nditi*n vi*lati*n Gcalling a +eth*d !ith an i+pr*per para+eter, calling a #tateE#peci9ic +eth*d *n an *34ect that# n*t in the reDuired #tateH i#, 3y de9initi*n, the re#ult *9 a pr*gra++ing err*r) Retrie# are, at 3e#t, u#ele## in #uch a #ituati*n Gat !*r#t, the retry !ill !*rk and there3y all*! the pr*gra++ing err*r t* g* un9i;edKH) S* "ava ha# an*ther type *9 e;cepti*n that i# unchecked) -n practice !hat happen# i# that !hile pr*gra++er# are generally accepting *9 #tr*ng typeEchecking !hen it c*+e# t* para+eter# and return value#, the value *9 #tr*ngly typed e;cepti*n# i# n*t nearly a# evident in realE!*rld practice) There are t** +any l*!Elevel thing# that can g* !r*ng G9ailure# *9 9ile# and net!*rk# and R=A and #* 9*rthH and +any pr*gra++er# d* n*t #ee the 3ene9it *9 creating an a3#tracti*n hierarchy a# they deal !ith all 9ailure# in a generic +anner) =nd the di99erent intent *9 checked and unchecked e;cepti*n# i# c*n9u#ing t* +any devel*per#) =nd thu# *ne #ee# a great deal *9 "ava c*de in t!* eDually 3ad 9*r+#1 +eaningle## pr*pagati*n *9 l*!Ea3#tracti*n e;cepti*n# G,e3 #ervice# that are declared a# thr*!ing -OE;cepti*n#H and I+ake it c*+pileJ hack# !here +eth*d# are declared a# Ithr*!# E;cepti*nJ Gin *ther !*rd#, #aying I- can thr*! anything - darn !ell plea#e)JH) ,*r#e, th*ugh, it# n*t unc*++*n t* #ee the very !*r#t p*##i3le I#*luti*n,J !hich i# t* catch and ign*re the e;cepti*n, all 9*r the #ake *9 getting a clean c*+pile) The*retically, i9 y*ure g*ing t* have a #tr*ngly typed language, it pr*3a3ly +ake# #en#e 9*r e;cepti*n# t* 3e part *9 the +eth*d #ignature) Prag+atically, th*ugh, the prevalence *9 3ad e;cepti*nEhandling c*de in "ava argue# 9*r C## appr*ach, !hich i# e##entially that the 3urden i# *n the pr*gra++er t* kn*! t* place err*rEhandling c*de in the appr*priate place#)
5(1
catch0+xception e1 ; Sy#te!.Con#o e.+rror.VriteLine0&Caught an exception&13 < Thi# !ill catch any e;cepti*n, #* i9 y*u u#e it y*ull !ant t* put it at the end *9 y*ur li#t *9 handler# t* av*id pree+pting any e;cepti*n handler# that +ight *ther!i#e 9*ll*! it) Since the &xception cla## i# the 3a#e *9 all the e;cepti*n cla##e#, y*u d*nt get +uch #peci9ic in9*r+ati*n a3*ut the #peci9ic pr*3le+) :*u d*, h*!ever, get #*+e +eth*d# 9r*+ ob)ect Gevery3*dy# 3a#e typeH) The *ne that +ight c*+e in handy 9*r e;cepti*n# i# et+ype(), !hich return# an *34ect repre#enting the cla## *9 this) :*u can in turn read the ,ame pr*perty *9 thi# +ype *34ect) :*u can al#* d* +*re #*phi#ticated thing# !ith +ype *34ect# that arent nece##ary in e;cepti*n handling) +ype *34ect# !ill 3e #tudied later in thi# 3**k)
6ethrowing an e&ce$tion
S*+eti+e# y*ull !ant t* rethr*! the e;cepti*n that y*u 4u#t caught, particularly !hen y*u u#e catch(&xception) t* catch any e;cepti*n) Since y*u already have the re9erence t* the current e;cepti*n, y*u can #i+ply rethr*! that re9erence1 catch0+xception e1 ; Sy#te!.Con#o e.+rror.VriteLine0&)n exception .a# thro.n&13 thro. e3 < Rethr*!ing an e;cepti*n cau#e# the e;cepti*n t* g* t* the e;cepti*n handler# in the ne;tEhigher c*nte;t) =ny 9urther catch clau#e# 9*r the #a+e try 3l*ck are #till ign*red) -n additi*n, everything a3*ut the e;cepti*n *34ect i# pre#erved, #* the handler at the higher c*nte;t that catche# the #peci9ic e;cepti*n type can e;tract all the in9*r+ati*n 9r*+ that *34ect)
5()
Thinking in C
www.ThinkingIn.!et
5(3
c a## Bu#ine##Logic ; 'ran#action !y'ran#action 9 ne. 'ran#action013 pu$ ic *oid :oCharge01; try ; !y'ran#action.-roce##013 Sy#te!.Con#o e.VriteLine0&'ran#action .ent through&13 < catch 0'ran#actionHai ure+xception tfe1 ; Sy#te!.Con#o e.VriteLine0tfe.Ge##age13 Sy#te!.Con#o e.+rror.VriteLine0tfe.5nner+xception13 < < pu$ ic #tatic *oid Gain01; Bu#ine##Logic $ 9 ne. Bu#ine##Logic013 for 0int i 9 03 i W "03 iRR1 ; $ .:oCharge013 < < < < ///:8
-n thi# e;a+ple, the cla## +ransaction ha# an e;cepti*n cla## that i# at it# #a+e level *9 a3#tracti*n in +ransaction:ailure&xception) The try`catch(&xception eH c*n#truct in +ransaction6!rocess() +ake# 9*r a nice and e;plicit c*ntract1 I- try t* return v*id, 3ut i9 anything g*e# a!ry in +y pr*ce##ing, - +ay thr*! a +ransaction:ailed&xception)J -n *rder t* generate #*+e e;cepti*n#, !e u#e a rand*+ nu+3er generat*r t* thr*! di99erent type# *9 l*!Elevel e;cepti*n# in +ransaction6!rocess()) =ll e;cepti*n# are caught in +ransaction6!rocess()# catch 3l*ck, !here they are placed Iin#ideJ a ne! +ransaction:ailure&xception u#ing that type# *verridden c*n#truct*r that take# an e;cepti*n and
5(4
Thinking in C
www.ThinkingIn.!et
create# a generic IL*gical 9ailure cau#ed 3y l*!Elevel e;cepti*nJ +e##age) The c*de then thr*!# the ne!ly created +ransaction:ailure&xception, !hich i# in turn caught 3y BusinessLogic6$oCharge()# catch(+ransaction:ailure&xception tfe) 3l*ck) The higherE a3#tracti*n e;cepti*n# +e##age i# printed t* the C*n#*le, !hile the l*!erEa3#tracti*n e;cepti*n i# #ent t* the Err*r #trea+ G!hich i# al#* the c*n#*le, 3ut the p*int i# that there i# a #eparati*n 3et!een the t!* level# *9 a3#tracti*n) -n practice, the higherEa3#tracti*n e;cepti*n !*uld 3e u#ed 9*r 3u#ine## l*gic ch*ice# and the l*!erEa3#tracti*n e;cepti*n 9*r de3uggingH)
'tandard C# e&ce$tions
The C# cla## &xception de#cri3e# anything that can 3e thr*!n a# an e;cepti*n) There are t!* general type# *9 &xception *34ect# GItype# *9J X Iinherited 9r*+JH) #ystem&xception repre#ent# e;cepti*n# in the Sy#te+ na+e#pace and it# de#cendant# Gin *ther !*rd#, ) ET# #tandard e;cepti*n#H) :*ur e;cepti*n# 3y c*nventi*n #h*uld e;tend 9r*+ 'pplication&xception) -9 y*u 3r*!#e the ) ET d*cu+entati*n, y*ull #ee that each na+e#pace ha# a #+all hand9ul *9 e;cepti*n# that are at a level *9 a3#tracti*n appr*priate t* the na+e#pace) 5*r in#tance, Sy#te+)-O ha# an BnternalBuffer1verflow&xception, !hich i# pretty darn l*!Elevel, !hile Sy#te+),e3)Service#)Pr*t*c*l# ha# #oap&xception, !hich i# pretty darn highElevel) -t# !*rth 3r*!#ing thr*ugh the#e e;cepti*n# *nce t* get a 9eel 9*r the vari*u# e;cepti*n#, 3ut y*ull #**n #ee that there i#nt anything #pecial 3et!een *ne e;cepti*n and the ne;t e;cept 9*r the na+e) The 3a#ic idea i# that the na+e *9 the e;cepti*n repre#ent# the pr*3le+ that *ccurred, and the e;cepti*n na+e i# intended t* 3e relatively #el9E e;planat*ry)
5(5
5(6
Thinking in C
www.ThinkingIn.!et
pu$ ic #tatic *oid Gain01 ; .hi e0true1; try; if0countRR W T1; thro. ne. 'hree+xception013 < Sy#te!.Con#o e.VriteLine0&Co exception&13 < catch0'hree+xception 1 ; Sy#te!.Con#o e.VriteLine0&'hree+xception&13 < fina y ; Sy#te!.Con#o e.+rror.VriteLine0&5n fina y c au#e&13 //! if0count 99 T1 $rea%3 W6 Co!pi er error < if0count Z T1 $rea%3 < < < ///:8 Thi# pr*gra+ al#* give# a hint 9*r h*! y*u can deal !ith the 9act that e;cepti*n# in C# d* n*t all*! y*u t* re#u+e 3ack t* !here the e;cepti*n !a# thr*!n, a# di#cu##ed earlier) -9 y*u place y*ur try 3l*ck in a l**p, y*u can e#ta3li#h a c*nditi*n that +u#t 3e +et 3e9*re y*u c*ntinue the pr*gra+) :*u can al#* add a static c*unter *r #*+e *ther device t* all*! the l**p t* try #everal di99erent appr*ache# 3e9*re giving up) Thi# !ay y*u can 3uild a greater level *9 r*3u#tne## int* y*ur pr*gra+#) The *utput i#1 'hree+xception 5n fina y c au#e 'hree+xception 5n fina y c au#e 'hree+xception 5n fina y c au#e Co exception 5n fina y c au#e ,hether an e;cepti*n i# thr*!n *r n*t, the finally clau#e i# al!ay# e;ecuted)
5(#
5(&
Thinking in C
www.ThinkingIn.!et
#..Off013 < < < ///:8 The g*al here i# t* +ake #ure that the #!itch i# *99 !hen .ain( ) i# c*+pleted, #* sw61ff( ) i# placed at the end *9 the try 3l*ck and at the end *9 each e;cepti*n handler) But it# p*##i3le that an e;cepti*n c*uld 3e thr*!n that i#nt caught here, #* sw61ff( ) !*uld 3e +i##ed) H*!ever, !ith finally y*u can place the cleanup c*de 9r*+ a try 3l*ck in 4u#t *ne place1 //:c0>:VhyHina y2.c# // Vhy u#e fina yY u#ing Sy#te!3 c a## S.itch ; $oo #tate 9 fa #e3 pu$ ic $oo Read; get ; return #tate3< #et ; #tate 9 *a ue3< < pu$ ic *oid On01; #tate 9 true3< pu$ ic *oid Off01; #tate 9 fa #e3< < c a## OnOff+xception" : +xception ; < c a## OnOff+xception2 : +xception ; < pu$ ic c a## OnOffS.itch ; #tatic S.itch #. 9 ne. S.itch013 #tatic *oid H01 ;< pu$ ic #tatic *oid Gain01 ; try ; #..On013 // Code that can thro. exception#... H013 < catch 0OnOff+xception" 1 ;
5('
Sy#te!.Con#o e.VriteLine0&OnOff+xception"&13 < catch 0OnOff+xception2 1 ; Sy#te!.Con#o e.VriteLine0&OnOff+xception2&13 < fina y ; #..Off013 < < < ///:8 Here the sw61ff( ) ha# 3een +*ved t* 4u#t *ne place, !here it# guaranteed t* run n* +atter !hat happen#) Even in ca#e# in !hich the e;cepti*n i# n*t caught in the current #et *9 catch clau#e#, finally !ill 3e e;ecuted 3e9*re the e;cepti*n handling +echani#+ c*ntinue# it# #earch 9*r a handler at the ne;t higher level1 //:c0>:Ce#tedHina y.c# // Hina y i# a .ay# executed. u#ing Sy#te!3 c a## Hour+xception : )pp ication+xception ;< pu$ ic c a## ) .ay#Hina y ; pu$ ic #tatic *oid Gain01 ; Sy#te!.Con#o e.VriteLine0 &+ntering fir#t try $ oc%&13 try ; Sy#te!.Con#o e.VriteLine0 &+ntering #econd try $ oc%&13 try ; thro. ne. Hour+xception013 < fina y ; Sy#te!.Con#o e.VriteLine0 &fina y in 2nd try $ oc%&13 < < catch0Hour+xception 1 ; Sy#te!.Con#o e.VriteLine0 &Caught Hour+xception in "#t try $ oc%&13 < fina y ;
51(
Thinking in C
www.ThinkingIn.!et
Sy#te!.Con#o e.VriteLine0 &fina y in "#t try $ oc%&13 < < < ///:8 The *utput 9*r thi# pr*gra+ #h*!# y*u !hat happen#1 +ntering fir#t try $ oc% +ntering #econd try $ oc% fina y in 2nd try $ oc% Caught Hour+xception in "#t try $ oc% fina y in "#t try $ oc%
511
ca
Sy#te!.Con#o e.VriteLine0&Con#tructor ed&13 < pu$ ic *oid :i#po#e01; Sy#te!.Con#o e.VriteLine0&:i#po#e ca < ed&13
8O#ingC eanup01; Sy#te!.Con#o e.VriteLine0&:e#tructor ca < <//:8 :*u #h*uld n*t 3e #urpri#ed at the *utput1 Con#tructor ca ed :i#po#e ca ed )fter di#po#a :e#tructor ca ed Changing the .ain() +eth*d t*1
ed&13
pu$ ic #tatic *oid Gain01; try ; O#ingC eanup uc 9 ne. O#ingC eanup013 u#ing0uc1; thro. ne. Cot5!p e!ented+xception013 < <catch0+xception 1; Sy#te!.Con#o e.VriteLine0&)fter di#po#a &13 < < pr*duce# the e;act #a+e *utput) -n 9act, the using key!*rd i# 4u#t I#yntactic #ugarJ that !rap# an B$isposable #u3type in a try`finally 3l*ckK Behind the #cene#, the e;act #a+e c*de i# generated, 3ut the using 3l*ck i# ter#er)
51)
Thinking in C
www.ThinkingIn.!et
cri#i# in y*ur pr*gra+ and #h*uld never 3e ign*red, it# p*##i3le 9*r an e;cepti*n t* #i+ply 3e l*#t) Thi# happen# !ith a particular c*n9igurati*n u#ing a finally clau#e1 //:c0>:Lo#t+xception.c# // Uo. an exception can $e u#ing Sy#te!3 o#t.
c a## Nery5!portant+xception : +xception ; < c a## UoUu!+xception : +xception ; < pu$ ic c a## Lo#tGe##age ; *oid H01 ; thro. ne. Nery5!portant+xception013 < *oid :i#po#e01 ; thro. ne. UoUu!+xception013 < pu$ ic #tatic *oid Gain01; try ; Lo#tGe##age ! 9 ne. Lo#tGe##age013 try ; !.H013 < fina y ; !.:i#po#e013 < < catch 0+xception e1 ; Sy#te!.Con#o e.VriteLine0e13 < < < ///:8 The *utput i#1 UoUu!+xception: +xception of type UoUu!+xception .a# thro.n. at Lo#tGe##age.:i#po#e01 at Lo#tGe##age.Gain01
513
:*u can #ee that there# n* evidence *9 the HeryBmportant&xception, !hich i# #i+ply replaced 3y the "o"um&xception in the finally clau#e) Thi# i# a rather #eri*u# pit9all, #ince it +ean# that an e;cepti*n can 3e c*+pletely l*#t, and in a 9ar +*re #u3tle and di99icultEt*Edetect 9a#hi*n than the e;a+ple a3*ve) -n c*ntra#t, C@@ treat# the #ituati*n in !hich a #ec*nd e;cepti*n i# thr*!n 3e9*re the 9ir#t *ne i# handled a# a dire pr*gra++ing err*r) T* av*id thi# p*##i3ility, it i# a g**d idea t* !rap all y*ur !*rk in#ide a finally 3l*ck in a try`catch(&xception)D //:c0>:Carefu Hina u#ing Sy#te!3 y.c#
c a## Nery5!portant+xception : +xception ; < c a## UoUu!+xception : +xception ; < pu$ ic c a## Lo#tGe##age ; *oid H01 ; thro. ne. Nery5!portant+xception013 < *oid :i#po#e01 ; thro. ne. UoUu!+xception013 < pu$ ic #tatic *oid Gain01; try ; Lo#tGe##age ! 9 ne. Lo#tGe##age013 try ; !.H013 < fina y ; try; !.:i#po#e013 <catch0+xception e1; Sy#te!.Con#o e.VriteLine0e13 < < < catch 0+xception e1 ; Sy#te!.Con#o e.VriteLine0e13 < <
514
Thinking in C
www.ThinkingIn.!et
< ///:8 Pr*duce# the de#ired *utput1 UoUu!+xception: +xception of type UoUu!+xception .a# thro.n. at Lo#tGe##age.:i#po#e01 at Lo#tGe##age.Gain01 Nery5!portant+xception: +xception of type Nery5!portant+xception .a# thro.n. at Lo#tGe##age.H01 at Lo#tGe##age.Gain01
Constructors
,hen !riting c*de !ith e;cepti*n#, it# particularly i+p*rtant that y*u al!ay# a#k, I-9 an e;cepti*n *ccur#, !ill thi# 3e pr*perly cleaned upFJ A*#t *9 the ti+e y*ure 9airly #a9e, 3ut in c*n#truct*r# there# a pr*3le+) The c*n#truct*r put# the *34ect int* a #a9e #tarting #tate, 3ut it +ight per9*r+ #*+e *perati*nR#uch a# *pening a 9ileRthat d*e#nt get cleaned up until the u#er i# 9ini#hed !ith the *34ect and call# a #pecial cleanup +eth*d) -9 y*u thr*! an e;cepti*n 9r*+ in#ide a c*n#truct*r, the#e cleanup 3ehavi*r# +ight n*t *ccur pr*perly) Thi# +ean# that y*u +u#t 3e e#pecially diligent !hile y*u !rite y*ur c*n#truct*r) Since y*uve 4u#t learned a3*ut finally, y*u +ight think that it i# the c*rrect #*luti*n) But it# n*t Duite that #i+ple, 3ecau#e finally per9*r+# the cleanup c*de e-er4 time6 even in the #ituati*n# in !hich y*u d*nt !ant the cleanup c*de e;ecuted until the cleanup +eth*d run#) Thu#, i9 y*u d* per9*r+ cleanup in finally, y*u +u#t #et #*+e kind *9 9lag !hen the c*n#truct*r 9ini#he# n*r+ally #* that y*u d*nt d* anything in the finally 3l*ck i9 the 9lag i# #et) Becau#e thi# i#nt particularly elegant Gy*u are c*upling y*ur c*de 9r*+ *ne place t* an*therH, it# 3e#t i9 y*u try t* av*id per9*r+ing thi# kind *9 cleanup in finally unle## y*u are 9*rced t*) -n the 9*ll*!ing e;a+ple, a cla## called Bnput:ile i# created that *pen# a 9ile and all*!# y*u t* read it *ne line Gc*nverted int* a #tringH at a ti+e) -t u#e# the cla##e# :ile*eader and Buffered*eader 9r*+ the "ava #tandard -<O li3rary that !ill 3e di#cu##ed in Chapter 00, 3ut !hich are
515
#i+ple en*ugh that y*u pr*3a3ly !*nt have any tr*u3le under#tanding their 3a#ic u#e1 //:c0>:Con#tructorHina y.c# // -aying attention to exception# // in con#tructor#. u#ing Sy#te!3 u#ing Sy#te!.5O3 na!e#pace C eanup; interna c a## 5nputHi e : 5:i#po#a$ e ; pri*ate Strea!Reader inStrea!3 interna 5nputHi e0#tring fCa!e1 ; try ; inStrea! 9 ne. Strea!Reader0 ne. Hi eStrea!0 fCa!e2 Hi eGode.Open113 // Other code that !ight thro. exception# < catch 0Hi eCotHound+xception e1 ; Sy#te!.Con#o e.+rror.VriteLine0 &Cou d not open & R fCa!e13 // Va#n't open2 #o don't c o#e it thro. e3 < catch 0+xception e1 ; // ) other exception# !u#t c o#e it try ; inStrea!.C o#e013 < catch 05O+xception 1 ; Sy#te!.Con#o e.+rror.VriteLine0 &in.C o#e01 un#ucce##fu &13 < thro. e3 // Rethro. < fina y ; // :on't c o#e it here!!! < <
516
Thinking in C
www.ThinkingIn.!et
interna #tring ReadLine01 ; #tring #3 try ; # 9 inStrea!.ReadLine013 < catch 05O+xception 1 ; Sy#te!.Con#o e.+rror.VriteLine0 &ReadLine01 un#ucce##fu &13 # 9 &fai ed&3 < return #3 < pu$ ic *oid :i#po#e01 ; try ; inStrea!.C o#e013 < catch 05O+xception 1 ; Sy#te!.Con#o e.+rror.VriteLine0 &in.C o#e01 un#ucce##fu &13 < < < pu$ ic c a## C eanup ; pu$ ic #tatic *oid Gain01 ; try ; 5nputHi e inHi e 9 ne. 5nputHi e0&C eanup.c#&13 u#ing0inHi e1; String #3 int i 9 "3 .hi e 00# 9 inHi e.ReadLine011 !9 nu 1 Sy#te!.Con#o e.VriteLine0 &&R iR R R &: & R #13 < < catch 0+xception e1 ; Sy#te!.Con#o e.+rror.VriteLine0 &Caught in Gain&13
51#
Sy#te!.Con#o e.+rror.VriteLine0 e.Stac%'race13 < < < < ///:8 The c*n#truct*r 9*r Bnput:ile take# a string argu+ent, !hich i# the na+e *9 the 9ile y*u !ant t* *pen) -n#ide a try 3l*ck, it create# a :ile#tream u#ing the 9ile na+e) = :ile#tream i#nt particularly u#e9ul 9*r te;t until y*u turn ar*und and u#e it t* create a #tream*eader that can deal !ith +*re than *ne character at a ti+e) -9 the :ile#tream c*n#truct*r i# un#ucce##9ul, it thr*!# a :ile,ot:ound&xception, !hich +u#t 3e caught #eparately 3ecau#e that# the *ne ca#e in !hich y*u d*nt !ant t* cl*#e the 9ile #ince it !a#nt #ucce##9ully *pened) =ny other catch clau#e# +u#t cl*#e the 9ile 3ecau#e it was *pened 3y the ti+e th*#e catch clau#e# are entered) GO9 c*ur#e, thi# i# trickier i9 +*re than *ne +eth*d can thr*! a :ile,ot:ound&xception) -n that ca#e, y*u +ight !ant t* 3reak thing# int* #everal try 3l*ck#)H The Close( ) +eth*d +ight thr*! an e;cepti*n #* it i# tried and caught even th*ugh it# !ithin the 3l*ck *9 an*ther catch clau#eRit# 4u#t an*ther pair *9 curly 3race# t* the C# c*+piler) =9ter per9*r+ing l*cal *perati*n#, the e;cepti*n i# rethr*!n, !hich i# appr*priate 3ecau#e thi# c*n#truct*r 9ailed, and y*u !*uldnt !ant the calling +eth*d t* a##u+e that the *34ect had 3een pr*perly created and !a# valid) -n thi# e;a+ple, !hich d*e#nt u#e the a9*re+enti*ned 9lagging techniDue, the finally clau#e i# de9initely not the place t* Close( ) the 9ile, #ince that !*uld cl*#e it every ti+e the c*n#truct*r c*+pleted) Since !e !ant the 9ile t* 3e *pen 9*r the u#e9ul li9eti+e *9 the Bnput:ile *34ect thi# !*uld n*t 3e appr*priate) The *eadLine( ) +eth*d return# a string c*ntaining the ne;t line in the 9ile) -t call# #tream*eader6*eadLine( ), !hich can thr*! an e;cepti*n, 3ut that e;cepti*n i# caught #* *eadLine( ) d*e#nt thr*! any e;cepti*n#)
51&
Thinking in C
www.ThinkingIn.!et
The $ispose( ) +eth*d +u#t 3e called !hen the Bnput:ile i# 9ini#hed !ith) Thi# !ill relea#e the #y#te+ re#*urce# G#uch a# 9ile handle#H that are u#ed 3y the #tream*eader and<*r :ile#tream *34ect#) :*u d*nt !ant t* d* thi# until y*ure 9ini#hed !ith the Bnput:ile *34ect, at the p*int y*ure g*ing t* let it g*) :*u +ight think *9 putting #uch 9uncti*nality int* a de#truct*r +eth*d, 3ut a# +enti*ned in Chapter #initiali7ati*n and cleanup# y*u cant al!ay# 3e #ure !hen the de#truct*r !ill 3e called Geven i9 y*u can 3e #ure that it !ill 3e called, all y*u kn*! a3*ut when i# that it# #ure t* 3e called 3e9*re the pr*ce## end#H) -n the Cleanup cla##, an Bnput:ile i# created t* *pen the #a+e #*urce 9ile that create# the pr*gra+, the 9ile i# read in a line at a ti+e, and line nu+3er# are added) The using key!*rd i# u#ed t* en#ure that Bnput:ile6$ispose() i# called) =ll e;cepti*n# are caught generically in .ain( ), alth*ugh y*u c*uld ch**#e greater granularity) One *9 the 3ene9it# *9 thi# e;a+ple i# t* #h*! y*u !hy e;cepti*n# are intr*duced at thi# p*int in the 3**kRy*u cant d* 3a#ic -<O !ith*ut u#ing e;cepti*n#) E;cepti*n# are #* integral t* pr*gra++ing in C# that y*u can acc*+pli#h *nly #* +uch !ith*ut kn*!ing h*! t* !*rk !ith the+)
%&ce$tion #atching
,hen an e;cepti*n i# thr*!n, the e;cepti*n handling #y#te+ l**k# thr*ugh the Ineare#tJ handler# in the *rder they are !ritten) ,hen it 9ind# a +atch, the e;cepti*n i# c*n#idered handled, and n* 9urther #earching *ccur#) Aatching an e;cepti*n d*e#nt reDuire a per9ect +atch 3et!een the e;cepti*n and it# handler) = derivedEcla## *34ect !ill +atch a handler 9*r the 3a#e cla##, a# #h*!n in thi# e;a+ple1 //:c0>:SneeMe.c# // Catching exception hierarchie#. u#ing Sy#te!3 c a## )nnoyance : +xception ;< c a## SneeMe : )nnoyance ;< pu$ ic c a## Uu!an ;
51'
pu$ ic #tatic *oid Gain01 ; try ; thro. ne. SneeMe013 < catch0SneeMe 1 ; Sy#te!.Con#o e.+rror.VriteLine0&Caught SneeMe&13 < catch0)nnoyance 1 ; Sy#te!.Con#o e.+rror.VriteLine0&Caught )nnoyance&13 < < < ///:8 The #neeTe e;cepti*n !ill 3e caught 3y the 9ir#t catch clau#e that it +atche#R!hich i# the 9ir#t *ne, *9 c*ur#e) H*!ever, i9 y*u re+*ve the 9ir#t catch clau#e, leaving *nly1 try ; thro. ne. SneeMe013 < catch0)nnoyance1 ; Sy#te!.Con#o e.+rror.VriteLine0&Caught )nnoyance&13 < The c*de !ill #till !*rk 3ecau#e it# catching the 3a#e cla## *9 #neeTe) Put an*ther !ay, catch('nnoyance e) !ill catch an 'nnoyance or an4 class deri-ed $rom it) Thi# i# u#e9ul 3ecau#e i9 y*u decide t* add +*re derived e;cepti*n# t* a +eth*d, then the client pr*gra++er# c*de !ill n*t need changing a# l*ng a# the client catche# the 3a#e cla## e;cepti*n#) -9 y*u try t* I+a#kJ the derivedEcla## e;cepti*n# 3y putting the 3a#eEcla## catch clau#e 9ir#t, like thi#1 try ; thro. ne. SneeMe013 < catch0)nnoyance a1 ; Sy#te!.Con#o e.+rror.VriteLine0&Caught )nnoyance&13 < catch0SneeMe #1 ; Sy#te!.Con#o e.+rror.VriteLine0&Caught SneeMe&13 <
5)(
Thinking in C
www.ThinkingIn.!et
the c*+piler !ill give y*u an err*r +e##age, #ince it #ee# that the #neeTe catchEclau#e can never 3e reached)
%&ce$tion guidelines
U#e e;cepti*n# t*1 () 5i; the pr*3le+ and call the +eth*d that cau#ed the e;cepti*n again) 6) Patch thing# up and c*ntinue !ith*ut retrying the +eth*d) 0$) Calculate #*+e alternative re#ult in#tead *9 !hat the +eth*d !a# #upp*#ed t* pr*duce) 00) ?* !hatever y*u can in the current c*nte;t and rethr*! the same e;cepti*n t* a higher c*nte;t) 02) ?* !hatever y*u can in the current c*nte;t and thr*! a di$$erent e;cepti*n t* a higher c*nte;t) 0/) Ter+inate the pr*gra+) 0&) Si+pli9y) G-9 y*ur e;cepti*n #che+e +ake# thing# +*re c*+plicated, then it i# pain9ul and ann*ying t* u#e)H 0') Aake y*ur li3rary and pr*gra+ #a9er) GThi# i# a #h*rtEter+ inve#t+ent 9*r de3ugging, and a l*ngEter+ inve#t+ent G9*r applicati*n r*3u#tne##)H
'u##ar5
-+pr*ved err*r rec*very i# *ne *9 the +*#t p*!er9ul !ay# that y*u can increa#e the r*3u#tne## *9 y*ur c*de) Err*r rec*very i# a 9unda+ental c*ncern 9*r every pr*gra+ y*u !rite, 3ut it# e#pecially i+p*rtant in C#, !here *ne *9 the pri+ary g*al# i# t* create pr*gra+ c*+p*nent# 9*r *ther# t* u#e) To create a ro2ust s4stem6 each com"onent must 2e ro2ust. E;cepti*n# are n*t terri3ly di99icult t* learn, and are *ne *9 th*#e 9eature# that pr*vide i++ediate and #igni9icant 3ene9it# t* y*ur pr*4ect)
5)1
%&ercises
5))
Thinking in C
www.ThinkingIn.!et
11, I?O in C#
Creating a g**d input<*utput G-<OH #y#te+ i# *ne *9 the +*re di99icult ta#k# 9*r the language de#igner)
Thi# i# evidenced 3y the nu+3er *9 di99erent appr*ache#) The challenge #ee+# t* 3e in c*vering all eventualitie#) *t *nly are there di99erent #*urce# and #ink# *9 -<O that y*u !ant t* c*++unicate !ith G9ile#, the c*n#*le, net!*rk c*nnecti*n#H, 3ut y*u need t* talk t* the+ in a !ide variety *9 !ay# G#eDuential, rand*+Eacce##, 3u99ered, 3inary, character, 3y line#, 3y !*rd#, etc)H) The ) ET li3rary de#igner# attacked thi# pr*3le+ 3y creating l*t# *9 cla##e#) -n 9act, there are #* +any cla##e# 9*r ) ET# -<O #y#te+ that it can 3e inti+idating at 9ir#t Gir*nically, the de#ign actually prevent# an e;pl*#i*n *9 cla##e#H) =# a re#ult there are a 9air nu+3er *9 cla##e# t* learn 3e9*re y*u under#tand en*ugh *9 ) ET# -<O picture t* u#e it pr*perly)
5)3
#tatic +eth*d#1 !ath, $irectory, and :ile) The#e cla##e# have #*+e!hat c*n9u#ing na+e# in that there# n* c*rre#p*ndence 3et!een *34ect in#tance# and ite+# !ithin the 9ileE#y#te+ Gindeed, y*u cant in#tantiate the#e cla##e# P their c*n#truct*r# are n*t pu3licH)
) director5 lister
Let# #ay y*u !ant t* li#t the na+e# *9 the 9ile# in the direct*ry) Thi# i# ea#ily d*ne !ith the #tatic $irectory6 et:iles() +eth*d, a# i# #h*!n in thi# #a+ple1 //c"":HLi#t.c# //:i#p ay# directory u#ing Sy#te!.5O3 i#ting
pu$ ic c a## HLi#t; pu$ ic #tatic *oid Gain0#tringJK arg#1; #tring dir'oRead 9 &.&3 #tring pattern 9 &=&3 if0arg#.Length Z 01; dir'oRead 9 arg#J0K3 < if0arg#.Length Z "1; pattern 9 arg#J"K3 < #tringJK f-ath# 9 :irectory._etHi e#0dir'oRead2 pattern13 foreach0#tring f-ath in f-ath#1;
5)4
Hi e5nfo f5nfo 9 ne. Hi e5nfo0f-ath13 Sy#te!.Con#o e.VriteLine0 &-ath 9 ;0< Hi ena!e: ;"< ext: ;2< & R &touch: ;T< #iMe: ;E<&2 f-ath2 f5nfo.Ca!e2 f5nfo.+xten#ion2 f5nfo.La#tVrite'i!e2 f5nfo.Length13 Sy#te!.Con#o e.VriteLine0fCa!e13 < < <///:8 ,hen run !ith n* argu+ent#, thi# return# all the na+e# in the current direct*ryQ an*ther direct*ry can 3e #peci9ied !ith the 9ir#t argu+ent, and a #tandard ?OS 9ilena+e pattern !ith the #ec*nd) =n *verl*ad *9 the $irectory6 et:iles() +eth*d take# 4u#t a #ingle #tring, !hich i# eDuivalent t* calling $irectory6 et:iles(dir#tring, G;G)6 The +eth*d $irectory6 et:iles() i# a little p**rly na+ed, it# really returned #tring# that repre#ent the path# t* 9ile# G#* perhap# it !*uld have 3een 3etter na+ed et:ile!aths()H) T* get in9*r+ati*n *n the c*rre#p*nding 9ile, the path i# pa##ed in t* a :ileBnfo c*n#truct*r) The :ileBnfo and related $irectoryBnfo cla##e# encap#ulate !hat the 9ile #y#te+ kn*!# P thing# like #i7e, ti+e *9 creati*n and la#t edit, attri3ute# #uch a# 3eing ReadOnly, etc)
5)5
if0arg#.Length Z 01; dir'oRead 9 arg#J0K3 < if0arg#.Length Z "1; pattern 9 arg#J"K3 < #tringJK #u$dir# 9 :irectory._et:irectorie#0 dir'oRead2 pattern13 foreach0#tring #u$dir in #u$dir#1; :irectory5nfo d5nfo 9 ne. :irectory5nfo0#u$dir13 Sy#te!.Con#o e.VriteLine0 &-ath 9 ;0< Created: ;"< )cce##ed: ;2< & R & Vritten to ;T< &2 #u$dir2 d5nfo.Creation'i!e2 d5nfo.La#t)cce##'i!e2 d5nfo.La#tVrite'i!e13 < < <///:8 -n additi*n t* getting in9*r+ati*n *n 9ile# and direct*rie#, the :ile and $irectory cla##e# c*ntain +eth*d# 9*r creating, deleting, and +*ving 9ile#y#te+ entitie#) Thi# e;a+ple #h*!# h*! t* create ne! #u3direct*rie#, 9ile#, and delete direct*rie#1 //:c"":Hi eGanip //:e!on#trate# $a#ic fi e#y#te! !anipu ation u#ing Sy#te!3 u#ing Sy#te!.5O3 c a## Hi eGanip; pu$ ic #tatic *oid Gain01; #tring cur-ath 9 :irectory._etCurrent:irectory013 :irectory5nfo cur:ir 9 ne. :irectory5nfo0cur-ath13 #tring curCa!e 9 cur:ir.Ca!e3 charJK char# 9 curCa!e.'oChar)rray013 )rray.Re*er#e0char#13 #tring re*Ca!e 9 ne. String0char#13 if0:irectory.+xi#t#0re*Ca!e11;
5)6
Thinking in C
www.ThinkingIn.!et
:irectory.:e ete0re*Ca!e2 true13 <e #e; :irectory.Create:irectory0re*Ca!e13 #tring fCa!e 9 &./& R re*Ca!e R &/Hoo.fi e&3 Hi e.Create0fCa!e13 < < <///:8 5ir#t, !e u#e $irectory6 etCurrent$irectory() t* retrieve the current pathQ the #a+e data i# al#* availa3le a# &nvironment6Current$irectory) T* get the current direct*ry# na+e, !e u#e the $irectoryBnfo cla## and it# ,ame pr*perty) The na+e *9 *ur ne! direct*ry i# the current direct*ry# na+e in rever#e) The 9ir#t ti+e thi# pr*gra+ run#, $irectory6&xists() !ill return 9al#e Gunle## y*u happen t* run thi# pr*gra+ in a direct*ry !ith a rever#edEna+e #u3direct*ry already thereKH) -n that ca#e, !e u#e $irectory6Create$irectory() and :ile6Create() Gn*te the #light inc*n#i#tency in na+ingH t* create a ne! #u3direct*ry and a 9ile) -9 y*u check, y*ull #ee that I5**)9ileJ i# *9 length $ P :ile6Create() !*rk# at the 9ile#y#te+ level, n*t at the level *9 actually initiali7ing the 9ile !ith u#e9ul data) The #ec*nd ti+e :ile.anip i# run, the &xists() +eth*d !ill return true and $irectory6$elete() delete# 3*th the direct*ry and all its contents6 including $iles and su2directories) -9 y*u d*nt !ant thi# highly danger*u# 3ehavi*r, either pa## in a false value, *r u#e the *verl*aded $irectory6$elete(string) !hich d*e#nt take a 3**l and !hich !ill thr*! an B1&xception i9 called *n a n*nEe+pty direct*ry)
'solated Stores
S*+e *9 the +*#t c*++*n 9ileE*riented ta#k# are a##*ciated !ith a #ingle u#er1 pre9erence# #h*uld 3e #et t* individual u#er#, #ecurity dictate# that there 3e re#tricti*n# *n ar3itrary 9ile +anipulati*n 3y c*+p*nent# d*!nl*aded *99 the ,e3, etc) -n the#e #cenari*#, the ) ET 5ra+e!*rk pr*vide# 9*r isolated storage) =n i#*lated #t*re i# a virtual 9ile #y#te+ !ithin a data com"artment) = data c*+part+ent i# 3a#ed *n the u#er, a##e+3ly, and perhap# *ther a#pect# *9 the c*de# identity Ge)g), it# #ignatureH) -#*lated #t*rage i# 9*r th*#e #ituati*n# !hen y*u d*nt need *r !ant data3a#eElevel #ecurity and c*ntr*lQ i#*lated #t*re# end up a# 9ile# *n
5)#
the hardEdrive and !hile *peratingE#y#te+ re#tricti*n# +ay prevent the+ 9r*+ 3eing ca#ually availa3le, it# n*t appr*priate t* u#e i#*lated #t*rage 9*r highEvalue data) >etting an i#*lated #t*re 9*r the current a##e+3ly i# #traight9*r!ard i9 !*rdy, *ne u#e# a #tatic +eth*d called etVser#tore:or'ssembly() in the Bsolated#torage:ile cla##1 //c"":5#oStore.c# u#ing Sy#te!.5O.5#o atedStorage3 c a## 5#oStore; pu$ ic #tatic *oid Gain01; 5#o atedStorageHi e i#f 9 5#o atedStorageHi e._etO#erStoreHor)##e!$ y013 Sy#te!.Con#o e.VriteLine0 &)##e!$ y identity ;0< ^n& R &CurrentSiMe ;"< ^n& R &Gaxi!u!SiMe ;2< ^n& R &Scope ;T< ^n&2 i#f.)##e!$ y5dentity2 i#f.CurrentSiMe2 i#f.Gaxi!u!SiMe2 i#f.Scope13 < <///:8 5ir#t, !e have t* #peci9y that !ere u#ing the #ystem6B16Bsolated#torage na+e#pace) =9ter !e create the i#*lated #t*re, !e print #*+e *9 it# attri3ute# t* the c*n#*le) = typical run l**k# like thi#1 )##e!$ y identity WSy#te!.Security.-o icy.Or *er#ion9&"&Z WOr Zfi e://::/tic/chap""/5#oStore.exeW/Or Z W/Sy#te!.Security.-o icy.Or Z CurrentSiMe 0 Gaxi!u!SiMe >22TTF20T?IPEFFPI0F Scope O#er2 )##e!$ y Becau#e !eve n*t d*ne any digital #igning G#ee chapter ##ecurity#H, the identit4 *9 the a##e+3ly thi# i# 3eing run 9r*+ i# #i+ply the na+e *9 the
5)&
Thinking in C
www.ThinkingIn.!et
a##e+3ly a# a URL) The #t*re c*n#u+e# n* #pace currently and !*uld 3e all*!ed t* c*n#u+e a# +uch a# 6>B) The #t*re that !eve g*t a handle *n i# a##*ciated !ith the u#er and a##e+3ly# identityQ i9 !e changed either *9 th*#e, !ed get a di99erent i#*lated #t*re) The Bsolated:ile#tore i# e##entially a virtual 9ile #y#te+, 3ut un9*rtunately it d*e# n*t #upp*rt the general #ystem6B1 cla##e# #uch a# $irectory, $irectoryBnfo, :ile, and :ileBnfo) Rather, the Bsolated:ile#tore cla## ha# #tatic +eth*d# et$irectory,ames() and et:ile,ames() !hich c*rre#p*nd t* $irectory6 et$irectories() and $irectory6 et:ile,ames()) Thi# i# Duite clu+#y, a# *ne cann*t u#e *34ect# t* traver#e d*!n a tree *9 direct*rie# Ga# *ne can d* !ith the $irectory cla##H, 3ut rather +u#t per9*r+ #tring +anipulati*n t* c*n#truct path# !ithin the i#*lated #t*re) H*pe9ully 9uture ver#i*n# *9 the 9ra+e!*rk !ill +*ve t*!ard# c*n#i#tency !ith the #ystem6B1 na+e#pace#)
5)'
3ene9it# *9 aggregating inter9ace# t* #peci9y the +i; *9 a3#tract data type# in an i+ple+entati*n) Rather than d* that, the ) ET -O cla##e# have an *verlyEinclu#ive #tream 3a#e cla## and a tri* *9 pu3lic in#tance pr*pertie# Can*ead, Can=rite, and Can#ee( that #u3#titute 9*r !hat #h*uld 3e type in9*r+ati*n) The +*tivati*n 9*r thi# !a# pr*3a3ly a !ellE +eaning de#ire t* av*id an Ie;pl*#i*nJ in type# and inter9ace#, 3ut g**d de#ign i# a# #i+ple a# p*##i3le and no sim"ler) By g*ing t** 9ar !ith #tream, and !ith an un9*rtunate hand9ul *9 na+ing and 3ehavi*r inc*n#i#tencie#, the #ystem6B1 na+e#pace can 3e Duite 9ru#trating)
-5$es o0 Stream
Cla##e# de#cended 9r*+ #tream c*+e in t!* type#1 i+ple+entati*n cla##e# a##*ciated !ith a particular type *9 data #ink *r #*urce1 0) Ae+*ryStrea+# are the #i+ple#t #trea+# and !*rk !ith inE+e+*ry data repre#entati*n# 2) 5ileStrea+# !*rk !ith 9ile# and add 9uncti*n# 9*r l*cking the 9ile 9*r e;clu#ive acce##) -#*latedSt*rage5ileStrea+ de#cend# 9r*+ 5ileStrea+ and i# u#ed 3y i#*lated #t*re#) /) et!*rkStrea+# are very help9ul !hen net!*rk pr*gra++ing and encap#ulate G3ut pr*vide acce## t*H an underlying net!*rk #*cket)
=nd cla##e# !hich are u#ed t* dyna+ically add additi*nal re#p*n#i3ilitie# t* *ther #trea+#1 0) Crypt*Strea+# can enc*de and dec*de any *ther #trea+#, !hether th*#e #trea+# *riginate in +e+*ry, the 9ile #y#te+, *r *ver a net!*rk) 2) Bu99eredStrea+# i+pr*ve the per9*r+ance *9 +*#t #trea+ #cenari*# 3y reading and !riting 3yte# in large chunk#, rather than *ne at a ti+e) Cla##e# #uch a# Crypto#tream and Buffered#tream are called I,rapperJ *r I?ec*rat*rJ cla##e# G#ee Thinking in /atternsH)
53(
Thinking in C
www.ThinkingIn.!et
=ll t*ld, there are 6$ di99erent valid c*+3inati*n# *9 the#e three a#pect# and !hile it can 3e c*n9u#ing at 9ir#t, it# clearer than having, 9*r in#tance, a cla## called BinaryCrypto:ile*eader) "u#t t* keep y*u *n y*ur t*e#, th*ugh, #tream*eader and #tream=riter have #i3ling cla##e# #tring*eader and #tring=riter !hich !*rk directly *n #tring#, n*t #trea+#)
531
SourceStrea!0Strea! #rc1; thi#.#rc 9 #rc3 < /= #tatic SourceStrea! HorCet.or%Strea!01; #tring thin%ing5n 9 &....!icro#oft.co!&3 5-)ddre## tCet 9 :n#.Re#o *e0thin%ing5n1.)ddre##Li#tJ0K3 5-+nd-oint ep 9 ne. 5-+nd-oint0tCet2 I013 Soc%et # 9 ne. Soc%et0 )ddre##Ha!i y.5nterCet.or%2 Soc%et'ype.Strea!2 -rotoco 'ype.'cp 13 #.Connect0ep13 Cet.or%Strea! nStrea! 9 ne. Cet.or%Strea!0#13 SourceStrea! #rcStrea! 9 ne. SourceStrea!0nStrea!13 return #rcStrea!3 < =/ *oid Read) 01; Sy#te!.Con#o e.VriteLine0 &Reading #trea! of type & R #rc._et'ype0113 int nextByte3 .hi e 00nextByte 9 #rc.ReadByte011 !9 6"1 ; Sy#te!.Con#o e.Vrite00char1 nextByte13 < < pu$ ic #tatic *oid Gain01; SourceStrea! #rcStr 9 HorGe!oryStrea!013 #rcStr.Read) 013 #rcStr 9 HorHi eStrea!013 #rcStr.Read) 013 //#rcStr 9 HorCet.or%Strea!013 //#rcStr.Read) 013 <
53)
Thinking in C
www.ThinkingIn.!et
#tatic SourceStrea! HorGe!oryStrea!01; #tring aString 9 &!ary had a itt e a!$&3 Onicode+ncoding ue 9 ne. Onicode+ncoding013 char $yte# 9 ue._etByte#0aString13 Ge!oryStrea! !e!Strea! 9 ne. Ge!oryStrea!0$yte#13 SourceStrea! #rcStrea! 9 ne. SourceStrea!0!e!Strea!13 return #rcStrea!3 < #tatic SourceStrea! HorHi eStrea!01; #tring fCa!e 9 &SourceStrea!.c#&3 Hi eStrea! fStrea! 9 ne. Hi eStrea!0fCa!e2 Hi eGode.Open13 SourceStrea! #rcStrea! 9 ne. SourceStrea!0fStrea!13 return #rcStrea!3 < < The c*n#truct*r t* #ource#tream take# a #tream and a##ign# it t* the in#tance varia3le src, !hile the +eth*d *ead'll() read# that src *ne 3yte at a ti+e until the +eth*d return# E0, indicating that there are n* +*re 3yte#) Each 3yte read i# ca#t t* a char and #ent t* the c*n#*le) The .ain() +eth*d u#e# the #tatic +eth*d# :or.emory#tream() and :or:ile#tream() t* in#tantiate #ource#tream# and then call# the *ead'll() +eth*d) S* 9ar, all the c*de ha# dealt !ith #tream# n* +atter !hat their real #*urce, 3ut the #tatic +eth*d# +u#t nece##arily 3e #peci9ic t* the #u3type *9 #tream 3eing created) -n the ca#e *9 the .emory#tream, !e #tart !ith a string, u#e the Vnicode&ncoding cla## 9r*+ the #ystem6+ext na+e#pace t* c*nvert the string int* an array *9 bytes, and pa## the re#ult int* the .emory#tream c*n#truct*r) The .emory#tream g*e# t* the #ource#tream c*n#truct*r, and then !e return the #ource#tream)
533
5*r the 5ileStrea+, *n the *ther hand, !e have t* #peci9y an e;tant 9ilena+e and !hat 5ileA*de !e !i#h t* u#e t* *pen it) The 5ileA*de enu+erati*n include#1 +able 77-76 :ile.ode Halues :ile.ode6Halue 'ppend Behavior -9 the 9ile e;i#t#, *pen it and g* t* the end *9 the 9ile i++ediately) -9 the 9ile d*e# n*t e;i#t, create it) 5ile cann*t 3e read) Create# a ne! 9ile *9 the given na+e, e-en i$ that 9ile already e;i#t# Git era#e# the e;tant 9ileH) Create# a ne! 9ile, i$ it does not e%ist) -9 the 9ile e;i#t#, thr*!# an B1&xception) Open# an e;i#ting 9ile and thr*!# a :ile,ot:ound&xception *ther!i#e) Create# and *pen# a 9ile, creating a ne! 9ile i9 nece##ary Open# an e;i#ting 9ile and truncate# it# #i7e t* 7er*)
Create
534
Thinking in C
www.ThinkingIn.!et
as4mmetric algorithms have a Ipu3licJ key 9*r encrypti*n and a IprivateJ key 9*r decrypti*n) The ) ET 5ra+e!*rk c*+e# !ith #everal #y++etric alg*rith+# and t!* a#y++etric alg*rith+#, *ne 9*r general u#e and *ne that #upp*rt# the #tandard 9*r digital #ignature#)
Category Sy++etric
,ame ?ES
Characteristics Older US 5ederal #tandard 9*r I#en#itive 3ut n*t cla##i9iedJ data) '.E3it e99ective key) Cracked in 22 h*ur# 3y U2'$,$$$ cu#t*+ c*+puter, plu# 0$$N di#tri3uted PC#) -9 it# !*rth encrypting, it# !*rth n*t u#ing ?ES) =n e;ten#i*n *9 ?ES that ha# a 002E3it e99ective key Gn*te that thi# increa#e# cracking di99iculty 3y 2'.H) Caria3le key #i7e, i+ple+entati*n #ee+# t* 3e 9a#te#t #y++etric) =lg*rith+ ch*#en 9*r =dvanced Encrypti*n Standard, e99ectively ?ES replace+ent) 5a#t, varia3le and large key #i7e#, generally the 3e#t #y++etric cipher) Pr*n*unced IrainEdahlJ Cann*t 3e u#ed 9*r encrypti*nQ *nly g**d 9*r digital #igning) Patent e;pired, al+*#t #yn*ny+*u# !ith pu3licEkey crypt*pgraphy)
Sy++etric
Triple?ES
Sy++etric Sy++etric
RC2 Ri4ndael
=#y++etric =#y++etric
?S= RS=
Crypt*Strea+# are *nly created 3y the #y++etric alg*rith+#) //:c"":SecretCode.c# u#ing Sy#te!3 u#ing Sy#te!.5O3 u#ing Sy#te!.Security.Cryptography3
535
c a## SecretCode; #tring fi eCa!e3 #tring Hi eCa!e; get ; return fi eCa!e3 < #et ; fi eCa!e 9 *a ue3 < < RiDndae Ganaged r!3 SecretCode0#tring fCa!e1; fi eCa!e 9 fCa!e3 r! 9 ne. RiDndae Ganaged013 r!._enerateaey013 r!._enerate5N013 < *oid +ncode'oHi e0#tring outCa!e1; Hi eStrea! #rc 9 ne. Hi eStrea!0 fi eCa!e2 Hi eGode.Open13 5Crypto'ran#for! encoder 9 r!.Create+ncryptor013 CryptoStrea! #tr 9 ne. CryptoStrea!0 #rc2 encoder2 CryptoStrea!Gode.Read13 Hi eStrea! outHi e 9 ne. Hi eStrea!0 outCa!e2 Hi eGode.Create13 int i 9 03 .hi e00i 9 #tr.ReadByte011 !9 6"1; outHi e.VriteByte00$yte1i13 < #rc.C o#e013 outHi e.C o#e013 < *oid :ecode0#tring cypherHi e1; Hi eStrea! #rc 9 ne. Hi eStrea!0 cypherHi e2 Hi eGode.Open13
536
Thinking in C
www.ThinkingIn.!et
5Crypto'ran#for! decoder 9 r!.Create:ecryptor013 CryptoStrea! #tr 9 ne. CryptoStrea!0 #rc2 decoder2 CryptoStrea!Gode.Read13 int i 9 03 .hi e00i 9 #tr.ReadByte011 !9 6"1; Sy#te!.Con#o e.Vrite00char1 i13 < #rc.C o#e013 < pu$ ic #tatic *oid Gain0#tringJK arg#1; SecretCode #c 9 ne. SecretCode0arg#J0K13 #c.+ncode'oHi e0&encoded.dat&13 Sy#te!.Con#o e.VriteLine0&:ecoded:&13 #c.:ecode0&encoded.dat&13 < <///:8 The crypt*graphic pr*vider# are in the Sy#te+)Security)Crypt*graphy na+e#pace) Each alg*rith+ ha# 3*th a 3a#e cla## na+ed a9ter the alg*rith+ G?ES, Ri4ndael, RS=, etc)H and an i+ple+entati*n *9 that alg*rith+ pr*vided 3y Aicr*#*9t) Thi# i# a nice de#ign, all*!ing *ne t* plug in ne! i+ple+entati*n# *9 vari*u# alg*rith+# a# de#ired) The Sy#te+)Security)Crypt*graphy na+e#pace i# n*t part *9 Aicr*#*9t# #u3+i##i*n t* ECA= and there9*re the #*urce c*de i# n*t availa3le t* #crutiny a# part *9 the #haredE#*urce C*++*n Language -n9ra#tructure initiative that Aicr*#*9t i# trying t* u#e t* generate g**d!ill in the acade+ic c*++unity) =lth*ugh Aicr*#*9t# i+ple+entati*n# have 3een validated 3y the US and Canadian 5ederal g*vern+ent#, it# a pity that thi# #*urce c*de i# n*t availa3le 9*r pu3lic revie!) -n thi# ca#e, !e u#e the Ri4ndaelAanaged cla## that i+ple+ent# the Ri4ndael alg*rith+) Like the *ther i+ple+entati*n#, the Ri4ndaelAanaged cla## i# a3le t* generate rand*+ key# and initiali7ati*n vect*r#, a# #h*!n in the #ecretCode c*n#truct*r, !hich al#* #et# an in#tance varia3le file,ame t* the na+e *9 the 9ile !hich !ell 3e encrypting)
53#
&ncode+o:ile() *pen# a :ile#tream na+ed src t* *ur t*E3eE encrypted 9ile) The #y++etric crypt*graphic alg*rith+# each pr*vide a Create&ncryptor() and Create$ecryptor() +eth*d !hich return# an BCrypto+ransform that i# a nece##ary para+eter 9*r the Crypto#tream c*n#truct*r) ,ith the input #trea+ src, the BCrypto+ransform enc*der, and the Crypto#tream.ode6*ead +*de a# para+eter# !e generate a Crypto#tream called str) The out:ile #trea+ i# c*n#tructed in a 9a+iliar !ay 3ut thi# ti+e !ith :ile.ode6Create) ,e read the str Crypto#tream and !rite it t* the out:ile, u#ing the +eth*d =riteByte()) Once d*ne, !e cl*#e 3*th the #*urce 9ile and the ne!ly created encrypted 9ile) The +eth*d $ecode() d*e# the c*+ple+entQ it *pen# a :ile#tream, u#e# the *i)ndael.anaged in#tance t* create an BCrypto+ransform decoder and a Crypto#tream appr*priate 9*r reading the encrypted 9ile) ,e read the encrypted 9ile *ne 3yte at a ti+e and print the *utput *n the c*n#*le) The .ain() +eth*d create# a ne! #ecretCode cla##, pa##ing in the 9ir#t c*++andEline argu+ent a# the 9ilena+e t* 3e enc*ded) Then, the call t* &ncode+o:ile() encrypt# that 9ile t* an*ther called Ienc*ded)dat)J Once that 9ile i# created, it i# in turn dec*ded 3y the $ecode() +eth*d) One characteri#tic *9 a g**d encrypted #trea+ i# that it i# di99icult t* di#tingui#h 9r*+ a #trea+ *9 rand*+ dataQ #ince rand*+ data i# n*nE c*+pre##i3le, i9 y*u atte+pt t* c*+pre## Ienc*ded)datJ y*u #h*uld #ee tht #ure en*ugh the Ic*+pre##edJ 9ile i# larger than the *riginal)
53&
Thinking in C
www.ThinkingIn.!et
u#ing Sy#te!.5O3 c a## BinaryVrite; pu$ ic #tatic *oid Gain01; Strea! fStrea! 9 ne. Hi eStrea!0 &$inaryio.dat&2 Hi eGode.Create13 Vrite'ype#0fStrea!13 fStrea!.C o#e013 < #tatic *oid Vrite'ype#0Strea! #in%1; BinaryVriter $. 9 ne. BinaryVriter0#in%13 $..Vrite0true13 $..Vrite0fa #e13 $..Vrite00$yte1 F13 $..Vrite0ne. $yteJK ; "2 22 T2 E <13 $..Vrite0'M'13 $..Vrite0ne. charJK ; ')'2 'B'2 'C'2 ':' <13 $..Vrite0ne. :eci!a 0"2T.EP113 $..Vrite0"2T.EP13 $..Vrite00#hort1 2"213 $..Vrite00 ong1 2"213 $..Vrite0&W$oo eanZtrueW/$oo eanZ&13 < <///:8 Binary,rite# AainGH +eth*d create# a 5ileStrea+ 9*r !riting, upca#t# the re#ult t* #tream, pa##e# it t* the #tatic =rite+ypes() +eth*d, and a9ter!ard# cl*#e# it) The =rite+ypes() +eth*d take# the pa##ed in #tream and pa##e# it a# a para+eter t* the Binary=riter c*n#truct*r) Then, !e call Binary=riter6=rite() !ith vari*u# para+eter#, everything 9r*+ bool t* string) Behind the #cene#, the Binary=riter turn# the#e type# int* #eDuence# *9 3yte# and !rite# the+ t* the underlying #trea+) Every type, e;cept 9*r string, ha# a predeter+ined length in 3yte# P even 3**l#, !hich c*uld 3e repre#ented in a #ingle 3it, are #t*red a# a 9ull 3yte EEE #* it +ight 3e +*re accurate t* call thi# type *9 #t*rage I3yte dataJ rather than I3inary data)J T* #t*re a #tring, Binary=riter 9ir#t !rite#
53'
*ne *r +*re 3yte# t* indicate the nu+3er *9 3yte# that the #tring reDuire# 9*r #t*rageQ the#e 3yte# u#e % 3it# t* enc*de the length and the ( th 3it Gi9 nece##aryH t* indicate that the ne;t 3yte i# n*t the 9ir#t character *9 the #tring, 3ut an*ther length 3yte) The Binary=riter cla## d*e# n*thing !e c*uldnt d* *n *ur *!n, 3ut it# +uch +*re c*nvenient) aturally, there# a c*+ple+entary Binary*eader cla##, 3ut 3ecau#e *ne cann*t have p*ly+*rphi#+ 3a#ed *nly *n return type G#ee chapter #p*ly+*rphi#+#H, the +eth*d# 9*r reading vari*u# type# are a little l*nger1 //:c"":BinaryRead.c# u#ing Sy#te!3 u#ing Sy#te!.5O3 c a## BinaryRead; pu$ ic #tatic *oid Gain0#tringJK arg#1; Strea! fStrea! 9 ne. BufferedStrea!0 ne. Hi eStrea!0arg#J0K2 Hi eGode.Open113 Byte:u!p0fStrea!13 fStrea!.C o#e013 fStrea! 9 ne. BufferedStrea!0 ne. Hi eStrea!0arg#J0K2 Hi eGode.Open113 Read'ype#0fStrea!13 fStrea!.C o#e013 < #tatic *oid Byte:u!p0Strea! #rc1; int i 9 03 .hi e00i 9 #rc.ReadByte011 !9 6"1; Sy#te!.Con#o e.VriteLine0 &;0< 9 ;"< &2 0char1 i2 i13 < Sy#te!.Con#o e.VriteLine013 < #tatic *oid Read'ype#0Strea! #rc1; BinaryReader $r 9 ne. BinaryReader0#rc13 $oo $ 9 $r.ReadBoo ean013 Sy#te!.Con#o e.VriteLine0$13
54(
Thinking in C
www.ThinkingIn.!et
$ 9 $r.ReadBoo ean013 Sy#te!.Con#o e.VriteLine0$13 $yte $t 9 $r.ReadByte013 Sy#te!.Con#o e.VriteLine0$t13 $yteJK $yte)rray 9 $r.ReadByte#0E13 Sy#te!.Con#o e.VriteLine0$yte)rray13 char c 9 $r.ReadChar013 Sy#te!.Con#o e.VriteLine0c13 charJK char)rray 9 $r.ReadChar#0E13 Sy#te!.Con#o e.VriteLine0char)rray13 :eci!a d 9 $r.Read:eci!a 013 Sy#te!.Con#o e.VriteLine0d13 :ou$ e d$ 9 $r.Read:ou$ e013 Sy#te!.Con#o e.VriteLine0d$13 #hort # 9 $r.Read5nt"?013 Sy#te!.Con#o e.VriteLine0#13 ong 9 $r.Read5nt?E013 Sy#te!.Con#o e.VriteLine0 13 #tring tag 9 $r.ReadString013 Sy#te!.Con#o e.VriteLine0tag13 < <///:8 Binary*ead6.ain() intr*duce# an*ther !rapper cla##, Buffered#tream, !hich increa#e# the e99iciency *9 n*nE+e+*ryE3a#ed #trea+# 3y u#ing an internal +e+*ry 3u99er t* te+p*rarily #t*re the data rather than !riting a #ingle 3yte t* the underlying 9ile *r net!*rk) Bu99eredStrea+# are largely tran#parent t* u#e, alth*ugh the +eth*d :lush(), !hich #end# the c*ntent# *9 the 3u99er t* the underlying #trea+, regardle## *9 !hether it# 9ull *r n*t, can 3e u#ed t* 9ineEtune 3ehavi*r) Binary*ead !*rk# *n a 9ile !h*#e na+e i# pa##ed in *n the c*++and line) Byte$ump() #h*!# the c*ntent# *9 the 9ile *n the c*n#*le, printing the 3yte a# 3*th a character and di#playing it# deci+al value) ,hen run *n I3inaryi*)datJ, the run 3egin#1 d 9 " 9 0 9 F d 9 " e 9 2 f 9 T
541
g 9 E M 9 "22 ) 9 ?P B 9 ?? C 9 ?F : 9 ?I LetcL The 9ir#t t!* 3yte# repre#ent the B**lean value# true and 9al#e, !hile the ne;t part# *9 the 9ile c*rre#p*nd directly t* the value# *9 the 3yte# and char# !e !r*te !ith the pr*gra+ Binary=rite) The +*re c*+plicated data type# are harder t* interpret, 3ut t*!ard# the end *9 thi# +eth*d, y*ull #ee a 3yte value *9 202 that c*rre#p*nd# t* the short and the long !e !r*te) The la#t part *9 the *utput 9r*+ thi# +eth*d l**k# like thi#1 h W $ o o e a n Z t r u e W / $ o o e a n Z 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 2T ?0 >I """ """ "0I "0" >F ""0 ?2 ""? ""E ""F "0" ?0 EF >I """ """ "0I "0" >F ""0 ?2
54)
Thinking in C
www.ThinkingIn.!et
Thi# particular #tring, !hich c*n#u+e# 2& 3yte# *9 #t*rage G0 length 3yte, and 2/ character 3yte#H, i# the BAL eDuivalent *9 the #ingle 3yte at the 3eginning *9 the 9ile that #t*re# a bool) ,ell di#cu## BAL in length in chapter #BAL#, 3ut thi# #h*!# the pri+ary tradeE*99 3et!een 3inary data and BAL P e99iciency ver#u# de#criptivene##) -r*nically, !hile l*cal #t*rage i# e;periencing greaterEthanEA**re#ELa! increa#e# in data den#ity Gand there3y 3ec*+ing cheaper and cheaperH and net!*rk 3and!idth Ge#pecially t* the h*+e and *ver !irele##H !ill 3e a pr*3le+ 9*r the 9*re#eea3le 9uture, 9ile 9*r+at# re+ain pri+arily 3inary and BAL i# e;pl*ding a# the *verEnet!*rk 9*r+at *9 ch*iceK =9ter Binary*ead du+p# the ra! data t* the c*n#*le, it then read# the #a+e #trea+, thi# ti+e !ith the #tatic +eth*d *ead+ypes()) *ead+ypes() in#tantiate# a Binary*eader() and call# it# vari*u# *eadxxx() +eth*d# in e;act c*rre#p*ndence t* the Binary=riter6=rite() +eth*d# *9 Binary=rite6=rite+ypes()) ,hen run *n 3inaryi*)dat, Binary*ead6*ead+ypes() repr*duce# the e;act data, 3ut y*u can al#* run the pr*gra+ *n any 9ile and it !ill ga+ely interpret that pr*gra+# 3yte# a# the #peci9ied type#) Here# the *utput !hen Binary*ead i# run *n it# *!n #*urce 9ile1 'rue 'rue PI Sy#te!.ByteJK B inar 6T.PFT22?F>22"T??T?P"F"IIEPF0I"+6FP ?.2F?TEI?TE02P2+62EP 2>>?2 IT20FFT"IP"IT0P00>> e!.5O3 c a## BinaryRead; pu$ ic #tatic *oid Gain0#tringJK arg#1; Strea! fStrea! 9 ne. BufferedStrea!0 =gain, thi# i# the price t* 3e paid 9*r the e99iciency *9 3yte data P the #lighte#t di#crepancy 3et!een the type# #peci9ied !hen the data i# !ritten and !hen it i# read lead# t* inc*rrect data value#, 3ut the pr*3le+ !ill
543
pr*3a3ly n*t 3e detected until #*+e other +eth*d atte+pt# t* u#e thi# !r*ng data)
544
Thinking in C
www.ThinkingIn.!et
create# a ne! #tream*eader t* dec*rate the Buffered#tream and u#e# #tream*eader6*eadLine() t* read the underlying #trea+ a line at a ti+e) #tream*eader6*eadLine() return# a null re9erence at the end *9 the 9ile, ending the *utput l**p) Strea+Reader i# u#e9ul 9*r !riting line# and 3l*ck# *9 te;t, and c*ntain# a #le! *9 *verl*aded =rite() +eth*d# #i+ilar t* th*#e in Binary,riter, a# thi# e;a+ple #h*!#1 //:c"":'extVrite.c# u#ing Sy#te!3 u#ing Sy#te!.5O3 c a## 'extVrite; pu$ ic #tatic *oid Gain01; Strea! fStrea! 9 ne. Hi eStrea!0 &textio.dat&2 Hi eGode.Create13 VriteLine'ype#0fStrea!13 fStrea!.C o#e013 < #tatic *oid VriteLine'ype#0Strea! #in%1; Strea!Vriter #. 9 ne. Strea!Vriter0#in%13 #..VriteLine0true13 #..VriteLine0fa #e13 #..VriteLine00$yte1 F13 #..VriteLine0'M'13 #..VriteLine0ne. charJK ; ')'2 'B'2 'C'2 ':' <13 #..VriteLine0ne. :eci!a 0"2T.EP113 #..VriteLine0"2T.EP13 #..VriteLine00#hort1 2"213 #..VriteLine00 ong1 2"213 #..VriteLine0&;0< : ;"<&2 &#tring for!atting #upported&2 &true&13 #..C o#e013 < <///:8
545
Like the Binary,rite #a+ple, thi# pr*gra+ create# a 9ile#trea+ Gthi# ti+e 9*r a 9ile called Ite;ti*)datJH and pa##e# that t* an*ther +eth*d that dec*rate# the underlying data #ink and !rite# t* it) -n additi*n t* =rite() +eth*d# that are *verl*aded t* !rite the pri+itive type#, #tream=riter !ill call +o#tring() *n an4 *34ect and #upp*rt# #tring 9*r+atting) -n *ne *9 the na+e#pace# ann*yance#, #tream=riter i# 3u99ered Galth*ugh it d*e#nt de#cend 9r*+ Buffered#treamH, and #* y*u +u#t e;plicitly call Close() in *rder t* 9lu#h the line# t* the underlying #trea+) The data !ritten 3y #tream=riter i# in te;t 9*r+at, a# #h*!n in the c*ntent# *9 te;ti*)dat1 'rue Ha #e F M )BC: "2T.EP "2T.EP 2"2 2"2 #tring for!atting #upported : true Bear in +ind that #tream*eader d*e# n*t have *eadxxx() +eth*d# P i9 y*u !ant t* #t*re pri+itive type# t* 3e read and u#ed a# pri+itive type#, y*u #h*uld u#e the 3yteE*riented *eader and =riter cla##e#) :*u could #t*re the data a# te;t, read it a# te;t, and then per9*r+ the vari*u# #tring par#ing *perati*n# t* recreate the value#, 3ut that !*uld 3e !a#te9ul) -t# !*rth n*ting that #tream*eader and #tream=riter have #i3ling cla##e# #tring*eader and #tring=riter that are de#cended 9r*+ the #a+e *eader and =riter a3#tracti*n) Since string *34ect# are i++uta3le G*nce #et, a string cann*t 3e changedH, there i# a need 9*r an e99icient t**l 9*r 3uilding #tring# and c*+ple; 9*r+atting ta#k#) The 3a#ic ta#k *9 3uilding a #tring 9r*+ #u3#tring# i# handled 3y the #tringBuilder cla##, !hile the c*+ple; 9*r+atting can 3e d*ne !ith the #tring=riter G!hich dec*rate# a #tringBuilder in the #a+e !ay that the #tream=riter dec*rate# a #treamH)
546
Thinking in C
www.ThinkingIn.!et
54#
*oid :oSee%0See%Origin #o1; if 0#o 99 See%Origin.+nd1 ; #rc.See%06"02 #o13 < e #e ; #rc.See%0"02 #o13 < int i 9 #rc.ReadByte013 Sy#te!.Con#o e.VriteLine0 &"0 $yte# fro! ;0< i# : ;"<&2 #o2 0char1 i13 < pu$ ic #tatic *oid Gain0#tringJK arg#1; foreach0#tring fCa!e in arg#1; Hi eStrea! f 9 nu 3 try ; f 9 ne. Hi eStrea!0fCa!e2 Hi eGode.Open13 Hi$See% f# 9 ne. Hi$See%0f13 f#.:oSee%0See%Origin.Begin13 f#.:oSee%0See%Origin.+nd13 f.See%0"22 See%Origin.Begin13 f#.:oSee%0See%Origin.Current13 < catch 0+xception ex1 ; Sy#te!.Con#o e.VriteLine0ex13 < fina y ; f.C o#e013 < < < <///:8
'tandard I?O
The ter+ standard IF1 re9er# t* the Uni; c*ncept G!hich i# repr*duced in #*+e 9*r+ in ,ind*!# and +any *ther *perating #y#te+#H *9 a #ingle #trea+ *9 in9*r+ati*n that i# u#ed 3y a pr*gra+) =ll the pr*gra+# input can c*+e 9r*+ standard in"ut, all it# *utput can g* t* standard out"ut, and all *9 it# err*r +e##age# can 3e #ent t* standard error) The value *9 #tandard -<O i# that pr*gra+# can ea#ily 3e chained t*gether and *ne pr*gra+# #tandard *utput can 3ec*+e the #tandard input 9*r an*ther
54&
Thinking in C
www.ThinkingIn.!et
pr*gra+) A*re than 4u#t a c*nvenience, thi# i# a p*!er9ul architectural pattern called /i"es and +iltersQ alth*ugh thi# architecture !a# n*t very c*++*n in the 066$#, it# a very p*!er9ul *ne, a# any*ne !h*# !itne##ed a U -B guru can te#ti9y)
54'
GThere i# n* *3vi*u# rea#*n !hy the#e +eth*d# are u#ed rather than all*!ing the Pr*pertie# t* 3e #et directly)H Redirecting *utput i# e#pecially u#e9ul i9 y*u #uddenly #tart creating a large a+*unt *9 *utput *n y*ur #creen and it# #cr*lling pa#t 9a#ter than y*u can read it) Redirecting input i# valua3le 9*r a c*++andEline pr*gra+ in !hich y*u !ant t* te#t a particular u#erEinput #eDuence repeatedly) Here# a #i+ple e;a+ple that #h*!# the u#e *9 the#e +eth*d#1 //: c"":Redirecting.c# // :e!on#trate# #tandard 5/O redirection. u#ing Sy#te!3 u#ing Sy#te!.5O3 pu$ ic c a## Redirecting ; pu$ ic #tatic *oid Gain01; Strea!Reader #r 9 ne. Strea!Reader0 ne. BufferedStrea!0 ne. Hi eStrea!0 &Redirecting.c#&2 Hi eGode.Open1113 Strea!Vriter #. 9 ne. Strea!Vriter0 ne. BufferedStrea!0 ne. Hi eStrea!0 &redirect.dat&2 Hi eGode.Create1113 Sy#te!.Con#o e.Set5n0#r13 Sy#te!.Con#o e.SetOut0#.13 Sy#te!.Con#o e.Set+rror0#.13 String #3 .hi e00# 9 Sy#te!.Con#o e.5n.ReadLine011 !9 nu Sy#te!.Con#o e.Out.VriteLine0#13 Sy#te!.Con#o e.Out.C o#e013 // Re!e!$er thi#! < < ///:8 Thi# pr*gra+ attache# #tandard input t* a 9ile, and redirect# #tandard *utput and #tandard err*r t* an*ther 9ile)
55(
Thinking in C
www.ThinkingIn.!et
6egular %&$ressions
Regular e;pre##i*n# are a p*!er9ul patternE+atching t**l 9*r interpreting and +anipulating #tring#) =lth*ugh regular e;pre##i*n# are n*t nece##arily related t* input and *utput, it i# pr*3a3ly their +*#t c*++*n applicati*n, #* !ell di#cu## the+ here) Regular e;pre##i*n# have a l*ng hi#t*ry in the 9ield *9 c*+puter #cience 3ut c*ntinue t* 3e e;panded and i+pr*ved, !hich give# ri#e t* an inti+idating #et *9 capa3ilitie# and alternate r*ute# t* a given end) The regular e;pre##i*n# in the ) ET 5ra+e!*rk are Perl ' c*+pati3le 3ut include additi*nal 9eature# #uch a# rightEt*Ele9t +atching and d* n*t reDuire a #eparate c*+pilati*n #tep) The 9unda+ental re#p*n#i3ility *9 the #ystem6+ext6*egular&xpressions *egex cla## i# t* +atch a given pattern !ith a given target #tring) The pattern i# de#cri3ed in a ter#e n*tati*n that c*+3ine# literal te;t that +u#t appear in the target !ith +etaEte;t that #peci9ie# 3*th accepta3le variati*n# in te;t and de#ired +anipulati*n# #uch a# varia3le a##ign+ent *r te;t replace+ent) Thi# #a+ple print# *ut the 9ile na+e# and line# that +atch a regular e;pre##i*n typed in the c*++and line1 //:c"":'_rep.c# //:e!on#trate $a#ic regex !atching again#t fi e# u#ing Sy#te!3 u#ing Sy#te!.5O3 u#ing Sy#te!.'ext.Regu ar+xpre##ion#3 c a## '_rep; pu$ ic #tatic *oid Gain0#tringJK arg#1; '_rep tg 9 ne. '_rep0arg#J0K13 tg.)pp y'oHi e#0arg#J"K13 < Regex re3 '_rep0#tring pattern1; re 9 ne. Regex0pattern13 <
551
*oid )pp y'oHi e#0#tring f-attern1; #tringJK fCa!e# 9 :irectory._etHi e#0&.&2 f-attern13 foreach 0#tring fCa!e in fCa!e# 1 ; Strea!Reader #r 9 nu 3 try; #r 9 ne. Strea!Reader0 ne. BufferedStrea!0 ne. Hi eStrea!0 fCa!e2 Hi eGode.Open1113 #tring ine 9 &&3 int Count 9 03 .hi e00 ine 9 #r.ReadLine011 !9 nu 1; CountRR3 if0re.5#Gatch0 ine11; Sy#te!.Con#o e.VriteLine0 &;0< ;"<: ;2<&2 fCa!e2 Count2 ine13 < < <fina y; #r.C o#e013 < < < <///:8 The .ain() +eth*d pa##e# the 9ir#t c*++andEline argu+ent t* the + rep() c*n#truct*r, !hich in turn pa##e# it t* the *egex() c*n#truct*r) The #ec*nd argu+ent i# then pa##ed a# the argu+ent t* the 'pply+o:iles() +eth*d) 'pply+o:iles() u#e# -O techniDue# !eve di#cu##ed previ*u#ly t* read a #erie# *9 9ile# lineE3yEline and incre+enting the varia3le lCount t* let u# kn*! !hat line nu+3er !*rk#) Each line i# pa##ed t* the *egex6Bs.atch() +eth*d, and i9 that +eth*d return# true, the 9ilena+e, line nu+3er, and c*ntent# *9 the line are printed t* the #creen) :*u +ight gue## that Itgrep u#ing tgrep)c#J !*uld print line# /, &, and ' *9 tgrep)c#, 3ut y*u +ight n*t e;pect that Itgrep Z$E6\ tgrep)c#J !*uld print every line that c*ntain# a nu+3er, *r that Itgrep Zd#\9Zd!\bZd#\bX b)c#J
55)
Thinking in C
www.ThinkingIn.!et
!*uld print every line that a##ign# a value t* a varia3le that 3egin# !ith a l*!erca#e T9) Like SML in =?O) ET, the regular e;pre##i*n n*tati*n i# a #eparate language Duite unlike C#, and Thinking in ?egular E%"ressions !*uld 3e Duite a di99erent 3**k than thi# *ne) -n additi*n t* #i+ply deter+ining i9 a +atch e;i#t#, *egex can actually return the value *9 the +atche#, a# thi# pr*gra+ de+*n#trate#1 //:c"":_repGatche#.c# u#ing Sy#te!3 u#ing Sy#te!.5O3 u#ing Sy#te!.'ext.Regu ar+xpre##ion#3 c a## _repGatche#; pu$ ic #tatic *oid Gain0#tringJK arg#1; _repGatche# tg 9 ne. _repGatche#0arg#J0K13 #tring target 9 arg#J"K3 tg.)pp y'oHi e#0target13 < Regex re3 _repGatche#0#tring pattern1; re 9 ne. Regex0pattern13 < *oid )pp y'oHi e#0#tring f-attern1; #tringJK fCa!e# 9 :irectory._etHi e#0 &.&2 f-attern13 foreach 0#tring fCa!e in fCa!e# 1 ; Strea!Reader #r 9 nu 3 try; #r 9 ne. Strea!Reader0 ne. BufferedStrea!0 ne. Hi eStrea!0fCa!e2 Hi eGode.Open1113 #tring ine 9 &&3 int Count 9 03 .hi e00 ine 9 #r.ReadLine011 !9 nu 1; CountRR3
553
if0re.5#Gatch0 ine11; Sy#te!.Con#o e.VriteLine0 &;0< ;"<: ;2<&2 fCa!e2 Count2 Sho.Gatche#0re.Gatche#0 ine113 < < <fina y; #r.C o#e013 < < < pri*ate *oid Sho.Gatche#0GatchCo ection !c1; for0int i 9 03 i W !c.Count3 iRR1; Sy#te!.Con#o e.VriteLine0 &GatchJ;0<K 9 ;"<&2 i2 !cJiK13 < <
ine13
< *egex6.atches() return# a .atchCollection !hich naturally c*ntain# .atch *34ect#) Thi# #a+ple pr*gra+ can 3e help9ul in de3ugging the devel*p+ent *9 a regular e;pre##i*n, !hich 9*r +*#t *9 u# reDuire# a c*n#idera3le a+*unt *9 trial and err*rK The #tatic +eth*d Rege;)ReplaceGH can +ake c*+ple; tran#9*r+ati*n# #urpri#ingly #traight9*r!ard) Thi# #a+ple +ake# pattern #u3#tituti*n# in a te;t 9ile1 //:c"":'Sed.c# u#ing Sy#te!3 u#ing Sy#te!.5O3 u#ing Sy#te!.'ext.Regu ar+xpre##ion#3 c a## 'Sed; pu$ ic #tatic *oid Gain0#tringJK arg#1; 'Sed tg 9 ne. 'Sed0arg#J0K2 arg#J"K13 #tring target 9 arg#J2K3 tg.)pp y'oHi e#0target13 < #tring pattern3
554
Thinking in C
www.ThinkingIn.!et
#tring rep3 'Sed0#tring pattern2 #tring rep1; thi#.pattern 9 pattern3 thi#.rep 9 rep3 < *oid )pp y'oHi e#0#tring f-attern1; #tringJK fCa!e# 9 :irectory._etHi e#0&.&2 f-attern13 foreach 0#tring fCa!e in fCa!e# 1 ; Strea!Reader #r 9 nu 3 try; #r 9 ne. Strea!Reader0 ne. BufferedStrea!0 ne. Hi eStrea!0 fCa!e2 Hi eGode.Open1113 #tring ine 9 &&3 int Count 9 03 .hi e00 ine 9 #r.ReadLine011 !9 nu 1; #tring nLine 9 Regex.Rep ace0 ine2 pattern2 rep13 Sy#te!.Con#o e.VriteLine0nLine13 < <fina y; #r.C o#e013 < < < < Like the previ*u# #a+ple#, thi# *ne !*rk# !ith c*++andEline argu+ent#, 3ut thi# ti+e, in#tead *9 in#tantiating a *egex 9*r patternE+atching, the 9ir#t t!* c*++andEline argu+ent# are 4u#t #t*red a# #tring#, !hich are later pa##ed t* the *egex6*eplace() +eth*d) -9 the pattern +atche#, the replace+ent pattern i# in#erted int* the #tring, i9 n*t, the line i# unt*uched) ,hether t*uched *r n*t, the line i# !ritten t* the c*n#*leQ thi# +ake# thi# pr*gra+ a ItinyJ ver#i*n *9 U -B# #ed c*++and and i# very c*nvenient)
555
556
Thinking in C
www.ThinkingIn.!et
&o$Dect&2 &thi#&2 &$oo &2 &fa #e&2 &operator&2 &thro.&2 &$rea%&2 &fina y&2 &out&2 &true&2 &$yte&2 &fixed&2 &o*erride&2 &try&2 &ca#e&2 &f oat&2 ¶!#&2 &typeof&2 &catch&2 &for&2 &pri*ate&2 &uint&2 &char&2 &foreach&2 &protected&2 &u ong&2 &chec%ed&2 &goto&2 &pu$ ic&2 &unchec%ed&2 &c a##&2 &if&2 &readon y&2 &un#afe&2 &con#t&2 &i!p icit&2 &ref&2 &u#hort&2 &continue&2 &in&2 &return&2 &u#ing&2 &deci!a &2 &int&2 &#$yte&2 &*irtua &2 &defau t&2 &interface&2 &#ea ed&2 &*o ati e&2 &de egate&2 &interna &2 &#hort&2 &*oid&2 &do&2 &i#&2 &#iMeof&2 &.hi e&2 &dou$ e&2 & oc%&2 &#tac%a oc&2 &e #e&2 & ong&2 &#tatic&2 &enu!&2 &na!e#pace&2 &#tring&2 &try&2 &catch&2 &fina y&2 &u#ing&2 &e #e&2 &#.itch&2 &pu$ ic&2 &#tatic&2 &*oid&2 &foreach&2 &if&2 &.hi e&2 &$oo &2 &$yte&2 &for&2 &get&2 &#et& <3 Strea!Reader fStrea!3 Regex $ oc%-refix3 Regex !ethod:ef3 CapSty e0#tring fCa!e1; fStrea! 9 ne. Strea!Reader0 ne. BufferedStrea!0 ne. Hi eStrea!0fCa!e2 Hi eGode.Open1113 /= !atche# Du#t6$efore6$rac%et identifier #tarting .ith o.erca#e =/ $ oc%-refix 9 ne. Regex0\&J^#K0YWidZJa6MKJ^.K=1J^#K=;&13 /= !atche# Du#t6$efore6$rac%et .ith argu!ent and identifier #tarting .ith o.erCa#e =/ !ethod:ef 9 i#t
55#
ne. Regex0 \&J^#K0YWidZJa6MKJ^.K=1^#=^00.=1^1J^#K=;&13 Sy#te!.Con#o e.VriteLine0 &Chec%ing fi e: & R fCa!e13 < *oid C o#e01; fStrea!.C o#e013 < *oid Chec%01; #tring ine 9 &&3 int Count 9 03 .hi e00 ine 9 fStrea!.ReadLine011 !9 nu CountRR3 if0Su#piciou#0 ine11; Sy#te!.Con#o e.VriteLine0 &;0<: ;"<&2 Count2 ine13 < < < $oo
1;
Su#piciou#0#tring ine1; if0GatchCotaey.ord0 ine2 $ oc%-refix1 99 true1; return true3 < if0GatchCotaey.ord0 ine2 !ethod:ef1 99 true1; return true3 < return fa #e3 GatchCotaey.ord0#tring ine2 Regex re1; if0re.5#Gatch0 ine11; Gatch ! 9 re.Gatch0 ine13 #tring identifier 9 !._roup#J&id&K.Na ue3 if0)rray.5ndexOf0%eyVord#2 identifier1 W 01; return true3 < <
< $oo
55&
Thinking in C
www.ThinkingIn.!et
return fa #e3 < < The .ain() generate# a li#t *9 all the C# 9ile# in the current direct*ry and 9*r each *ne create# a Cap#tyle in#tance, run# Cap#tyle6Chec(() and then Cap#tyle6Close()6 Each Cap#tyle in#tance c*ntain# a li#t *9 C# key!*rd# that are all*!ed t* 3e in l*!erca#e, a# !ell a# in#tance varia3le# that h*ld the t!* regular e;pre##i*n#, and a #tream*eader in#tance varia3le that read# the underlying 9ile) The Cap#tyle() c*n#truct*r *pen# the 9ile and c*n#truct# the t!* t!* regular e;pre##i*n#) The e;pre##i*n# !ill +atch na+e#pace#, cla## and inter9ace identi9ier#, pr*pertie#, and +eth*d na+e# that precede a TcT character Ghandling +ultiEline 3racketing c*nventi*n# i# an*ther e;erci#eKH) =dditi*nally, the e;pre##i*n# u#e grou" naming t* a##*ciate the !*rd that 3egin# !ith a l*!erca#e letter t* a rege; varia3le called id GI0YWidZJa6MKJ^.K=1J i# the relevant n*tati*nQ the parenthe#e# #peci9y the gr*up, the YWidZ #peci9ie# the na+eH) The Chec(() +eth*d g*e# thr*ugh the #tream*eader lineE3yEline, #eeing i9 #uspicious() return# trueQ i9 #*, that line i# *utput t* the C*n#*le) #uspicious() in turn call# .atch,otEeyword(), pa##ing in the #u#pect line and a re9erence t* *ne *9 the t!* in#tance *egex#) .atch,otEeyword() check# 9*r a +atchQ i9 there i# *ne it a##ign# the value *9 the *egex gr*up na+ed id t* the #tring identifier) -9 thi# #tring d*e# n*t appear in the array *9 C# key!*rd#, .atch,otEeyword() return# true, !hich cau#e# #uspicious t* return true t* Chec(()) -n additi*n t* n*t handling +ultiEline 3racketing, thi# pr*gra+ #*+eti+e# +ark# string# that c*ntain 9*r+atting 3racket# inc*rrectly) -9 y*u i+pr*ve the pr*gra+, plea#e dr*p the auth*r# a line at !!!)thinkingin)net)
'u##ar5
The ) ET -O #trea+ li3rary d*e# #ati#9y the 3a#ic reDuire+ent#1 y*u can per9*r+ reading and !riting !ith the c*n#*le, a 9ile, a 3l*ck *9 +e+*ry, *r even acr*## the -nternet Ga# y*u !ill #ee in Chapter #net!*rking#H)
55'
,ith inheritance, y*u can create ne! type# *9 input and *utput *34ect#) The -O li3rary 3ring# up +i;ed 9eeling#Q it d*e# the 4*3 and it u#e# the ?ec*rat*r pattern t* g**d e99ect) But i9 y*u d*nt already under#tand the ?ec*rat*r pattern, the de#ign i# n*nintuitive, #* there# e;tra *verhead in learning and teaching it) There are al#* #*+e p**r ch*ice# in na+ing and i+ple+entati*n i##ue#) H*!ever, *nce y*u do under#tand the 9unda+ental# *9 #tream# and the ?ec*rat*r pattern and 3egin u#ing the li3rary in #ituati*n# that reDuire it# 9le;i3ility, y*u can 3egin t* 3ene9it 9r*+ thi# de#ign, at !hich p*int it# c*#t in e;tra line# *9 c*de !ill n*t 3*ther y*u at all)
%&ercises
56(
Thinking in C
www.ThinkingIn.!et
561
C ir c le
S q u a re
T r ia n g le
Thi# i# a typical cla## hierarchy diagra+, !ith the 3a#e cla## at the t*p and the derived cla##e# gr*!ing d*!n!ard) The n*r+al g*al in *34ectE *riented pr*gra++ing i# 9*r the 3ulk *9 y*ur c*de t* +anipulate re9erence# t* the 3a#e type G#hape, in thi# ca#eH, #* i9 y*u decide t* e;tend the pr*gra+ 3y adding a ne! cla## G*homboid, derived 9r*+ #hape, 9*r e;a+pleH, the 3ulk *9 the c*de i# n*t a99ected) -n thi# e;a+ple, the dyna+ically 3*und +eth*d in the #hape inter9ace i# draw( ), #* the intent i# 9*r the client pr*gra++er t* call draw( ) thr*ugh a generic #hape re9erence) draw( ) i# *verridden in all *9 the derived cla##e#, and 3ecau#e it i# a dyna+ically 3*und +eth*d, the pr*per 3ehavi*r !ill *ccur
56)
even th*ugh it i# called thr*ugh a generic #hape re9erence) That# p*ly+*rphi#+) Thu#, y*u generally create a #peci9ic *34ect GCircle, #%uare, *r +riangleH, upca#t it t* a #hape G9*rgetting the #peci9ic type *9 the *34ectH, and u#e that an*ny+*u# #hape re9erence in the re#t *9 the pr*gra+) =# a 3rie9 revie! *9 p*ly+*rphi#+ and upca#ting, y*u +ight c*de the a3*ve e;a+ple a# 9*ll*!#1 //: c"2:Shape#.Da*a i!port Da*a.uti .=3 c a## Shape ; *oid dra.01 ; Sy#te!.out.print n0thi# R &.dra.01&13 < < c a## Circ e extend# Shape ; pu$ ic String toString01 ; return &Circ e&3 < < c a## S7uare extend# Shape ; pu$ ic String toString01 ; return &S7uare&3 < < c a## 'riang e extend# Shape ; pu$ ic String toString01 ; return &'riang e&3 < < pu$ ic c a## Shape# ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; Li#t # 9 ne. )rrayLi#t013 #.add0ne. Circ e0113 #.add0ne. S7uare0113 #.add0ne. 'riang e0113 5terator e 9 #.iterator013 .hi e0e.ha#Cext011 00Shape1e.next011.dra.013
563
< < ///:8 The 3a#e cla## c*ntain# a draw( ) +eth*d that indirectly u#e# to#tring( ) t* print an identi9ier 9*r the cla## 3y pa##ing this t* #ystem6out6println( )) -9 that 9uncti*n #ee# an *34ect, it aut*+atically call# the to#tring( ) +eth*d t* pr*duce a #tring repre#entati*n) Each *9 the derived cla##e# *verride# the to#tring( ) +eth*d G9r*+ ob)ectH #* that draw( ) end# up printing #*+ething di99erent in each ca#e) -n main( ), #peci9ic type# *9 #hape are created and then added t* a List) Thi# i# the p*int at !hich the upca#t *ccur# 3ecau#e the List h*ld# *nly ob)ect#) Since everything in "ava G!ith the e;cepti*n *9 pri+itive#H i# an ob)ect, a List can al#* h*ld #hape *34ect#) But during an upca#t t* ob)ect, it al#* l*#e# any #peci9ic in9*r+ati*n, including the 9act that the *34ect# are #hape#) T* the 'rrayList, they are 4u#t ob)ect#) =t the p*int y*u 9etch an ele+ent *ut *9 the List !ith next( ), thing# get a little 3u#y) Since the List h*ld# *nly ob)ect#, next( ) naturally pr*duce# an ob)ect reference) But !e kn*! it# really a #hape re9erence, and !e !ant t* #end #hape +e##age# t* that *34ect) S* a ca#t t* #hape i# nece##ary u#ing the traditi*nal I(#hape)J ca#t) Thi# i# the +*#t 3a#ic 9*r+ *9 RTT-, #ince in "ava all ca#t# are checked at runEti+e 9*r c*rrectne##) That# e;actly !hat RTT- +ean#1 at runEti+e, the type *9 an *34ect i# identi9ied) -n thi# ca#e, the RTT- ca#t i# *nly partial1 the ob)ect i# ca#t t* a #hape, and n*t all the !ay t* a Circle, #%uare, *r +riangle) That# 3ecau#e the *nly thing !e know at thi# p*int i# that the List i# 9ull *9 #hape#) =t c*+pileEti+e, thi# i# en9*rced *nly 3y y*ur *!n #el9Ei+p*#ed rule#, 3ut at runEti+e the ca#t en#ure# it) *! p*ly+*rphi#+ take# *ver and the e;act +eth*d that# called 9*r the #hape i# deter+ined 3y !hether the re9erence i# 9*r a Circle, #%uare, *r +riangle) =nd in general, thi# i# h*! it #h*uld 3eQ y*u !ant the 3ulk *9 y*ur c*de t* kn*! a# little a# p*##i3le a3*ut s"eci$ic type# *9 *34ect#, and t* 4u#t deal !ith the general repre#entati*n *9 a 9a+ily *9 *34ect# Gin thi# ca#e, #hapeH) =# a re#ult, y*ur c*de !ill 3e ea#ier t* !rite, read, and +aintain, and y*ur de#ign# !ill 3e ea#ier t* i+ple+ent, under#tand, and
564
Thinking in C
www.ThinkingIn.!et
change) S* p*ly+*rphi#+ i# the general g*al in *34ectE*riented pr*gra++ing) But !hat i9 y*u have a #pecial pr*gra++ing pr*3le+ that# ea#ie#t t* #*lve i9 y*u kn*! the e;act type *9 a generic re9erenceF 5*r e;a+ple, #upp*#e y*u !ant t* all*! y*ur u#er# t* highlight all the #hape# *9 any particular type 3y turning the+ purple) Thi# !ay, they can 9ind all the triangle# *n the #creen 3y highlighting the+) Or perhap# y*ur +eth*d need# t* Ir*tateJ a li#t *9 #hape#, 3ut it +ake# n* #en#e t* r*tate a circle #* y*ud like t* #kip *nly the circle *34ect#) Thi# i# !hat RTT- acc*+pli#he#1 y*u can a#k a #hape re9erence the e;act type that it# re9erring t*) ,ith RTT- y*u can #elect and i#*late #pecial ca#e#)
565
c a## Candy ; #tatic ; Sy#te!.out.print n0&Loading Candy&13 < < c a## _u! ; #tatic ; Sy#te!.out.print n0&Loading _u!&13 < < c a## Coo%ie ; #tatic ; Sy#te!.out.print n0&Loading Coo%ie&13 < < pu$ ic c a## S.eetShop ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; Sy#te!.out.print n0&in#ide !ain&13 ne. Candy013 Sy#te!.out.print n0&)fter creating Candy&13 try ; C a##.forCa!e0&_u!&13 < catch0C a##CotHound+xception e1 ; e.printStac%'race0Sy#te!.err13 < Sy#te!.out.print n0 &)fter C a##.forCa!e0^&_u!^&1&13 ne. Coo%ie013 Sy#te!.out.print n0&)fter creating Coo%ie&13 < < ///:8 Each *9 the cla##e# Candy, um, and Coo(ie have a static clau#e that i# e;ecuted a# the cla## i# l*aded 9*r the 9ir#t ti+e) -n9*r+ati*n !ill 3e printed t* tell y*u !hen l*ading *ccur# 9*r that cla##) -n main( ), the *34ect creati*n# are #pread *ut 3et!een print #tate+ent# t* help detect the ti+e *9 l*ading)
566
Thinking in C
www.ThinkingIn.!et
= particularly intere#ting line i#1 C a##.forCa!e0&_u!&13 Thi# +eth*d i# a static +e+3er *9 Class Gt* !hich all Class *34ect# 3el*ngH) = Class *34ect i# like any *ther *34ect and #* y*u can get and +anipulate a re9erence t* it) GThat# !hat the l*ader d*e#)H One *9 the !ay# t* get a re9erence t* the Class *34ect i# for,ame( ), !hich take# a #tring c*ntaining the te;tual na+e G!atch the #pelling and capitali7ati*nKH *9 the particular cla## y*u !ant a re9erence 9*r) -t return# a Class re9erence) The *utput *9 thi# pr*gra+ 9*r *ne "CA i#1 in#ide !ain Loading Candy )fter creating Candy Loading _u! )fter C a##.forCa!e0&_u!&1 Loading Coo%ie )fter creating Coo%ie :*u can #ee that each Class *34ect i# l*aded *nly !hen it# needed, and the static initiali7ati*n i# per9*r+ed up*n cla## l*ading)
Class literals
"ava pr*vide# a #ec*nd !ay t* pr*duce the re9erence t* the Class *34ect, u#ing a class literal) -n the a3*ve pr*gra+ thi# !*uld l**k like1 _u!.c a##3 !hich i# n*t *nly #i+pler, 3ut al#* #a9er #ince it# checked at c*+pileE ti+e) Becau#e it eli+inate# the +eth*d call, it# al#* +*re e99icient) Cla## literal# !*rk !ith regular cla##e# a# !ell a# inter9ace#, array#, and pri+itive type#) -n additi*n, there# a #tandard 9ield called +@!& that e;i#t# 9*r each *9 the pri+itive !rapper cla##e#) The +@!& 9ield pr*duce# a re9erence t* the Class *34ect 9*r the a##*ciated pri+itive type, #uch that1
56#
` is e%uivalent to ` boolean6class char6class byte6class short6class int6class long6class float6class double6class void6class Boolean6+@!& Character6+@!& Byte6+@!& #hort6+@!& Bnteger6+@!& Long6+@!& :loat6+@!& $ouble6+@!& Hoid6+@!&
Ay pre9erence i# t* u#e the I6classJ ver#i*n# i9 y*u can, #ince theyre +*re c*n#i#tent !ith regular cla##e#)
0.) The Class *34ect repre#enting the type *9 y*ur *34ect) The Class *34ect can 3e Dueried 9*r u#e9ul runEti+e in9*r+ati*n) -n C@@, the cla##ic ca#t I(#hape)J d*e# not per9*r+ RTT-) -t #i+ply tell# the c*+piler t* treat the *34ect a# the ne! type) -n "ava, !hich d*e# per9*r+ the type check, thi# ca#t i# *9ten called a Itype #a9e d*!nca#t)J The rea#*n 9*r the ter+ Id*!nca#tJ i# the hi#t*rical arrange+ent *9 the cla## hierarchy diagra+) -9 ca#ting a Circle t* a #hape i# an upca#t, then ca#ting a #hape t* a Circle i# a d*!nca#t) H*!ever, y*u kn*! a Circle i# al#* a #hape, and the c*+piler 9reely all*!# an upca#t a##ign+ent, 3ut y*u don:t kn*! that a #hape i# nece##arily a Circle, #* the c*+piler
56&
Thinking in C
www.ThinkingIn.!et
d*e#nt all*! y*u t* per9*r+ a d*!nca#t a##ign+ent !ith*ut u#ing an e;plicit ca#t) There# a third 9*r+ *9 RTT- in "ava) Thi# i# the key!*rd instanceof that tell# y*u i9 an *34ect i# an in#tance *9 a particular type) -t return# a boolean #* y*u u#e it in the 9*r+ *9 a Due#ti*n, like thi#1 if0x in#tanceof :og1 00:og1x1.$ar%013 The a3*ve if #tate+ent check# t* #ee i9 the *34ect x 3el*ng# t* the cla## $og 2e$ore ca#ting x t* a $og) -t# i+p*rtant t* u#e instanceof 3e9*re a d*!nca#t !hen y*u d*nt have *ther in9*r+ati*n that tell# y*u the type *9 the *34ectQ *ther!i#e y*ull end up !ith a ClassCast&xception) Ordinarily, y*u +ight 3e hunting 9*r *ne type Gtriangle# t* turn purple, 9*r e;a+pleH, 3ut y*u can ea#ily tally all *9 the *34ect# u#ing instanceof) Supp*#e y*u have a 9a+ily *9 !et cla##e#1 //: c"2:-et#.Da*a c a## -et ;< c a## :og extend# -et ;< c a## -ug extend# :og ;< c a## Cat extend# -et ;< c a## Rodent extend# -et ;< c a## _er$i extend# Rodent ;< c a## Ua!#ter extend# Rodent ;< c a## Counter ; int i3 < ///:8 The Counter cla## i# u#ed t* keep track *9 the nu+3er *9 any particular type *9 !et) :*u c*uld think *9 it a# an Bnteger that can 3e +*di9ied) U#ing instanceof, all the pet# can 3e c*unted1 //: c"2:-etCount.Da*a // O#ing in#tanceof. i!port Da*a.uti .=3 pu$ ic c a## -etCount ; #tatic StringJK typena!e# 9 ; &-et&2 &:og&2 &-ug&2 &Cat&2
56'
&Rodent&2 &_er$i &2 &Ua!#ter&2 <3 // +xception# thro.n out to con#o e: pu$ ic #tatic *oid !ain0StringJK arg#1 thro.# +xception ; )rrayLi#t pet# 9 ne. )rrayLi#t013 try ; C a##JK pet'ype# 9 ; C a##.forCa!e0&:og&12 C a##.forCa!e0&-ug&12 C a##.forCa!e0&Cat&12 C a##.forCa!e0&Rodent&12 C a##.forCa!e0&_er$i &12 C a##.forCa!e0&Ua!#ter&12 <3 for0int i 9 03 i W "P3 iRR1 pet#.add0 pet'ype#J 0int10Gath.rando!01=pet'ype#. ength1K .ne.5n#tance0113 < catch05n#tantiation+xception e1 ; Sy#te!.err.print n0&Cannot in#tantiate&13 thro. e3 < catch05 ega )cce##+xception e1 ; Sy#te!.err.print n0&Cannot acce##&13 thro. e3 < catch0C a##CotHound+xception e1 ; Sy#te!.err.print n0&Cannot find c a##&13 thro. e3 < Ua#hGap h 9 ne. Ua#hGap013 for0int i 9 03 i W typena!e#. ength3 iRR1 h.put0typena!e#JiK2 ne. Counter0113 for0int i 9 03 i W pet#.#iMe013 iRR1 ; O$Dect o 9 pet#.get0i13 if0o in#tanceof -et1 00Counter1h.get0&-et&11.iRR3 if0o in#tanceof :og1 00Counter1h.get0&:og&11.iRR3 if0o in#tanceof -ug1 00Counter1h.get0&-ug&11.iRR3
5#(
Thinking in C
www.ThinkingIn.!et
if0o in#tanceof Cat1 00Counter1h.get0&Cat&11.iRR3 if0o in#tanceof Rodent1 00Counter1h.get0&Rodent&11.iRR3 if0o in#tanceof _er$i 1 00Counter1h.get0&_er$i &11.iRR3 if0o in#tanceof Ua!#ter1 00Counter1h.get0&Ua!#ter&11.iRR3 < for0int i 9 03 i W pet#.#iMe013 iRR1 Sy#te!.out.print n0pet#.get0i1.getC a##0113 for0int i 9 03 i W typena!e#. ength3 iRR1 Sy#te!.out.print n0 typena!e#JiK R & 7uantity: & R 00Counter1h.get0typena!e#JiK11.i13 < < ///:8 There# a rather narr*! re#tricti*n *n instanceof1 y*u can c*+pare it t* a na+ed type *nly, and n*t t* a Class *34ect) -n the e;a+ple a3*ve y*u +ight 9eel that it# tedi*u# t* !rite *ut all *9 th*#e instanceof e;pre##i*n#, and y*ure right) But there i# n* !ay t* cleverly aut*+ate instanceof 3y creating an 'rrayList *9 Class *34ect# and c*+paring it t* th*#e in#tead G#tay tunedRy*ull #ee an alternativeH) Thi# i#nt a# great a re#tricti*n a# y*u +ight think, 3ecau#e y*ull eventually under#tand that y*ur de#ign i# pr*3a3ly 9la!ed i9 y*u end up !riting a l*t *9 instanceof e;pre##i*n#) O9 c*ur#e thi# e;a+ple i# c*ntrivedRy*ud pr*3a3ly put a static data +e+3er in each type and incre+ent it in the c*n#truct*r t* keep track *9 the c*unt#) :*u !*uld d* #*+ething like that i$ y*u had c*ntr*l *9 the #*urce c*de 9*r the cla## and c*uld change it) Since thi# i# n*t al!ay# the ca#e, RTT- can c*+e in handy)
5#1
i!port Da*a.uti .=3 pu$ ic c a## -etCount2 ; pu$ ic #tatic *oid !ain0StringJK arg#1 thro.# +xception ; )rrayLi#t pet# 9 ne. )rrayLi#t013 C a##JK pet'ype# 9 ; // C a## itera #: -et.c a##2 :og.c a##2 -ug.c a##2 Cat.c a##2 Rodent.c a##2 _er$i .c a##2 Ua!#ter.c a##2 <3 try ; for0int i 9 03 i W "P3 iRR1 ; // Off#et $y one to e i!inate -et.c a##: int rnd 9 " R 0int10 Gath.rando!01 = 0pet'ype#. ength 6 "113 pet#.add0 pet'ype#JrndK.ne.5n#tance0113 < < catch05n#tantiation+xception e1 ; Sy#te!.err.print n0&Cannot in#tantiate&13 thro. e3 < catch05 ega )cce##+xception e1 ; Sy#te!.err.print n0&Cannot acce##&13 thro. e3 < Ua#hGap h 9 ne. Ua#hGap013 for0int i 9 03 i W pet'ype#. ength3 iRR1 h.put0pet'ype#JiK.toString012 ne. Counter0113 for0int i 9 03 i W pet#.#iMe013 iRR1 ; O$Dect o 9 pet#.get0i13 if0o in#tanceof -et1 00Counter1h.get0&c a## -et&11.iRR3 if0o in#tanceof :og1 00Counter1h.get0&c a## :og&11.iRR3
5#)
Thinking in C
www.ThinkingIn.!et
if0o in#tanceof -ug1 00Counter1h.get0&c a## if0o in#tanceof Cat1 00Counter1h.get0&c a## if0o in#tanceof Rodent1 00Counter1h.get0&c a## if0o in#tanceof _er$i 1 00Counter1h.get0&c a## if0o in#tanceof Ua!#ter1 00Counter1h.get0&c a##
< for0int i 9 03 i W pet#.#iMe013 iRR1 Sy#te!.out.print n0pet#.get0i1.getC a##0113 5terator %ey# 9 h.%eySet01.iterator013 .hi e0%ey#.ha#Cext011 ; String n! 9 0String1%ey#.next013 Counter cnt 9 0Counter1h.get0n!13 Sy#te!.out.print n0 n!.#u$#tring0n!. a#t5ndexOf0'.'1 R "1 R & 7uantity: & R cnt.i13 < < < ///:8 Here, the typenames array ha# 3een re+*ved in 9av*r *9 getting the type na+e #tring# 9r*+ the Class *34ect) *tice that the #y#te+ can di#tingui#h 3et!een cla##e# and inter9ace#) :*u can al#* #ee that the creati*n *9 pet+ypes d*e# n*t need t* 3e #urr*unded 3y a try 3l*ck #ince it# evaluated at c*+pileEti+e and thu# !*nt thr*! any e;cepti*n#, unlike Class6for,ame( )) ,hen the !et *34ect# are dyna+ically created, y*u can #ee that the rand*+ nu+3er i# re#tricted #* it i# 3et!een *ne and pet+ypes6length and d*e# n*t include 7er*) That# 3ecau#e 7er* re9er# t* !et6class, and pre#u+a3ly a generic !et *34ect i# n*t intere#ting) H*!ever, #ince !et6class i# part *9 pet+ypes the re#ult i# that all *9 the pet# get c*unted)
5#3
) d5na#ic instanceof
The Class isBnstance +eth*d pr*vide# a !ay t* dyna+ically call the instanceof *perat*r) Thu#, all th*#e tedi*u# instanceof #tate+ent# can 3e re+*ved in the !etCount e;a+ple1 //: c"2:-etCountT.Da*a // O#ing i#5n#tance01. i!port Da*a.uti .=3 pu$ ic c a## -etCountT ; pu$ ic #tatic *oid !ain0StringJK arg#1 thro.# +xception ; )rrayLi#t pet# 9 ne. )rrayLi#t013 C a##JK pet'ype# 9 ; -et.c a##2 :og.c a##2 -ug.c a##2 Cat.c a##2 Rodent.c a##2 _er$i .c a##2 Ua!#ter.c a##2 <3 try ; for0int i 9 03 i W "P3 iRR1 ; // Off#et $y one to e i!inate -et.c a##: int rnd 9 " R 0int10 Gath.rando!01 = 0pet'ype#. ength 6 "113 pet#.add0 pet'ype#JrndK.ne.5n#tance0113 < < catch05n#tantiation+xception e1 ; Sy#te!.err.print n0&Cannot in#tantiate&13 thro. e3 < catch05 ega )cce##+xception e1 ; Sy#te!.err.print n0&Cannot acce##&13 thro. e3 < Ua#hGap h 9 ne. Ua#hGap013 for0int i 9 03 i W pet'ype#. ength3 iRR1 h.put0pet'ype#JiK.toString012
5#4
Thinking in C
www.ThinkingIn.!et
ne. Counter0113 for0int i 9 03 i W pet#.#iMe013 iRR1 ; O$Dect o 9 pet#.get0i13 // O#ing i#5n#tance to e i!inate indi*idua // in#tanceof expre##ion#: for 0int D 9 03 D W pet'ype#. ength3 RRD1 if 0pet'ype#JDK.i#5n#tance0o11 ; String %ey 9 pet'ype#JDK.toString013 00Counter1h.get0%ey11.iRR3 < < for0int i 9 03 i W pet#.#iMe013 iRR1 Sy#te!.out.print n0pet#.get0i1.getC a##0113 5terator %ey# 9 h.%eySet01.iterator013 .hi e0%ey#.ha#Cext011 ; String n! 9 0String1%ey#.next013 Counter cnt 9 0Counter1h.get0n!13 Sy#te!.out.print n0 n!.#u$#tring0n!. a#t5ndexOf0'.'1 R "1 R & 7uantity: & R cnt.i13 < < < ///:8 :*u can #ee that the isBnstance( ) +eth*d ha# eli+inated the need 9*r the instanceof e;pre##i*n#) -n additi*n, thi# +ean# that y*u can add ne! type# *9 pet# #i+ply 3y changing the pet+ypes arrayQ the re#t *9 the pr*gra+ d*e# n*t need +*di9icati*n Ga# it did !hen u#ing the instanceof e;pre##i*n#H)
5#5
c a## Ba#e ;< c a## :eri*ed extend# Ba#e ;< pu$ ic c a## Ha!i yN#+xact'ype ; #tatic *oid te#t0O$Dect x1 ; Sy#te!.out.print n0&'e#ting x of type & R x.getC a##0113 Sy#te!.out.print n0&x in#tanceof Ba#e & R 0x in#tanceof Ba#e113 Sy#te!.out.print n0&x in#tanceof :eri*ed & R 0x in#tanceof :eri*ed113 Sy#te!.out.print n0&Ba#e.i#5n#tance0x1 & R Ba#e.c a##.i#5n#tance0x113 Sy#te!.out.print n0&:eri*ed.i#5n#tance0x1 & R :eri*ed.c a##.i#5n#tance0x113 Sy#te!.out.print n0 &x.getC a##01 99 Ba#e.c a## & R 0x.getC a##01 99 Ba#e.c a##113 Sy#te!.out.print n0 &x.getC a##01 99 :eri*ed.c a## & R 0x.getC a##01 99 :eri*ed.c a##113 Sy#te!.out.print n0 &x.getC a##01.e7ua #0Ba#e.c a##11 & R 0x.getC a##01.e7ua #0Ba#e.c a##1113 Sy#te!.out.print n0 &x.getC a##01.e7ua #0:eri*ed.c a##11 & R 0x.getC a##01.e7ua #0:eri*ed.c a##1113 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; te#t0ne. Ba#e0113 te#t0ne. :eri*ed0113 < < ///:8 The test( ) +eth*d per9*r+# type checking !ith it# argu+ent u#ing 3*th 9*r+# *9 instanceof) -t then get# the Class re9erence and u#e# II and e%uals( ) t* te#t 9*r eDuality *9 the Class *34ect#) Here i# the *utput1 'e#ting x of type c a## Ba#e x in#tanceof Ba#e true x in#tanceof :eri*ed fa #e Ba#e.i#5n#tance0x1 true
5#6
Thinking in C
www.ThinkingIn.!et
:eri*ed.i#5n#tance0x1 fa #e x.getC a##01 99 Ba#e.c a## true x.getC a##01 99 :eri*ed.c a## fa #e x.getC a##01.e7ua #0Ba#e.c a##11 true x.getC a##01.e7ua #0:eri*ed.c a##11 fa #e 'e#ting x of type c a## :eri*ed x in#tanceof Ba#e true x in#tanceof :eri*ed true Ba#e.i#5n#tance0x1 true :eri*ed.i#5n#tance0x1 true x.getC a##01 99 Ba#e.c a## fa #e x.getC a##01 99 :eri*ed.c a## true x.getC a##01.e7ua #0Ba#e.c a##11 fa #e x.getC a##01.e7ua #0:eri*ed.c a##11 true Rea##uringly, instanceof and isBnstance( ) pr*duce e;actly the #a+e re#ult#, a# d* e%uals( ) and II) But the te#t# the+#elve# dra! di99erent c*nclu#i*n#) -n keeping !ith the c*ncept *9 type, instanceof #ay# Iare y*u thi# cla##, *r a cla## derived 9r*+ thi# cla##FJ On the *ther hand, i9 y*u c*+pare the actual Class *34ect# u#ing II, there i# n* c*ncern !ith inheritanceRit# either the e;act type *r it i#nt)
6--I s5nta&
"ava per9*r+# it# RTT- u#ing the Class *34ect, even i9 y*ure d*ing #*+ething like a ca#t) The cla## Class al#* ha# a nu+3er *9 *ther !ay# y*u can u#e RTT-) 5ir#t, y*u +u#t get a re9erence t* the appr*priate Class *34ect) One !ay t* d* thi#, a# #h*!n in the previ*u# e;a+ple, i# t* u#e a #tring and the Class6for,ame( ) +eth*d) Thi# i# c*nvenient 3ecau#e y*u d*nt need an *34ect *9 that type in *rder t* get the Class re9erence) H*!ever, i9 y*u d* already have an *34ect *9 the type y*ure intere#ted in, y*u can 9etch the Class re9erence 3y calling a +eth*d that# part *9 the ob)ect r**t cla##1 getClass( )) Thi# return# the Class re9erence repre#enting the actual type *9 the *34ect) Class ha# +any intere#ting +eth*d#, de+*n#trated in the 9*ll*!ing e;a+ple1 //: c"2:'oy'e#t.Da*a // 'e#ting c a## C a##.
5##
interface Ua#Batterie# ;< interface Vaterproof ;< interface Shoot#'hing# ;< c a## 'oy ; // Co!!ent out the fo o.ing defau t // con#tructor to #ee // CoSuchGethod+rror fro! 0="=1 'oy01 ;< 'oy0int i1 ;< < c a## Hancy'oy extend# 'oy i!p e!ent# Ua#Batterie#2 Vaterproof2 Shoot#'hing# ; Hancy'oy01 ; #uper0"13 < < pu$ ic c a## 'oy'e#t ; pu$ ic #tatic *oid !ain0StringJK arg#1 thro.# +xception ; C a## c 9 nu 3 try ; c 9 C a##.forCa!e0&Hancy'oy&13 < catch0C a##CotHound+xception e1 ; Sy#te!.err.print n0&Can't find Hancy'oy&13 thro. e3 < print5nfo0c13 C a##JK face# 9 c.get5nterface#013 for0int i 9 03 i W face#. ength3 iRR1 print5nfo0face#JiK13 C a## cy 9 c.getSuperc a##013 O$Dect o 9 nu 3 try ; // Re7uire# defau t con#tructor: o 9 cy.ne.5n#tance013 // 0="=1 < catch05n#tantiation+xception e1 ; Sy#te!.err.print n0&Cannot in#tantiate&13 thro. e3 < catch05 ega )cce##+xception e1 ;
5#&
Thinking in C
www.ThinkingIn.!et
Sy#te!.err.print n0&Cannot acce##&13 thro. e3 < print5nfo0o.getC a##0113 < #tatic *oid print5nfo0C a## cc1 ; Sy#te!.out.print n0 &C a## na!e: & R cc.getCa!e01 R & i# interfaceY J& R cc.i#5nterface01 R &K&13 < < ///:8 :*u can #ee that class :ancy+oy i# Duite c*+plicated, #ince it inherit# 9r*+ +oy and implements the interface# *9 "asBatteries, =aterproof, and #hoots+hings) -n main( ), a Class re9erence i# created and initiali7ed t* the :ancy+oy Class u#ing for,ame( ) in#ide an appr*priate try 3l*ck) The Class6getBnterfaces( ) +eth*d return# an array *9 Class *34ect# repre#enting the inter9ace# that are c*ntained in the Class *34ect *9 intere#t) -9 y*u have a Class *34ect y*u can al#* a#k it 9*r it# direct 3a#e cla## u#ing get#uperclass( )) Thi#, *9 c*ur#e, return# a Class re9erence that y*u can 9urther Duery) Thi# +ean# that, at runEti+e, y*u can di#c*ver an *34ect# entire cla## hierarchy) The newBnstance( ) +eth*d *9 Class can, at 9ir#t, #ee+ like 4u#t an*ther !ay t* clone( ) an *34ect) H*!ever, y*u can create a ne! *34ect !ith newBnstance( ) without an e;i#ting *34ect, a# #een here, 3ecau#e there i# n* +oy *34ectR*nly cy, !hich i# a re9erence t* y# Class *34ect) Thi# i# a !ay t* i+ple+ent a Ivirtual c*n#truct*r,J !hich all*!# y*u t* #ay Id*nt kn*! e;actly !hat type y*u are, 3ut create y*ur#el9 pr*perly any!ay)J -n the e;a+ple a3*ve, cy i# 4u#t a Class re9erence !ith n* 9urther type in9*r+ati*n kn*!n at c*+pileEti+e) =nd !hen y*u create a ne! in#tance, y*u get 3ack an ob)ect reference) But that re9erence i# p*inting t* a +oy *34ect) O9 c*ur#e, 3e9*re y*u can #end any +e##age# *ther than th*#e accepted 3y ob)ect, y*u have t* inve#tigate it a 3it and d* #*+e ca#ting) -n additi*n, the cla## that# 3eing created !ith
5#'
newBnstance( ) +u#t have a de9ault c*n#truct*r) -n the ne;t #ecti*n, y*ull #ee h*! t* dyna+ically create *34ect# *9 cla##e# u#ing any c*n#truct*r, !ith the "ava re$lection =P-) The 9inal +eth*d in the li#ting i# printBnfo( ), !hich take# a Class re9erence and get# it# na+e !ith get,ame( ), and 9ind# *ut !hether it# an inter9ace !ith isBnterface( )) The *utput 9r*+ thi# pr*gra+ i#1 C C C C C a## a## a## a## a## na!e: na!e: na!e: na!e: na!e: Hancy'oy i# interfaceY Jfa #eK Ua#Batterie# i# interfaceY JtrueK Vaterproof i# interfaceY JtrueK Shoot#'hing# i# interfaceY JtrueK 'oy i# interfaceY Jfa #eK
Thu#, !ith the Class *34ect y*u can 9ind *ut 4u#t a3*ut everything y*u !ant t* kn*! a3*ut an *34ect)
5&(
Thinking in C
www.ThinkingIn.!et
pr*gra++ing, in !hich y*u 3uild pr*4ect# u#ing ?a"id 5""lication Ce-elo"ment GR=?H in an applicati*n 3uilder t**l) Thi# i# a vi#ual appr*ach t* creating a pr*gra+ G!hich y*u #ee *n the #creen a# a I9*r+JH 3y +*ving ic*n# that repre#ent c*+p*nent# *nt* the 9*r+) The#e c*+p*nent# are then c*n9igured 3y #etting #*+e *9 their value# at pr*gra+ ti+e) Thi# de#ignEti+e c*n9igurati*n reDuire# that any c*+p*nent 3e in#tantia3le, that it e;p*#e# part# *9 it#el9, and that it all*!# it# value# t* 3e read and #et) -n additi*n, c*+p*nent# that handle >Uevent# +u#t e;p*#e in9*r+ati*n a3*ut appr*priate +eth*d# #* that the R=? envir*n+ent can a##i#t the pr*gra++er in *verriding the#e eventE handling +eth*d#) Re9lecti*n pr*vide# the +echani#+ t* detect the availa3le +eth*d# and pr*duce the +eth*d na+e#) "ava pr*vide# a #tructure 9*r c*+p*nentE3a#ed pr*gra++ing thr*ugh "avaBean# Gde#cri3ed in Chapter 0/H) =n*ther c*+pelling +*tivati*n 9*r di#c*vering cla## in9*r+ati*n at runE ti+e i# t* pr*vide the a3ility t* create and e;ecute *34ect# *n re+*te plat9*r+# acr*## a net!*rk) Thi# i# called ?emote .ethod In-ocation GRA-H and it all*!# a "ava pr*gra+ t* have *34ect# di#tri3uted acr*## +any +achine#) Thi# di#tri3uti*n can happen 9*r a nu+3er *9 rea#*n#1 9*r e;a+ple, perhap# y*ure d*ing a c*+putati*nEinten#ive ta#k and y*u !ant t* 3reak it up and put piece# *n +achine# that are idle in *rder t* #peed thing# up) -n #*+e #ituati*n# y*u +ight !ant t* place c*de that handle# particular type# *9 ta#k# Ge)g), IBu#ine## Rule#J in a +ultitier client<#erver architectureH *n a particular +achine, #* that +achine 3ec*+e# a c*++*n rep*#it*ry de#cri3ing th*#e acti*n# and it can 3e ea#ily changed t* a99ect every*ne in the #y#te+) GThi# i# an intere#ting devel*p+ent, #ince the +achine e;i#t# #*lely t* +ake #*9t!are change# ea#yKH =l*ng the#e line#, di#tri3uted c*+puting al#* #upp*rt# #peciali7ed hard!are that +ight 3e g**d at a particular ta#kR+atri; inver#i*n#, 9*r e;a+pleR3ut inappr*priate *r t** e;pen#ive 9*r general purp*#e pr*gra++ing) The cla## Class Gde#cri3ed previ*u#ly in thi# chapterH #upp*rt# the c*ncept *9 re$lection, and there# an additi*nal li3rary, )ava6lang6reflect, !ith cla##e# :ield, .ethod, and Constructor Geach *9 !hich i+ple+ent the .ember interfaceH) O34ect# *9 the#e type# are created 3y the "CA at runEti+e t* repre#ent the c*rre#p*nding +e+3er in the unkn*!n cla##) :*u can then u#e the Constructor# t*
5&1
create ne! *34ect#, the get( ) and set( ) +eth*d# t* read and +*di9y the 9ield# a##*ciated !ith :ield *34ect#, and the invo(e( ) +eth*d t* call a +eth*d a##*ciated !ith a .ethod *34ect) -n additi*n, y*u can call the c*nvenience +eth*d# get:ields( ), get.ethods( ), getConstructors( ), etc), t* return array# *9 the *34ect# repre#enting the 9ield#, +eth*d#, and c*n#truct*r#) G:*u can 9ind *ut +*re 3y l**king up the cla## Class in y*ur *nline d*cu+entati*n)H Thu#, the cla## in9*r+ati*n 9*r an*ny+*u# *34ect# can 3e c*+pletely deter+ined at runE ti+e, and n*thing need 3e kn*!n at c*+pileEti+e) -t# i+p*rtant t* reali7e that there# n*thing +agic a3*ut re9lecti*n) ,hen y*ure u#ing re9lecti*n t* interact !ith an *34ect *9 an unkn*!n type, the "CA !ill #i+ply l**k at the *34ect and #ee that it 3el*ng# t* a particular cla## G4u#t like *rdinary RTT-H 3ut then, 3e9*re it can d* anything el#e, the Class *34ect +u#t 3e l*aded) Thu#, the 6class 9ile 9*r that particular type +u#t #till 3e availa3le t* the "CA, either *n the l*cal +achine *r acr*## the net!*rk) S* the true di99erence 3et!een RTT- and re9lecti*n i# that !ith RTT-, the c*+piler *pen# and e;a+ine# the 6class 9ile at c*+pileE ti+e) Put an*ther !ay, y*u can call all the +eth*d# *9 an *34ect in the In*r+alJ !ay) ,ith re9lecti*n, the 6class 9ile i# unavaila3le at c*+pileE ti+eQ it i# *pened and e;a+ined 3y the runEti+e envir*n+ent)
5&)
Thinking in C
www.ThinkingIn.!et
//: c"2:Sho.Gethod#.Da*a // O#ing ref ection to #ho. a the !ethod# of // a c a##2 e*en if the !ethod# are defined in // the $a#e c a##. i!port Da*a. ang.ref ect.=3 pu$ ic c a## Sho.Gethod# ; #tatic fina String u#age 9 &u#age: ^n& R &Sho.Gethod# 7ua ified.c a##.na!e^n& R &'o #ho. a !ethod# in c a## or: ^n& R &Sho.Gethod# 7ua ified.c a##.na!e .ord^n& R &'o #earch for !ethod# in*o *ing '.ord'&3 pu$ ic #tatic *oid !ain0StringJK arg#1 ; if0arg#. ength W "1 ; Sy#te!.out.print n0u#age13 Sy#te!.exit0013 < try ; C a## c 9 C a##.forCa!e0arg#J0K13 GethodJK ! 9 c.getGethod#013 Con#tructorJK ctor 9 c.getCon#tructor#013 if0arg#. ength 99 "1 ; for 0int i 9 03 i W !. ength3 iRR1 Sy#te!.out.print n0!JiK13 for 0int i 9 03 i W ctor. ength3 iRR1 Sy#te!.out.print n0ctorJiK13 < e #e ; for 0int i 9 03 i W !. ength3 iRR1 if0!JiK.toString01 .indexOf0arg#J"K1!9 6"1 Sy#te!.out.print n0!JiK13 for 0int i 9 03 i W ctor. ength3 iRR1 if0ctorJiK.toString01 .indexOf0arg#J"K1!9 6"1 Sy#te!.out.print n0ctorJiK13 < < catch0C a##CotHound+xception e1 ; Sy#te!.err.print n0&Co #uch c a##: & R e13 < <
5&3
< ///:8 The Class +eth*d# get.ethods( ) and getConstructors( ) return an array *9 .ethod and Constructor, re#pectively) Each *9 the#e cla##e# ha# 9urther +eth*d# t* di##ect the na+e#, argu+ent#, and return value# *9 the +eth*d# they repre#ent) But y*u can al#* 4u#t u#e to#tring( ), a# i# d*ne here, t* pr*duce a #tring !ith the entire +eth*d #ignature) The re#t *9 the c*de i# 4u#t 9*r e;tracting c*++and line in9*r+ati*n, deter+ining i9 a particular #ignature +atche# !ith y*ur target #tring Gu#ing index1f( )H, and printing the re#ult#) Thi# #h*!# re9lecti*n in acti*n, #ince the re#ult pr*duced 3y Class6for,ame( ) cann*t 3e kn*!n at c*+pileEti+e, and there9*re all the +eth*d #ignature in9*r+ati*n i# 3eing e;tracted at runEti+e) -9 y*u inve#tigate y*ur *nline d*cu+entati*n *n re9lecti*n, y*ull #ee that there i# en*ugh #upp*rt t* actually #et up and +ake a +eth*d call *n an *34ect that# t*tally unkn*!n at c*+pileEti+e Gthere !ill 3e e;a+ple# *9 thi# later in thi# 3**kH) =gain, thi# i# #*+ething y*u +ay never need t* d* y*ur#el9Rthe #upp*rt i# there 9*r RA- and #* a pr*gra++ing envir*n+ent can +anipulate "avaBean#R3ut it# intere#ting) =n enlightening e;peri+ent i# t* run Da*a Sho.Gethod# Sho.Gethod# Thi# pr*duce# a li#ting that include# a public de9ault c*n#truct*r, even th*ugh y*u can #ee 9r*+ the c*de that n* c*n#truct*r !a# de9ined) The c*n#truct*r y*u #ee i# the *ne that# aut*+atically #ynthe#i7ed 3y the c*+piler) -9 y*u then +ake #how.ethods a n*nEpublic cla## Gthat i#, 9riendlyH, the #ynthe#i7ed de9ault c*n#truct*r n* l*nger #h*!# up in the *utput) The #ynthe#i7ed de9ault c*n#truct*r i# aut*+atically given the #a+e acce## a# the cla##) The *utput 9*r #how.ethods i# #till a little tedi*u#) 5*r e;a+ple, here# a p*rti*n *9 the *utput pr*duced 3y inv*king )ava #how.ethods )ava6lang6#tring1 pu$ ic $oo ean Da*a. ang.String.#tart#Vith0Da*a. ang.String2int1 pu$ ic $oo ean Da*a. ang.String.#tart#Vith0Da*a. ang.String1
5&4
Thinking in C
www.ThinkingIn.!et
pu$ ic $oo ean Da*a. ang.String.end#Vith0Da*a. ang.String1 -t !*uld 3e even nicer i9 the Duali9ier# like )ava6lang c*uld 3e #tripped *99) The #tream+o(eniTer cla## intr*duced in the previ*u# chapter can help create a t**l t* #*lve thi# pr*3le+1 //: co!:$ruceec%e :uti :StripQua ifier#.Da*a pac%age co!.$ruceec%e .uti 3 i!port Da*a.io.=3 pu$ ic c a## StripQua ifier# ; pri*ate Strea!'o%eniMer #t3 pu$ ic StripQua ifier#0String 7ua ified1 ; #t 9 ne. Strea!'o%eniMer0 ne. StringReader07ua ified113 #t.ordinaryChar0' '13 // aeep the #pace# < pu$ ic String getCext01 ; String # 9 nu 3 try ; int to%en 9 #t.next'o%en013 if0to%en !9 Strea!'o%eniMer.''X+OH1 ; #.itch0#t.ttype1 ; ca#e Strea!'o%eniMer.''X+OL: # 9 nu 3 $rea%3 ca#e Strea!'o%eniMer.''XCOGB+R: # 9 :ou$ e.toString0#t.n*a 13 $rea%3 ca#e Strea!'o%eniMer.''XVOR:: # 9 ne. String0#t.#*a 13 $rea%3 defau t: // #ing e character in ttype # 9 String.*a ueOf00char1#t.ttype13 < < < catch05O+xception e1 ; Sy#te!.err.print n0&+rror fetching to%en&13 < return #3
5&5
< pu$ ic #tatic String #trip0String 7ua ified1 ; StripQua ifier# #7 9 ne. StripQua ifier#07ua ified13 String # 9 &&2 #i3 .hi e00#i 9 #7.getCext011 !9 nu 1 ; int a#t:ot 9 #i. a#t5ndexOf0'.'13 if0 a#t:ot !9 6"1 #i 9 #i.#u$#tring0 a#t:ot R "13 # R9 #i3 < return #3 < < ///:8 T* 9acilitate reu#e, thi# cla## i# placed in com6bruceec(el6util) =# y*u can #ee, thi# u#e# the #tream+o(eniTer and #tring +anipulati*n t* d* it# !*rk) The ne! ver#i*n *9 the pr*gra+ u#e# the a3*ve cla## t* clean up the *utput1 //: c"2:Sho.Gethod#C ean.Da*a // Sho.Gethod# .ith the 7ua ifier# #tripped // to !a%e the re#u t# ea#ier to read. i!port Da*a. ang.ref ect.=3 i!port co!.$ruceec%e .uti .=3 pu$ ic c a## Sho.Gethod#C ean ; #tatic fina String u#age 9 &u#age: ^n& R &Sho.Gethod#C ean 7ua ified.c a##.na!e^n& R &'o #ho. a !ethod# in c a## or: ^n& R &Sho.Gethod#C ean 7ua if.c a##.na!e .ord^n& R &'o #earch for !ethod# in*o *ing '.ord'&3 pu$ ic #tatic *oid !ain0StringJK arg#1 ; if0arg#. ength W "1 ; Sy#te!.out.print n0u#age13 Sy#te!.exit0013 < try ; C a## c 9 C a##.forCa!e0arg#J0K13
5&6
Thinking in C
www.ThinkingIn.!et
GethodJK ! 9 c.getGethod#013 Con#tructorJK ctor 9 c.getCon#tructor#013 // Con*ert to an array of c eaned String#: StringJK n 9 ne. StringJ!. ength R ctor. engthK3 for0int i 9 03 i W !. ength3 iRR1 ; String # 9 !JiK.toString013 nJiK 9 StripQua ifier#.#trip0#13 < for0int i 9 03 i W ctor. ength3 iRR1 ; String # 9 ctorJiK.toString013 nJi R !. engthK 9 StripQua ifier#.#trip0#13 < if0arg#. ength 99 "1 for 0int i 9 03 i W n. ength3 iRR1 Sy#te!.out.print n0nJiK13 e #e for 0int i 9 03 i W n. ength3 iRR1 if0nJiK.indexOf0arg#J"K1!9 6"1 Sy#te!.out.print n0nJiK13 < catch0C a##CotHound+xception e1 ; Sy#te!.err.print n0&Co #uch c a##: & R e13 < < < ///:8 The cla## #how.ethodsClean i# Duite #i+ilar t* the previ*u# #how.ethods, e;cept that it take# the array# *9 .ethod and Constructor and c*nvert# the+ int* a #ingle array *9 #tring) Each *9 the#e #tring *34ect# i# then pa##ed thr*ugh #trip_ualifiers6#trip( ) t* re+*ve all the +eth*d Duali9icati*n) Thi# t**l can 3e a real ti+eE#aver !hile y*ure pr*gra++ing, !hen y*u cant re+e+3er i9 a cla## ha# a particular +eth*d and y*u d*nt !ant t* g* !alking thr*ugh the cla## hierarchy in the *nline d*cu+entati*n, *r i9 y*u d*nt kn*! !hether that cla## can d* anything !ith, 9*r e;a+ple, Color *34ect#)
5&#
Chapter 0/ c*ntain# a >U- ver#i*n *9 thi# pr*gra+ Gcu#t*+i7ed t* e;tract in9*r+ati*n 9*r S!ing c*+p*nent#H #* y*u can leave it running !hile y*ure !riting c*de, t* all*! Duick l**kup#)
'u##ar5
RTT- all*!# y*u t* di#c*ver type in9*r+ati*n 9r*+ an an*ny+*u# 3a#eE cla## re9erence) Thu#, it# ripe 9*r +i#u#e 3y the n*vice #ince it +ight +ake #en#e 3e9*re p*ly+*rphic +eth*d call# d*) 5*r +any pe*ple c*+ing 9r*+ a pr*cedural 3ackgr*und, it# di99icult n*t t* *rgani7e their pr*gra+# int* #et# *9 switch #tate+ent#) They c*uld acc*+pli#h thi# !ith RTT- and thu# l*#e the i+p*rtant value *9 p*ly+*rphi#+ in c*de devel*p+ent and +aintenance) The intent *9 "ava i# that y*u u#e p*ly+*rphic +eth*d call# thr*ugh*ut y*ur c*de, and y*u u#e RTT- *nly !hen y*u +u#t) H*!ever, u#ing p*ly+*rphic +eth*d call# a# they are intended reDuire# that y*u have c*ntr*l *9 the 3a#eEcla## de9initi*n 3ecau#e at #*+e p*int in the e;ten#i*n *9 y*ur pr*gra+ y*u +ight di#c*ver that the 3a#e cla## d*e#nt include the +eth*d y*u need) -9 the 3a#e cla## c*+e# 9r*+ a li3rary *r i# *ther!i#e c*ntr*lled 3y #*+e*ne el#e, a #*luti*n t* the pr*3le+ i# RTT-1 :*u can inherit a ne! type and add y*ur e;tra +eth*d) El#e!here in the c*de y*u can detect y*ur particular type and call that #pecial +eth*d) Thi# d*e#nt de#tr*y the p*ly+*rphi#+ and e;ten#i3ility *9 the pr*gra+ 3ecau#e adding a ne! type !ill n*t reDuire y*u t* hunt 9*r #!itch #tate+ent# in y*ur pr*gra+) H*!ever, !hen y*u add ne! c*de in y*ur +ain 3*dy that reDuire# y*ur ne! 9eature, y*u +u#t u#e RTT- t* detect y*ur particular type) Putting a 9eature in a 3a#e cla## +ight +ean that, 9*r the 3ene9it *9 *ne particular cla##, all *9 the *ther cla##e# derived 9r*+ that 3a#e reDuire #*+e +eaningle## #tu3 *9 a +eth*d) Thi# +ake# the inter9ace le## clear and ann*y# th*#e !h* +u#t *verride a3#tract +eth*d# !hen they derive 9r*+ that 3a#e cla##) 5*r e;a+ple, c*n#ider a cla## hierarchy repre#enting +u#ical in#tru+ent#) Supp*#e y*u !anted t* clear the #pit valve# *9 all the appr*priate in#tru+ent# in y*ur *rche#tra) One *pti*n i# t* put a clear#pitHalve( ) +eth*d in the 3a#e cla## Bnstrument, 3ut thi# i# c*n9u#ing 3ecau#e it i+plie# that !ercussion and &lectronic in#tru+ent# al#* have #pit valve#) RTT- pr*vide# a +uch +*re rea#*na3le
5&&
Thinking in C
www.ThinkingIn.!et
#*luti*n in thi# ca#e 3ecau#e y*u can place the +eth*d in the #peci9ic cla## G=ind in thi# ca#eH, !here it# appr*priate) H*!ever, a +*re appr*priate #*luti*n i# t* put a prepareBnstrument( ) +eth*d in the 3a#e cla##, 3ut y*u +ight n*t #ee thi# !hen y*ure 9ir#t #*lving the pr*3le+ and c*uld +i#takenly a##u+e that y*u +u#t u#e RTT-) 5inally, RTT- !ill #*+eti+e# #*lve e99iciency pr*3le+#) -9 y*ur c*de nicely u#e# p*ly+*rphi#+, 3ut it turn# *ut that *ne *9 y*ur *34ect# react# t* thi# general purp*#e c*de in a h*rri3ly ine99icient !ay, y*u can pick *ut that type u#ing RTT- and !rite ca#eE#peci9ic c*de t* i+pr*ve the e99iciency) Be !ary, h*!ever, *9 pr*gra++ing 9*r e99iciency t** #**n) -t# a #eductive trap) -t# 3e#t t* get the pr*gra+ !*rking $irst, then decide i9 it# running 9a#t en*ugh, and *nly then #h*uld y*u attack e99iciency i##ue#R!ith a pr*9iler)
%&ercises
S*luti*n# t* #elected e;erci#e# can 3e 9*und in the electr*nic d*cu+ent The Thinking in ,a-a 5nnotated @olution Duide, availa3le 9*r a #+all 9ee 9r*+ www.BruceEckel.com)
1.
=dd *homboid t* #hapes6)ava) Create a *homboid, upca#t it t* a #hape, then d*!nca#t it 3ack t* a *homboid) Try d*!nca#ting t* a Circle and #ee !hat happen#) A*di9y E;erci#e 0 #* that it u#e# instanceof t* check the type 3e9*re per9*r+ing the d*!nca#t) A*di9y #hapes6)ava #* that it can IhighlightJ G#et a 9lagH in all #hape# *9 a particular type) The to#tring( ) +eth*d 9*r each derived #hape #h*uld indicate !hether that #hape i# Ihighlighted)J A*di9y #weet#hop6)ava #* that each type *9 *34ect creati*n i# c*ntr*lled 3y a c*++andEline argu+ent) That i#, i9 y*ur c*++and line i# I)ava #weet#hop Candy,J then *nly the Candy *34ect i# created) *tice h*! y*u can c*ntr*l !hich Class *34ect# are l*aded via the c*++andEline argu+ent) =dd a ne! type *9 !et t* !etCount96)ava) Ceri9y that it i# created and c*unted c*rrectly in main( ))
2. 3.
!.
5&'
". C. D. E. 1F.
,rite a +eth*d that take# an *34ect and recur#ively print# all the cla##e# in that *34ect# hierarchy) A*di9y E;erci#e . #* that it u#e# Class6get$eclared:ields( ) t* al#* di#play in9*r+ati*n a3*ut the 9ield# in a cla##) -n +oy+est6)ava, c*++ent *ut +oy# de9ault c*n#truct*r and e;plain !hat happen#) -nc*rp*rate a ne! kind *9 interface int* +oy+est6)ava and veri9y that it i# detected and di#played pr*perly) Create a ne! type *9 c*ntainer that u#e# a private 'rrayList t* h*ld the *34ect#) Capture the type *9 the 9ir#t *34ect y*u put in it, and then all*! the u#er t* in#ert *34ect# *9 *nly that type 9r*+ then *n) ,rite a pr*gra+ t* deter+ine !hether an array *9 char i# a pri+itive type *r a true *34ect) -+ple+ent clear#pitHalve( ) a# de#cri3ed in the #u++ary) -+ple+ent the rotate(#hape) +eth*d de#cri3ed in thi# chapter, #uch that it check# t* #ee i9 it i# r*tating a Circle Gand, i9 #*, d*e#nt per9*r+ the *perati*nH) -n +oy+est6)ava, u#e re9lecti*n t* create a +oy *34ect u#ing the n*nde9ault c*n#truct*r) L**k up the inter9ace 9*r )ava6lang6Class in the HTAL "ava d*cu+entati*n 9r*+ 3a-a.sun.com) ,rite a pr*gra+ that take# the na+e *9 a cla## a# a c*++andEline argu+ent, then u#e# the Class +eth*d# t* du+p all the in9*r+ati*n availa3le 9*r that cla##) Te#t y*ur pr*gra+ !ith a #tandard li3rary cla## and a cla## y*u create)
1 . 1!.
5'(
Thinking in C
www.ThinkingIn.!et
There have 3een t!* antag*ni#tic 9*rce# at !*rk in the ,ind*!# >U- pr*gra++ing !*rld P the ea#e *9 u#e epit*+i7ed 3y Ci#ual Ba#ic and the c*ntr*l availa3le t* C pr*gra++er# u#ing the ,in/2 =P-) Rec*nciling the#e 9*rce# i# *ne *9 the great achieve+ent# *9 the ) ET 5ra+e!*rk) Ci#ual Studi* ) ET pr*vide# a CBElike t**l#et 9*r dra!ing 9*r+#, draggingEandEdr*pping !idget# *nt* the+, and rapidly #peci9ying their pr*pertie#, event, and re#p*n#e#) H*!ever, thi# ea#yEt*Eu#e t**l #it# *n t*p *9 ,ind*!# 5*r+# and >?-@, #y#te+# !h*#e *34ectE
0 = variati*n *n thi# i# called Ithe principle *9 lea#t a#t*ni#h+ent,J !hich e##entially #ay#1
5'1
*riented de#ign, c*n#i#tency, and 9le;i3ility are un#urpa##ed 9*r creating rich client inter9ace#)
The ai+ *9 thi# chapter i# t* give a g**d under#tanding *9 the underlying c*ncept# at play in i+ple+enting graphical u#er inter9ace# and t* c*uple th*#e c*ncept# !ith c*ncrete detail# *n the +*#t c*++*nlyEu#ed !idget#) 5*r "ava pr*gra++er#, the ea#e !ith !hich rich, highly re#p*n#ive inter9ace# and cu#t*+ c*+p*nent# can 3e created in C# !ill c*+e a# a revelati*n) "ava# U- +*del# have 3een 3a#ed *n the pre+i#e that *perating #y#te+ integrati*n i# #uper9lu*u# t* the ta#k *9 creating pr*gra+ inter9ace#) Thi# i# a3#urd, i9 9*r n* *ther rea#*n than it# vi*lati*n *9
4elegates
One *9 C## +*#t intere#ting language 9eature# i# it# #upp*rt 9*r delegates, an *34ectE*riented, +eth*d type) The line1 de egate #tring Hoo0int para!13 i# a t4"e declaration 4u#t a# i#1 c a## Bar; < =nd 4u#t a# t* 3e u#e9ul a cla## type ha# t* 3e in#tantiated Gunle## it 4u#t ha# static data and +eth*d#H, #* t** +u#t delegate type# 3e in#tantiated t* 3e *9 any u#e) = delegate can 3e in#tantiated !ith any +eth*d that
5')
+atche# the delegate# type #ignature) Once in#tantiated, the delegate re9erence can 3e u#ed directly a# a +eth*d) ?elegate# are *34ectE*riented in that they can 3e 3*und n*t 4u#t t* #tatic +eth*d#, 3ut t* in#tance +eth*d#Q in d*ing #*, a delegate !ill e;ecute the #peci9ied +eth*d *n the de#ignated *34ect) = #i+ple e;a+ple !ill #h*! the 3a#ic 9eature# *9 delegate#1 //:c"T:-rofe##ion.c# //:ec aration and in#tantiation of de egate# de egate *oid -rofe##ion013 c a## -rofe##ionSpea%er; #tatic *oid StaticSpea%er01; Sy#te!.Con#o e.VriteLine0&Gedicine&13 < #tatic int doctor5dCounter 9 03 int doctor5d 9 doctor5dCounterRR3 *oid 5n#tanceSpea%er01; Sy#te!.Con#o e.VriteLine0&:octor & R doctor5d13 < int :ifferentSignature01; Sy#te!.Con#o e.VriteLine0&Hirefighter&13 return 03 < pu$ ic #tatic *oid Gain01; //dec are de egate reference 099 nu 1 -rofe##ion p3 //in#tantiate de egate reference p 9 ne. -rofe##ion0 -rofe##ionSpea%er.StaticSpea%er13 p013 -rofe##ionSpea%er #" 9 ne. -rofe##ionSpea%er013 -rofe##ionSpea%er #2 9 ne. -rofe##ionSpea%er013
5'3
//&in#tantiate& to #pecific in#tance# -rofe##ion p" 9 ne. -rofe##ion0 #".5n#tanceSpea%er13 -rofe##ion p2 9 ne. -rofe##ion0 #2.5n#tanceSpea%er13 p"013 p2013 //Von't co!pi e2 different #ignature //-rofe##ion pT 9 ne. -rofe##ion0 // #2.:ifferentSignature13 < <///:8 The !rofession delegate type i# declared t* take n* para+eter# and t* return void) The !rofession#pea(er ha# t!* +eth*d# !ith thi# #ignature1 a static #tatic#pea(er() +eth*d and an in#tance +eth*d called Bnstance#pea(er()) !rofession#pea(er ha# a #tatic doctorBdCounter !hich i# incre+ented every ti+e a ne! !rofession#pea(er i# in#tantiatedQ thu# Bnstance#pea(er() ha# di99erent *utput 9*r each !rofession#pea(er in#tance) !rofession#pea(er6.ain() declare# a delegate re9erence !rofession p) Like all declared 3ut n*t initiali7ed varia3le#, p i# null at thi# p*int) The ne;t line i# the delegate# Ic*n#truct*rJ and i# *9 the 9*r+1 ne. :e egate'ypeCa!e0 Ca!eOfGethod'o:e egate 13 Thi# 9ir#t delegate i# in#tantiated !ith the #tatic#pea(er() +eth*d Gn*te that the value pa##ed t* the delegate Ic*n#truct*rJ i# 4u#t the name *9 the +eth*d !ith*ut the parenthe#e# that !*uld #peci9y an actual +eth*d callH) Once the delegate i# initiali7ed, the re9erence -aria2le act# a# i9 it !a# an inE#c*pe +eth*d name) S* the line p() re#ult# in a call t* !rofession#pea(er6#tatic#pea(er()) .ain() then in#tantiate# t!* ne! !rofession#pea(er#Q *ne *9 !hich !ill have a doctorBd *9 $ and the *ther *9 0) ,e declare t!* ne! !rofession delegate#, 3ut thi# ti+e u#e a #light di99erent 9*r+1
5'4
Thinking in C
www.ThinkingIn.!et
ne. :e egate'ypeCa!e0 o$DectReference.GethodCa!e 13 :*u can think *9 thi# a# pa##ing Ithe in#tance *9 the +eth*dJ a##*ciated !ith the ob)ect*eference, even th*ugh Ithat# n*t h*! it really i#J in +e+*ry Gthere# a c*py *9 each piece *9 data 9*r an in#tance, 3ut methods are n*t duplicatedH) The t!* delegate# p7 and p8 can n*! 3e u#ed a# pr*;ie# 9*r the +eth*d# s76Bnstance#pea(er() and s86Bnstance#pea(er()) The delegatedEt* +eth*d +u#t have the e;act para+eter# and return t4"e *9 the delegate type declarati*n) Thu#, !e cant u#e $ifferent#ignature() G!hich return# an intH t* in#tantiate a !rofession delegate) ,hen run, the call# t* the delegate# p, p7, and p8 re#ult in thi# *utput1 Gedicine :octor 0 :octor "
5'5
The Strategy pattern e;plicitly 3ind# the i+ple+entati*n t* it# u#e #ati#9ying the c*ntract *9 the inter9ace B#trategyQ any cla## !hich !ill 3e u#ed a# a #trategy +u#t declare it#el9 a# D B#trategy and i+ple+ent the +eth*d void #trategy()) ,ith delegate#, there i# n* e;plicit 3inding *9 the handler t* the delegate typeQ a ne! pr*gra++er c*+ing t* the #ituati*n !*uldnt nece##arily kn*! that 'nyClass6#trat"andler() !a# 3eing u#ed t* in#tantiate a #trategy delegate) Thi# +ight lead t* tr*u3le1 the ne! pr*gra++er c*uld change the 3ehavi*r *9 #trat"andler() in a !ay inappr*priate t* it# u#e a# a #trategy delegate and the change !*uld n*t 3e caught 3y either the c*+piler *r 3y 'nyClass# unit te#t#Q the pr*3le+ !*uldnt appear until Client# unit te#t# !ere run)
5'6
Thinking in C
www.ThinkingIn.!et
On the *ther hand, the delegate +*del i# #igni9icantly le## typing and can delegate handling t* a +eth*d in a type 9*r !hich y*u d*nt have #*urce c*de Galth*ugh there# n* *3vi*u# #cenari* that !*uld call 9*r thatH) .1*& "&*&
@ulticast 4elegates
?elegate# that return type v*id +ay de#ignate a series *9 +eth*d# that !ill 3e inv*ked !hen the delegate i# called) Such delegate# are called multicast delegates) Aeth*d# can 3e added and re+*ve 9r*+ the call chain 3y u#ing the *verl*aded @X and EX *perat*r#) Here# an e;a+ple1 //:c"T:Gu tica#t.c# //:e!on#trate# !u tica#t de egate# c a## Roo#ter; interna *oid Cro.01; Sy#te!.Con#o e.VriteLine0&Coc%6a6dood e6doo&13 < < c a## -aperBoy; interna *oid :e i*er-aper#01; Sy#te!.Con#o e.VriteLine0&'hro. paper on roof&13 < < c a## Sun; interna *oid Ri#e01; Sy#te!.Con#o e.VriteLine0&Spread ro#y finger#&13 < < c a## :a.nRoutine; de egate *oid :a.nBeha*ior013 :a.nBeha*ior !u tica#t3 :a.nRoutine01;
5'#
!u tica#t 9 ne. :a.nBeha*ior0 ne. Roo#ter01.Cro.13 !u tica#t R9 ne. :a.nBeha*ior0 ne. -aperBoy01.:e i*er-aper#13 !u tica#t R9 ne. :a.nBeha*ior0 ne. Sun01.Ri#e13 < *oid Brea%01; !u tica#t013 < pu$ ic #tatic *oid Gain01; :a.nRoutine dr 9 ne. :a.nRoutine013 dr.Brea%013 < <///:8 =9ter declaring three cla##e# G*ooster, !aperBoy, and #unH that have +eth*d# a##*ciated !ith the da!n, !e declare a $awn*outine cla## and, !ithin it# #c*pe, declare a $awnBehavior delegate type and an in#tance varia3le multicast t* h*ld the in#tance *9 the delegate) The $awn*outine() c*n#truct*r# 9ir#t line in#tantiate# the delegate t* the Crow() +eth*d *9 a *ooster *34ect Gthe gar3age c*llect*r i# #+art en*ugh t* kn*! that alth*ugh !ere u#ing an anon4mous in#tance *9 *ooster, the in#tance !ill n*t 3e c*llected a# l*ng a# the delegate c*ntinue# t* h*ld a re9erence t* itH) e! in#tance# *9 $awnBehavior are in#tantiated !ith re9erence# t* Iin#tance#J *9 !aperBoy6$eliver!apers() and #un6*ise()) The#e ?a!nBehavi*r delegate# are added t* the multicast delegate !ith the @X *perat*r) Brea(() inv*ke# multicast() *nce, 3ut that #ingle call in turn i# multicast t* all the delegate#1 Coc%6a6dood e6doo 'hro. paper on roof Spread ro#y finger# Aultica#t delegate# are u#ed thr*ugh*ut ,ind*!# 5*r+# t* create eventE handling chain#, each *9 !hich i# re#p*n#i3le 9*r a particular a#pect *9 the t*tal de#ired 3ehavi*r Gperhap# di#playE*riented, perhap# l*gical, perhap# #*+ething that !rite# t* a l*g9ileH)
5'&
Thinking in C
www.ThinkingIn.!et
The *ne di99erence i# that the Chain o$ ?es"onsi2ilit4 i# u#ually i+ple+ented #* that an individual handler can decide t* end the pr*ce##ing chain Gthat i#, a handler +ay decide n*t t* call it# successor# "andle*e%uest() +eth*dH) -t i# n*t p*##i3le 9*r a delegatedEt* +eth*d t* have thi# #*+eti+e#Ede#ired *pti*n, #* there +ay 3e ti+e# !hen y*u i+ple+ent a Chain o$ ?es"onsi2ilit4 !ithin an inter9ace *n !hich y*u create #ingle *r +ultica#t delegate#1 //:c"T::e egatedChainOfRe#pon#i$i ity.c# //Sho.# po y!orphic de egation2 p u# CoR pattern u#ing Sy#te!3 interface Uand er; *oid Uand eRe7ue#t013 < c a## ConcreteUand er" : Uand er; Rando! r 9 ne. Rando!013 Uand er #ucce##or 9 ne. ConcreteUand er2013 pu$ ic *oid Uand eRe7ue#t01 ; if0r.Cext:ou$ e01 Z 0.P1; Sy#te!.Con#o e.VriteLine0 &CU": Uand ing inco!p ete&13 #ucce##or.Uand eRe7ue#t013 <e #e; Sy#te!.Con#o e.VriteLine0
5''
&CU": Uand ing co!p ete&13 < < < c a## ConcreteUand er2 : Uand er; pu$ ic *oid Uand eRe7ue#t01 ; Sy#te!.Con#o e.VriteLine0&U2 hand ing&13 < < c a## C ient; de egate *oid -o y:e 013 pri*ate #tatic *oid ) #oUand er01; Sy#te!.Con#o e.VriteLine0&) #oUand er&13 < pu$ ic #tatic *oid Gain01; //Cote upca#t Uand er h 9 ne. ConcreteUand er"013 -o y:e de 9 ne. -o y:e 0h.Uand eRe7ue#t13 de R9 ne. -o y:e 0) #oUand er13 de 013 < < The "andler inter9ace and it# t!* #u3type# i+ple+ent the Chain o$ ?es"onsi2ilit4 pattern) Concrete"andler7 I9lip# a c*inJ in the 9*r+ *9 a rand*+ nu+3er and either call# successor6"andle*e%uest() *r n*t) The !oly$el delegate declared !ithin Client +atche# the inter9ace in "andler, #* !hen a ne! "andler i# in#tantiated in Client6.ain(), there i# n* pr*3le+ in u#ing that handle# "andle*e%uest +eth*d a# the argu+ent t* a ne! !oly$el delegate) Since delegate# are *34ectE *riented, there i# n* pr*3le+ u#ing a handle that# 3een upca#t t* an a3#tract data type in the c*n#tructi*n *9 a delegate) ,hen del() i# inv*ked, hal9 the ti+e the Concrete"andler7 !ill 9*r!ard a call t* it# Concrete"andler8 successor and hal9 the ti+e n*t) Becau#e !oly$el i# a +ultica#t handler, th*ugh, 'lso"andler() !ill al!ay# 3e called)
6((
Thinking in C
www.ThinkingIn.!et
%vents
The 3ehavi*r *9 a +ultica#t delegate can 3e interpreted a# a #ingle event Gthe +ultica#t +eth*d callH cau#ing +ultiple 3ehavi*r# Gthe call# *n the vari*u# delegatedEt* +eth*d#H) H*!ever, !ith a n*r+al delegate, the delegatedEt* +eth*d ha# n* !ay *9 kn*!ing anything a3*ut the c*nte;t in !hich it !a# inv*ked) -n *ur .ulticast e;a+ple, the #un6*ise() +eth*d G#ayH c*uld n*t have a99ected any change in the $awn*outine *34ect that inv*ked it) By c*nventi*n, +ultica#t delegate# that reDuire c*nte;t #h*uld 3e *9 type1 de egate *oid :e egateCa!e0 o$Dect #ource2 +*ent)rg#Su$type x13 The &vent'rgs cla## i# de9ined in the #ystem na+e#pace and, 3y de9ault, c*ntain# n*thing 3ut a #tatic read*nly pr*perty &mpty that i# de9ined a# returning an &vent'rg eDuivalent t* an &vent'rg created !ith a n*Earg# c*n#truct*r Gin *ther !*rd#, a generic, undi#tingui#ha3le, and there9*re IE+ptyJ argu+entH) Su3type# *9 &vent'rgs are e;pected t* de9ine and e;p*#e pr*pertie# that are the +*#t likely i+p*rtant piece# *9 c*nte;t) 5*r in#tance, the $awnBehavior delegate +ight 3e paired !ith a $awn&vent'rgs *34ect that c*ntained the !eather and ti+e *9 #unri#e) -9 a cla## !i#he# t* de9ine a +ultica#t delegate *9 thi# #*rt and e;p*#e it pu3licly a# a pr*perty, the n*r+al C# #ynta; !*uld 3e1 *oid :a.n:e egate0o$Dect #ource2 :a.n+*ent)rg# dea13 c a## :a.n+*ent)rg# : +*ent)rg#;< c a## :a.nBeha*ior; pri*ate :a.n:e egate d3 pu$ ic :a.n:e egate :a.n+*ent; get ; return d3 < #et ; d 9 *a ue3 < < < = #h*rtcut i# t* #i+ply declare an e-ent "ro"ert41 pu$ ic e*ent :a.n:e egate :a.n+*ent3
6(1
:*u #till have t* de9ine the delegate and the #u3type *9 $awn&vent'rgs and there i# n* di99erence in 3ehavi*r 3et!een a pu3lic +ultica#t delegate e;p*#ed a# a n*r+al pr*perty and *ne e;p*#ed a# an event pr*perty) H*!ever, event pr*pertie# +ay 3e treated di99erently 3y devel*per t**l# #uch a# the d*cEc*++ent generat*r *r vi#ual 3uilder t**l# #uch a# the *ne in Ci#ual Studi*) ET) Thi# e;a+ple #h*!# event handler# that +*di9y their 3ehavi*r depending *n the c*nte;t1 //:c"T:+*ent-roperty.c# u#ing Sy#te!3 de egate *oid :a.n:e egate0 o$Dect #ource2 :a.n+*ent)rg# dea13 enu! Veather; #unny2 rainy <3 c a## :a.n+*ent)rg# : +*ent)rg#; //Uide $a#e c a## con#tructor pri*ate :a.n+*ent)rg#01 : $a#e01;< pu$ ic :a.n+*ent)rg#0Veather .1; thi#.. 9 .3 < pri*ate Veather .3 pu$ ic Veather GorningVeather; #et ; . 9 *a ue3 < get ; return .3 < < < c a## :a.nBeha*ior; pu$ ic e*ent :a.n:e egate :a.n+*ent3 pu$ ic #tatic *oid Gain01; :a.nBeha*ior d$ 9 ne. :a.nBeha*ior013 d$.:a.n+*ent 9 ne. :a.n:e egate0 ne. Roo#ter01.Cro.13 d$.:a.n+*ent R9 ne. :a.n:e egate0 ne. Sun01.Ri#e13
6()
Thinking in C
www.ThinkingIn.!et
:a.n+*ent)rg# dea 9 ne. :a.n+*ent)rg#0Veather.#unny13 d$.:a.n+*ent0typeof0:a.nBeha*ior12 dea13 dea 9 ne. :a.n+*ent)rg#0Veather.rainy13 d$.:a.n+*ent0typeof0:a.nBeha*ior12 dea13 < < c a## Roo#ter; interna *oid Cro.0o$Dect #rc2 :a.n+*ent)rg# dea1; if0dea.GorningVeather 99 Veather.#unny1; Sy#te!.Con#o e.VriteLine0 &Coc%6a6dood e6doo&13 <e #e; Sy#te!.Con#o e.VriteLine0&S eep in&13 < < < c a## Sun; interna *oid Ri#e0o$Dect #rc2 :a.n+*ent)rg# dea1; if0dea.GorningVeather 99 Veather.#unny1; Sy#te!.Con#o e.VriteLine0 &Spread ro#y finger#&13 <e #e; Sy#te!.Con#o e.VriteLine0 &Ca#t a grey pa &13 < < < -n thi# e;a+ple, the $awn&vent i# created in the #tatic .ain() +eth*d, #* !e c*uldnt #end this a# the #*urce n*r d*e# pa##ing in the db in#tance #ee+ appr*priate) ,e c*uld pa## null a# the #*urce, 3ut pa##ing null i# generally a 3ad idea) Since the event i# created 3y a #tatic +eth*d and a #tatic +eth*d i# a##*ciated !ith the cla##, it #ee+# rea#*na3le t* #ay that the #*urce i# the type in9*r+ati*n *9 the cla##, !hich i# retrieved 3y typeof($awnBehavior))
6(3
6ecursive -ra$s
C*nceptually, eventEdriven pr*gra+# are a#ynchr*n*u# P !hen an event i# I9iredJ G*r Irai#edJ *r I#entJH, c*ntr*l return# t* the 9iring +eth*d and, #*+eti+e in the 9uture, the event handler get# called) -n reality, C## event# are #ynchr*n*u#, +eaning that c*ntr*l d*e# n*t return t* the 9iring +eth*d until the event handler ha# c*+pleted) Thi# c*nceptual gap can lead t* #eri*u# pr*3le+#) -9 the event handler *9 event H it#el9 rai#e# event#, and the handling *9 the#e event# re#ult# in a ne! event H, the #y#te+ !ill recur#e, eventually either cau#ing a #tack *ver9l*! e;cepti*n *r e;hau#ting #*+e n*nE+e+*ry re#*urce) -n thi# e;a+ple, a utility c*+pany #end# 3ill# *ut, a h*+e*!ner pay# the+, !hich trigger# a ne! 3ill) 5r*+ a c*nceptual #tandp*int, thi# #h*uld 3e 9ine, 3ecau#e the pay+ent and the ne! 3ill are #eparate event#) //:c"T:Recur#i*e+*ent#.c# //:e!on#trate# danger in C( e*ent !ode u#ing Sy#te!3 de egate *oid -ay!ent+*ent0o$Dect #rc2 Bi c a## Bi )rg#; interna Bi )rg#0dou$ e c1; co#t 9 c3 < pu$ ic dou$ e co#t3 < a$#tract c a## Boo%%eeper; pu$ ic e*ent -ay!ent+*ent 5n$ox3 pu$ ic #tatic *oid Gain01; Boo%%eeper ho 9 ne. Uo!eo.ner013 Oti ityCo uc 9 ne. Oti ityCo013 uc.BeginBi < interna *oid -o#t0o$Dect #rc2 dou$ e c1; 5n$ox0#rc2 ne. Bi )rg#0c113 ing0ho13 )rg# ea13
6(4
Thinking in C
www.ThinkingIn.!et
< < c a## Oti ityCo : Boo%%eeper; interna Oti ityCo01; 5n$ox R9 ne. -ay!ent+*ent0thi#.Recei*e-!t13 < interna *oid BeginBi ing0Boo%%eeper $%1; $%.-o#t0thi#2 E.013 < pu$ ic *oid Recei*e-!t0o$Dect #rc2 Bi )rg# ea1; Boo%%eeper #ender 9 #rc a# Boo%%eeper3 Sy#te!.Con#o e.VriteLine0&Recei*ed p!t fro! & R #ender13 #ender.-o#t0thi#2 "0.013 < < c a## Uo!eo.ner : Boo%%eeper; interna Uo!eo.ner01; 5n$ox R9 ne. -ay!ent+*ent0Recei*eBi 13 < pu$ ic *oid Recei*eBi 0o$Dect #rc2 Bi )rg# ea1; Boo%%eeper #ender 9 #rc a# Boo%%eeper3 Sy#te!.Con#o e.VriteLine0&Vriting chec% to & R #ender R & for & R ea.co#t13 #ender.-o#t0thi#2 ea.co#t13 < < 5ir#t, !e declare a delegate type called !ayment&vent !hich take# a# an argu+ent a Bill'rgs re9erence c*ntaining the a+*unt *9 the 3ill *r pay+ent) ,e then create an a3#tract Boo((eeper cla## !ith a !ayment&vent event called Bnbox) The .ain() 9*r the #a+ple create# a "ome1wner, a VtilityCo, and pa##e# the re9erence t* the "ome1wner t* the VtilityCo t* 3egin 3illing) Boo((eeper then
6(5
de9ine# a +eth*d called !ost() !hich trigger# the !ayment&vent( )F !ell e;plain the rati*nale 9*r thi# +eth*d in a little 3it) VtilityCo6BeginBilling() take# a Boo((eeper Gthe h*+e*!nerH a# an argu+ent) -t call# that Boo((eeper# !ost( ) +eth*d, !hich in turn !ill call that Boo((eeper# Bnbox delegate) -n the ca#e *9 the "omeowner, that !ill activate the *eceiveBill( ) +eth*d) The h*+e*!ner I!rite# a checkJ and !ost( )# it t* the #*urce) -9 event# !ere a#ynchr*n*u#, thi# !*uld n*t 3e a pr*3le+) H*!ever, !hen run, thi# !ill run a# e;pected 9*r #everal hundred iterati*n#, 3ut then !ill cra#h !ith a #tack *ver9l*! e;cepti*n) either *9 the event handler# G*eceiveBill( ) and *eceive!ayment( ) H ever return#, they 4u#t recur#ively call each *ther in !hat !*uld 3e an in9inite l**p 3ut 9*r the 9inite #tack) A*re #u3tle recur#ive l**p# are a challenge !hen !riting eventEdriven c*de in C#) Perhap# in *rder t* di#c*urage 4u#t the#e type# *9 pr*3le+#, event pr*pertie# di99er 9r*+ delegate# in *ne very i+p*rtant !ay1 an event can *nly 3e inv*ked 3y the very cla## in !hich it i# declaredQ even de#cendant type# cann*t directly inv*ke an event) Thi# i# !hy !e needed t* !rite the !ost( ) +eth*d in Boo((eeper, "ome1wner and VtilityCo cann*t e;ecute Bnbox( ), atte+pting t* d* #* re#ult# in a c*+pilati*n err*r) Thi# language re#tricti*n i# a #yntactical !ay *9 #aying Irai#ing an event i# a 3ig deal and +u#t 3e d*ne !ith care)J EventEdriven de#ign# +ay reDuire +ultiple thread# in *rder t* av*id recur#ive l**p# G+*re *n thi# in chapter #threading#H) Or they +ay n*t) Thi# re#tricti*n *n event# d*e# n*t 9*rce y*u int* any particular de#ign deci#i*n# P a# !e #h*!ed in thi# e;a+ple, *ne can #i+ply create a pu3lic pr*;y +eth*d t* inv*ke the event)
6(6
Thinking in C
www.ThinkingIn.!et
Thi# !a# #tateE*9EtheEart #tu99 in the +idE06($# 3e9*re *34ectE*rientati*n 3eca+e p*pular) -n the early 066$#, pr*duct# #uch a# =ct*r, SML ,ind*!#, Ci#ual Ba#ic, and A5C 3egan hiding thi# c*+ple;ity 3ehind a variety *9 di99erent +*del#, *9ten trading *99 *34ectE*riented IpurityJ 9*r ea#e *9 devel*p+ent *r per9*r+ance *9 the re#ulting applicati*n) =lth*ugh pr*gra++ing li3rarie# 9r*+ c*+panie# *ther than Aicr*#*9t !ere #*+eti+e# #uperi*r, Aicr*#*9t# li3rarie# al!ay# had the edge in #h*!ca#ing ,ind*!# late#t capa3ilitie#) Aicr*#*9t parlayed that int* increa#ing +arket #hare in the devel*p+ent t**l# categ*ry, at lea#t until the e;pl*#i*n *9 the ,*rld ,ide ,e3 in the +idE066$#, !hen the thenE current !i#d*+ a3*ut u#er inter9ace# G#u++ary1 IU-# +u#t c*n#i#tently 9*ll*! plat9*r+ #tandard#, and U-# +u#t 3e 9a#tJH !a# le9t 3y the !ay#ide 9*r the ne! i+perative GI=ll applicati*n# +u#t run in#ide 3r*!#er#JH) One *9 the pr*gra++ing t**l# that had di99iculty gaining +arket#hare again#t Aicr*#*9t !a# B*rland# ?elphi, !hich c*+3ined a #ynta; derived 9r*+ Tur3* Pa#cal, a graphical 3uilder a la Ci#ual Ba#ic, and an *34ectE *riented 9ra+e!*rk 9*r 3uilding U-#) ?elphi !a# the 3rainchild *9 =nder# He4l#3erg, !h* #u3#eDuently le9t B*rland 9*r Aicr*#*9t, !here he devel*ped the predece##*r *9 ) ET# ,ind*!# 5*r+# li3rary 9*r Ci#ual "@ @) He4l#3erg !a# the chie9 de#igner *9 the C# language and C## delegate# trace their ance#try t* ?elphi) G-ncidentally, ?elphi re+ain# a great pr*duct and i# n*!, ir*nically, the 3e#t t**l 9*r pr*gra++ing native Linu; applicati*n#KH S* ,ind*!# 5*r+# i# an *34ectE*riented !rapper *9 the underlying ,ind*!# applicati*n) The d*u3ling and red*u3ling *9 pr*ce##*r #peed thr*ugh*ut the 066$# ha# +ade any per9*r+ance hit a##*ciated !ith thi# type *9 a3#tracti*n irrelevantQ ,ind*!# 5*r+# applicati*n# tran#late the ra! ,ind*!# event# int* call# t* +ultica#t delegate# Gi)e), event#H #* e99iciently that +*#t pr*gra++er# !ill never have a need t* #ideE#tep the li3rary)
Creating a 7or#
,ith ,ind*!# 5*r+#, the #tatic AainGH +eth*d call# the #tatic +eth*d =pplicati*n)RunGH, pa##ing t* it a re9erence t* a #u3type *9 :orm) =ll the 3ehavi*r a##*ciated !ith creating, di#playing, cl*#ing and *ther!i#e
6(#
+anipulating a ,ind*! Gincluding repainting, a 9inicky p*int *9 the Ira!J ,ind*!# =P-H i# in the 3a#e type :orm and need n*t 3e *9 c*ncern t* the pr*gra++er) Here# a 9ully 9uncti*nal ,ind*!# 5*r+ pr*gra+1 //:c"T:Hir#tHor!.c# u#ing Sy#te!.Vindo.#.Hor!#3 c a## Hir#tHor! : Hor!; pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Hir#tHor!0113 < <///:8 that !hen run pr*duce# thi# !ind*!1
The 3a#e cla## :orm c*ntain# +*re than 0$$ pu3lic and pr*tected pr*pertie#, a #i+ilar nu+3er *9 +eth*d#, and +*re than %$ event# and c*rre#p*nding eventErai#ing +eth*d#) But it d*e#nt #t*p thereQ :orm i# a #u3type *9 a cla## called Control Gn*t a direct #u3type, it# actually :orm 1 ContainerControl 1 #crollableControl 1 ControlH) -n#tance# *9 Control have a pr*perty called Controls !hich c*ntain# a c*llecti*n *9 *ther c*ntr*l#) Thi# #tructure, an e;a+ple *9 the Com"osite de#ign pattern, all*!# everything 9r*+ #i+ple 3utt*n# t* the +*#t c*+ple; u#erE
6(&
Thinking in C
www.ThinkingIn.!et
inter9ace# t* 3e treated uni9*r+ly 3y pr*gra++er# and devel*p+ent t**l# #uch a# the vi#ual 3uilder t**l in Ci#ual Studi* ) ET)
G>I )rchitectures
=rchitecture# !ere pre#ented in chapter #architectur# a# an I*verall *rdering principleJ *9 a #y#te+ *r #u3#y#te+) ,hile the Controls pr*perty *9 Control i# an *rdering principle 9*r the #tatic #tructure *9 the !idget# in a ,ind*!# 5*r+# applicati*n, ,ind*!# 5*r+# d*e# n*t dictate an *rdering principle 9*r a##*ciating the#e !idget# !ith particular event# and pr*gra+ l*gic) Several architecture# are p*##i3le !ith ,ind*!# 5*r+#, and each ha# it# #trength# and !eakne##e#) -t# i+p*rtant t* have a c*n#i#tent U- architecture 3ecau#e, a# Larry C*n#tantine and Lucy L*ck!**d p*int *ut, !hile the U- i# 4u#t *ne, perhap# unintere#ting, part *9 the #y#te+ t* the pr*gra++er, t* the end u#er, the U- is the pr*gra+) The U- i# the entry p*int 9*r the va#t +a4*rity *9 change reDue#t#, #* y*ud 3etter +ake it ea#y t* change the U- !ith*ut changing the l*gical 3ehavi*r *9 the pr*gra+) ?ec*upling the pre#entati*n layer 9r*+ the 3u#ine## layer i# a 9unda+ental part *9 pr*9e##i*nal devel*p+ent)
6('
-n the de#igner, d*u3leEclick the 3utt*n) Ci#ual Studi* !ill #!itch t* a c*deEediting vie!, !ith the cur#*r in#ide a +eth*d called button7AClic(()) =dd the lineQ a$e ".'ext 9 &C ic%ed&3 The re#ulting pr*gra+ #h*uld l**k a l*t like thi#1 //:c"T:Hor!Contro +*ent.c# //:e#igner6generated Hor!6Contro 6+*ent architecture u#ing Sy#te!3
61(
Thinking in C
www.ThinkingIn.!et
na!e#pace Hor!Contro +*ent; /// W#u!!aryZ /// Su!!ary de#cription for Hor!". /// W/#u!!aryZ pu$ ic c a## Hor!" : Sy#te!.Vindo.#.Hor!#.Hor! ; pri*ate Sy#te!.Vindo.#.Hor!#.La$e a$e "3 pri*ate Sy#te!.Vindo.#.Hor!#.Button $utton"3 /// W#u!!aryZ /// Re7uired de#igner *aria$ e. /// W/#u!!aryZ pri*ate Sy#te!.Co!ponentGode .Container co!ponent# 9 nu 3 pu$ ic Hor!"01; // // Re7uired for Vindo.# Hor! :e#igner #upport // 5nitia iMeCo!ponent013 // // 'O:O: )dd any con#tructor code after // 5nitia iMeCo!ponent ca // < /// W#u!!aryZ /// C ean up any re#ource# $eing u#ed. /// W/#u!!aryZ protected o*erride *oid :i#po#e0 $oo di#po#ing 1; if 0 di#po#ing 1 ; if 0co!ponent# !9 nu 1 ; co!ponent#.:i#po#e013 < <
611
$a#e.:i#po#e0 di#po#ing 13 < (region Vindo.# Hor! :e#igner generated code /// W#u!!aryZ /// Re7uired !ethod for :e#igner #upport /// 6 do not !odify the content# of thi# !ethod /// .ith the code editor. /// W/#u!!aryZ pri*ate *oid 5nitia iMeCo!ponent01; thi#. a$e " 9 ne. Sy#te!.Vindo.#.Hor!#.La$e 013 thi#.$utton" 9 ne. Sy#te!.Vindo.#.Hor!#.Button013 thi#.Su#pendLayout013 // // a$e " // thi#. a$e ".Location 9 ne. Sy#te!.:ra.ing.-oint0"T?2 2E13 thi#. a$e ".Ca!e 9 & a$e "&3 thi#. a$e ".SiMe 9 ne. Sy#te!.:ra.ing.SiMe0P?2 "?13 thi#. a$e ".'a$5ndex 9 03 thi#. a$e ".'ext 9 & a$e "&3 // // $utton" // thi#.$utton".Location 9 ne. Sy#te!.:ra.ing.-oint0T22 2E13 thi#.$utton".Ca!e 9 &$utton"&3 thi#.$utton".'a$5ndex 9 "3 thi#.$utton".'ext 9 &$utton"&3 thi#.$utton".C ic% R9 ne. Sy#te!.+*entUand er0thi#.$utton"XC ic%13 // // Hor!" // thi#.)utoSca eBa#eSiMe 9 ne. Sy#te!.:ra.ing.SiMe0P2 "T13 thi#.C ientSiMe 9
61)
Thinking in C
www.ThinkingIn.!et
ne. Sy#te!.:ra.ing.SiMe02>22 2??13 thi#.Contro #.)ddRange0 ne. Sy#te!.Vindo.#.Hor!#.Contro JK; thi#.$utton"2 thi#. a$e "<13 thi#.Ca!e 9 &Hor!"&3 thi#.'ext 9 &Hor!"&3 thi#.Re#u!eLayout0fa #e13 < (endregion /// W#u!!aryZ /// 'he !ain entry point for the app ication. /// W/#u!!aryZ JS')'hreadK #tatic *oid Gain01 ; )pp ication.Run0ne. Hor!"0113 < pri*ate *oid $utton"XC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1 ; a$e ".'ext 9 &C ic%ed&3 < < < The 9ir#t intere#ting detail i# the Uregion E Uendregion #tate+ent#) The#e prepr*ce##ing directive# G#ee Chapter #prepr*ce##ing#H delineate a c*de #ecti*n that Ci#ual Studi* ) ET +ay c*llap#e in it# I*utliningJ +*deQ indeed, !hen y*u 9ir#t #!itch t* c*de vie!, thi# area *9 the c*de !a# pr*3a3ly #*+e!hat hidden 9r*+ vie!) ,hile it# generally a g**d idea t* heed the !arning a3*ut n*t editing ?e#ignerEgenerated c*de, the c*de i# !ell !*rth taking a cl*#er l**k at) The la3el and 3utt*n that !e dragged *nt* the 9*r+ are initiali7ed a# ne! *34ect# 9r*+ the Sy#te+),ind*!#)5*r+# na+e#pace) The call t* #uspendLayout() indicate# that a #erie# *9 +anipulati*n# are c*+ing and that each individual *ne #h*uld n*t trigger the p*tentially e;pen#ive lay*ut calculati*n *n the Control and all *9 it# #u3EControls) S*+e *9 the 3a#ic pr*pertie# 9*r each c*ntr*l are then #et1
613
Location #peci9ie# the p*int !here the upperEle9t c*rner *9 the c*ntr*l i# relative t* the upperEle9t c*rner *9 the c*ntaining c*ntr*l *r, i9 the Control i# a :orm Location i# the #creen c**rdinate# *9 the upperEle9t c*rner Gincluding the :orm# 3*rder i9 it ha# *ne, a# +*#t d*H) Thi# i# a value that y*u can 9reely +anipulate !ith*ut !*rrying a3*ut the #iTe i# +ea#ured in pi;el#) Like Location, thi# pr*perty return# a value, n*t a re9erence, #* t* +anipulate the Control, y*u +u#t a##ign any change t* the pr*perty t* have any a99ect1 SiMe # 9 !yContro .SiMe3 #.Vidth R9 "03 //not a reference2 no change to contro !yContro .SiMe 9 #3 //Co. contro .i change +abBndex #peci9ie# the *rder in !hich a c*ntr*l i# activated !hen the u#er pre##e# the Ta3 key) +ext i# di#played in vari*u# !ay#, depending up*n the Control# type) The +ext *9 the 9*r+, 9*r in#tance, i# di#played a# the ,ind*!# title, !hile the Button and Label have *ther pr*pertie# #uch a# +ext'lign and :ont t* 9ineEtune their appearance G:orm ha# a :ont pr*perty, t**, 3ut it 4u#t #et# the de9ault 9*nt 9*r it# #u3Ec*ntr*l#Q it d*e# n*t change the !ay the title *9 the :orm i# di#playedH) The ,ame pr*perty c*rre#p*nd# t* the na+ed varia3le that repre#ent# the c*ntr*l and i# nece##ary 9*r the vi#ual de#igner t* !*rkQ d*nt +anually change thi#) The 9inal part *9 the 3l*ck *9 c*de a##*ciated !ith button7 read#1 thi#.$utton".C ic% R9 ne. Sy#te!.+*entUand er0thi#.$utton"XC ic%13 5r*+ *ur previ*u# di#cu##i*n *9 +ultica#t delegate#, thi# #h*uld 3e 9airly ea#y t* interpret1 Button ha# an event pr*perty Clic( !hich #peci9ie# a +ultica#t delegate *9 type &vent"andler) The +eth*d this6button7AClic(() i# 3eing added a# a +ultica#t li#tener) =t the 3*tt*+ *9 the BnitialiTeComponent +eth*d, additi*nal pr*pertie# are #et 9*r the :orm7 it#el9) 'uto#caleBase#iTe #peci9ie# h*! the :orm !ill react i9 the :orm# 9*nt i# changed t* a di99erent #i7e Ga# can happen 3y de9ault in ,ind*!#H) Client#iTe i# the area *9 the Control in !hich *ther Control# can 3e placedQ in the ca#e *9 a !ind*!,
614
Thinking in C
www.ThinkingIn.!et
that e;clude# the title 3ar and 3*rder, #cr*ll3ar# are al#* n*t part *9 the client area) The +eth*d Controls6'dd*ange() place# an array *9 Control# in the c*ntaining Control) There i# al#* an 'dd() +eth*d !hich take# a #ingle c*ntr*l, 3ut the vi#ual de#igner al!ay# u#e# 'dd*ange()) 5inally, *esumeLayout(), the c*+ple+ent t* #uspendLayout(), reactivate# lay*ut 3ehavi*r) The vi#ual de#igner pa##e# a false para+eter, indicating that it# n*t nece##ary t* 9*rce an i++ediate reElay*ut *9 the Control) The .ain() +eth*d i# prepended !ith an <#+'+hread> attri3ute, !hich #et# the threading +*del t* I#ingleEthreaded apart+ent)J ,ell di#cu## threading +*del# in chapter #threading#) The la#t +eth*d i# the private +eth*d button7AClic((), !hich !a# attached t* button7# Clic( event pr*perty in the BnitialiTeComponent() +eth*d) -n thi# +eth*d !e directly +anipulate the +ext pr*perty *9 the label7 c*ntr*l) S*+e *3vi*u# *3#ervati*n# a3*ut the *utput *9 the vi#ual de#igner1 it !*rk# !ith c*de that i# 3*th reada3le and Gde#pite the !arningH edita3le, the vi#ual de#igner !*rk# !ithin the +*n*lithic BnitialiTeComponent() e;cept that it create# eventEhandler +eth*d# that are in the #a+e Control cla## 3eing de9ined, and the c*de i#nt ItrickyJ *ther than the <#+'+hread> attri3ute and the $ispose() +eth*d Ga +eth*d !hich i# n*t nece##ary unle## the Control *r *ne *9 it# #u3Ec*ntr*l# c*ntain# n*nE +anaged re#*urce#, a# di#cu##ed in chapter #di#p*#e#H) Le## *3vi*u#ly, taken t*gether, the vi#ual de#igner does i+plicitly i+p*#e Ian *verall *rdering principleJ t* the #y#te+) The vi#ual de#igner c*n#truct# applicati*n# that have a #tatically #tructured >U-, individual identity 9*r c*ntr*l# and handler#, and l*cali7ed eventEhandling) The pr*3le+ !ith thi# architecture, a# e;perienced Ci#ual Ba#ic pr*gra++er# can atte#t, i# that pe*ple can 3e 9**led int* thinking that the de#igner i# Id*ing the *34ect *rientati*nJ 9*r the+ and eventEhandling r*utine# 3ec*+e +*n*lithic pr*cedural c*de chunk#) Thi# can al#* lead t*
615
pe*ple placing the d*+ain l*gic directly in handler#, thu# 9*reg*ing the !h*le c*ncept *9 dec*upling U- l*gic 9r*+ d*+ain l*gic) Thi# i# a pri+e e;a+ple *9 !here #a+ple c*de #uch a# i# #h*!n in article# *r thi# 3**k i# +i#leading) =uth*r# and teacher# !ill generally place d*+ain l*gic inline !ith a c*ntr*l event in *rder t* #ave #pace and #i+pli9y the e;planati*n Ga# !e did !ith the label76+ext I aClic(edb c*deH) H*!ever, in pr*9e##i*nal devel*p+ent, the #tructure *9 pretty +uch any de#ignerEgenerated event handler #h*uld pr*3a3ly 3e1 pri*ate *oid #o!eContro XC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1 ; #o!e:o!ainO$Dect.So!eLogica +*ent013 < Thi# #tructure #eparate# the c*ncept *9 the Control and >U- event# 9r*+ d*+ain *34ect# and l*gical event# and a >U- that u#e# thi# #tructure !ill 3e a3le t* change it# d*+ain l*gic !ith*ut !*rrying a3*ut the di#play detail#) Un9*rtunately, alerting d*+ain *34ect# t* >U- event# i# *nly hal9 the 3attle, the >U- +u#t #*+eh*! re9lect change# in the #tate *9 d*+ain *34ect#) Thi# challenge ha# #everal di99erent #*luti*n#)
7or#;%vent;Control
The 9ir#t >U- architecture !ell di#cu## c*uld 3e called I5*r+EEventE C*ntr*l)J The 5EC architecture u#e# a uni9ied eventEdriven +*del1 >U*34ect# create >U- event# that trigger d*+ain l*gic that create d*+ain event# that trigger >U- l*gic) Thi# i# d*ne 3y creating d*+ain event pr*pertie# and having c*ntr*l# #u3#cri3e t* the+, a# thi# e;a+ple #h*!#1 //:c"T:H+C:o!ain.c# u#ing Sy#te!.'ext.Regu ar+xpre##ion#3 de egate *oid StringSp itUand er0 o$Dect #rc2 Sp itString)rg# arg#13 c a## Sp itString)rg# : +*ent)rg# ; pri*ate Sp itString)rg#01;<
616
Thinking in C
www.ThinkingIn.!et
pu$ ic Sp itString)rg#0#tringJK #tring#1; thi#.#tring# 9 #tring#3 < #tringJK #tring#3 pu$ ic #tringJK String#; get ; return #tring#3< #et ; #tring# 9 *a ue3< < < c a## :o!ainSp itter ; Regex re 9 ne. Regex0&^^#&13 #tringJK #u$#tring#3 pu$ ic e*ent StringSp itUand er String#Sp it3 pu$ ic *oid Sp itString0#tring inStr1; #u$#tring# 9 re.Sp it0inStr13 String#Sp it0 thi#2 ne. Sp itString)rg#0#u$#tring#113 < <///:8 Thi# i# *ur d*+ain *34ect, !hich #plit# a #tring int* it# #u3#tring# !ith the *egex6#plit() +eth*d) ,hen thi# happen#, the $omain#plitter rai#e# a #trings#plit event !ith the ne!ly created #u3#tring# a# an argu+ent t* it# #plit#tring'rgs) *! t* create a ,ind*!# 5*r+ that interact# !ith thi# d*+ain *34ect1 //:c"T:H+C:o!ain2.c# //Co!pi e .ith c#c H+C:o!ain H+C:o!ain2 u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## H+C:o!ain : Hor! ; 'extBox t$ 9 ne. 'extBox013 Button $ 9 ne. Button013 La$e JK a$e #3 :o!ainSp itter do!ainO$Dect 9 ne. :o!ainSp itter013
61#
H+C:o!ain01; t$.Location 9 ne. -oint0"02 "013 t$.'ext 9 &'he 7uic% $ro.n fox&3 $.Location 9 ne. -oint0"P02 "013 $.'ext 9 &Sp it text&3 $.C ic% R9 ne. +*entUand er0thi#._O5+*ent13 do!ainO$Dect.String#Sp it R9 ne. StringSp itUand er0thi#.:o!ain+*ent13 thi#.'ext 9 &Hor!6+*ent6Contro &3 thi#.Contro #.)dd0t$13 thi#.Contro #.)dd0$13 < *oid _O5+*ent0o$Dect #rc2 +*ent)rg# arg#1; do!ainO$Dect.Sp itString0t$.'ext13 < *oid :o!ain+*ent0o$Dect #rc2 Sp itString)rg# arg#1; #tringJK #tring# 9 arg#.String#3 if 0 a$e # !9 nu 1 ; foreach0La$e in a$e #1; thi#.Contro #.Re!o*e0 13 < < a$e # 9 ne. La$e J#tring#.LengthK3 int ro. 9 E03 for 0int i 9 03 i W a$e #.Length3 iRR1 ; a$e #JiK 9 ne. La$e 013 a$e #JiK.'ext 9 #tring#JiK3 a$e #JiK.Location 9 ne. -oint0"002 ro.13 ro. R9 203 < thi#.Contro #.)ddRange0 a$e #13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. H+C:o!ain0113 < <///:8
61&
Thinking in C
www.ThinkingIn.!et
O3vi*u#ly, !e didnt u#e Ci#ual Studi*# de#igner t* 3uild thi# 9*r+ 3ut have reverted t* !*rking directly 9r*+ !ithin a c*de edit*r) Our :&C$omain 9*r+ c*ntain# a te;t 3*;, a 3utt*n, an array *9 La3el c*ntr*l#, and a re9erence t* $omain#plitter) The 9ir#t part *9 the :&$omain() c*n#truct*r #peci9ie# the l*cati*n and te;t *9 the te;t 3*; and 3utt*n) ,e then #peci9y t!* delegate#1 VB&vent i# a delegate *9 type &vent"andler and i# attached t* the 3utt*n# Clic( event pr*perty and $omain&vent i# *9 type #tring#plit"andler and i# attached t* the $omain#plitter# #tring#plit event) The 9inal part *9 the c*n#truct*r add# the te;t3*; and 3utt*n t* the 9*r+) ,hen the 3utt*n i# pre##ed, the Clic( delegate inv*ke# the VB&vent() +eth*d, !hich pa##e# the te;t *9 the te;t3*; t* the domain1b)ect6#plit#tring() l*gical event) Thi# in turn !ill rai#e a #tring#plit event that call# 3ack t* the $omain&vent() +eth*d) The $omain&vent() +eth*d create# and di#play# a la3el 9*r each *9 the individual #tring#) The 9ir#t ti+e $omain&vent() i# called, the labels array !ill 3e null 3ecau#e !e d* n*t initiali7e it in the c*n#truct*r) -9, th*ugh, labels i# n*t null, !e re+*ve the e;i#ting la3el# 9r*+ the Controls c*llecti*n) ,e initiali7e the labels array t* 3e a3le t* h*ld a #u99icient nu+3er *9 re9erence# and then initiali7e individual la3el# !ith the appr*priate string and a ne! p*#iti*n) Once all the labels are created, Controls6'dd*ange() add# the+ t* the :&C$omain# client area) The 5EC architecture i# vulnera3le t* the recur#ive l**p# pr*3le+# di#cu##ed previ*u#ly) -9 a d*+ain event trigger# a >U- handler !hich in turn activate# the relevant d*+ain event, the #y#te+ !ill recur#e and cra#h G!hen dealing !ith >U-#, the cra#h e;cepti*n typically inv*lve# #tarvati*n *9 #*+e ,ind*!# re#*urce 3e9*re the #tack *ver9l*!#H) H*!ever, 5EC i# very #traight9*r!ard P alth*ugh in the tiny pr*gra+# that illu#trate a 3**k it i# +*re c*+ple; than 4u#t putting d*+ain l*gic directly int* a >U- event handler, in practice it !ill very likely 3e le## c*+ple; and pr*vide# 9*r a very clean and under#tanda3le #eparati*n *9 >U- and d*+ain l*gic)
61'
Presentation;)+straction; Control
=n alternative >U- architecture t* 5EC pr*p*#e# that the !h*le c*ncept *9 #eparating d*+ain l*gic 9r*+ Control# i# *vere+pha#i7ed) -n thi# vie!, 9le;i3ility i# achieved 3y encap#ulating all the di#play, c*ntr*l, and d*+ain l*gic a##*ciated !ith a relatively 9ineEgrained a3#tracti*n) >r*up# *9 the#e #el9Ec*ntained c*+p*nent# are c*+3ined t* 3uild c*ar#erE grained a3#tracti*n# G!ith c*rre#p*ndingly +*re c*+ple; di#play#, perhap# panel# and entire 9*r+#H) The#e c*ar#erEgrained a3#tracti*n# are gathered t*gether t* +ake pr*gra+#) -n the P=C architecture, the l*!e#tElevel *34ect# are likely t* 3e #u3type# *9 #peci9ic c*ntr*l#Q 9*r in#tance, a Button that encap#ulate# a 3it *9 d*+ain l*gic relating t* a trigger *r #!itch) AidElevel *34ect# +ay de#cend 9r*+ VserControl Ge##entially, an inter9aceEle## ControlH and !*uld encap#ulate di#crete chunk# *9 3u#ine## l*gic) HigherElevel *34ect# !*uld likely de#cend 9r*+ :orm and are likely t* encap#ulate all the l*gic a##*ciated !ith a particular #cenari* *r u#eEca#e) -n thi# e;a+ple, !e have a type de#cended 9r*+ Button that kn*!# !hether it i# *n *r *99 and a type de#cended 9r*+ !anel that c*ntain# the#e +wo#tate 3utt*n# and kn*!# i9 all the +wo#tate# !ithin it are in #tate IOnJ1 //:c"T:-)C.c# //-re#entation6)$#traction6Contro u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!3 c a## '.oState : Button; #tatic int in#tanceCounter 9 03 int id 9 in#tanceCounterRR3 interna '.oState01; thi#.'ext 9 State3 Sy#te!.+*entUand er hnd r 9
6)(
Thinking in C
www.ThinkingIn.!et
ne. Sy#te!.+*entUand er0$uttonC ic%13 thi#.C ic% R9 hnd r3 < $oo #tate 9 true3 pu$ ic #tring State; get ; return 0#tate 99 true1 Y &On& : &Off&3 < #et; #tate 9 0*a ue 99 &On&1 Y true : fa #e3 OnStateChanged013 < < pri*ate *oid $uttonC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1; changeState013 < pu$ ic *oid changeState01; #tate 9 !#tate3 OnStateChanged013 < pu$ ic *oid OnStateChanged01; Sy#te!.Con#o e.VriteLine0 &'.oState id & R id R & #tate changed&13 thi#.'ext 9 State3 < < c a## Chri#t!a#'ree : -ane ; $oo a On3 interna $oo ) On; get ; return a On3 < < pu$ ic Chri#t!a#'ree01; '.oState t# 9 ne. '.oState013 t#.Location 9 ne. -oint0"02 "013
6)1
'.oState t#2 9 ne. '.oState013 t#2.Location 9 ne. -oint0"202 "013 )dd0t#13 )dd0t#213 Bac%Co or 9 Co or._reen3 < pu$ ic *oid )dd0'.oState c1; Contro #.)dd0c13 c.C ic% R9 ne. +*entUand er0 thi#.'.oC ic%Changed13 < pu$ ic *oid )ddRange0'.oStateJK ca1; foreach0'.oState t# in ca1; t#.C ic% R9 ne. +*entUand er0 thi#.'.oC ic%Changed13 < Contro #.)ddRange0ca13 < pu$ ic *oid '.oC ic%Changed0 O$Dect #rc2 +*ent)rg# a1; a On 9 true3 foreach0Contro c in Contro #1; '.oState t# 9 c a# '.oState3 if0t#.State !9 &On&1; a On 9 fa #e3 < < if0a On1; Bac%Co or 9 Co or._reen3 <e #e; Bac%Co or 9 Co or.Red3 < < < c a## -)CHor! : Hor! ; Chri#t!a#'ree p" 9 ne. Chri#t!a#'ree013 Chri#t!a#'ree p2 9 ne. Chri#t!a#'ree013
6))
Thinking in C
www.ThinkingIn.!et
pu$ ic -)CHor!01; C ientSiMe 9 ne. SiMe0EP02 20013 'ext 9 &+*ent# @ Gode #&3 p".Location 9 ne. -oint0"02"013 p2.Location 9 ne. -oint02002 "013 Contro #.)dd0p"13 Contro #.)dd0p213 < #tatic *oid Gain01; )pp ication.Run0ne. -)CHor!0113 < < ///:8 ,hen run, i9 y*u #et 3*th the 3utt*n# !ithin an individual Christmas+ree panel t* IOn,J the Christmas+ree# 3ackgr*und c*l*r !ill 3ec*+e green, *ther!i#e, the 3ackgr*und c*l*r !ill 3e red) The !'C:orm kn*!# n*thing a3*ut the +wo#tate# !ithin the Christmas+ree) ,e c*uld Gand indeed it !*uld pr*3a3ly 3e l*gicalH change +wo#tate 9r*+ de#cending 9r*+ Button t* de#cending 9r*+ Chec(box and +wo#tate6#tate 9r*+ a string t* a bool and it !*uld +ake n* di99erence t* the !'C:orm that c*ntain# the t!* in#tance# *9 Christmas+ree) Pre#entati*nE=3#tracti*nEC*ntr*l i# *9ten the 3e#t architecture 9*r !*rking !ith ) ET) -t# killer advantage i# that it pr*vide# an encap#ulated c*+p*nent) = c*+p*nent i# a #*9t!are +*dule that can 3e depl*yed and c*+p*#ed int* *ther c*+p*nent# without source9code modi$ication) Ci#ual Ba#ic pr*gra++er# have en4*yed the 3ene9it# *9 #*9t!are c*+p*nent# 9*r +*re than a decade, !ith th*u#and# *9 thirdE party c*+p*nent# availa3le) Ci#ual Studi* ) ET #hip# !ith a 9e! c*+p*nent# that are at a higher level than 4u#t encap#ulating #tandard c*ntr*l#, 9*r in#tance, c*+p*nent# !hich encap#ulate =?O and an*ther !hich encap#ulate# the Cry#tal Rep*rt# t**l#) P=C c*+p*nent# need n*t really 3e !ritten a# a #ingle cla##Q rather, a #ingle Control cla## +ay pr*vide a #ingle public vie! *9 a +*re c*+ple;
6)3
na+e#pace !h*#e +e+3er# are n*t vi#i3le t* the *ut#ide !*rld) Thi# i# called the +aIade de#ign pattern) The pr*3le+ !ith P=C i# that it# hard !*rk t* create a decent c*+p*nent) Our Christmas+ree c*+p*nent i# h*rri3le P it d*e#nt aut*+atically place the internal +wo#tate# rea#*na3ly, it d*e#nt re#i7e t* 9it ne! +wo#tate#, it d*e#nt e;p*#e 3*th l*gical and >U- event# and pr*pertie#L The li#t g*e# *n and *n) Reu#e i# the great un9ul9illed pr*+i#e *9 *34ect *rientati*n1 I?r*p a c*ntr*l *n the 9*r+, #et a c*uple *9 pr*pertie#, and 3**+K :*uve g*t a payr*ll #y#te+)J But the reality *9 devel*p+ent i# that at lea#t 6$^ *9 y*ur ti+e i# a3#*lutely c*ntr*lled 3y the pre##ing i##ue# *9 the current devel*p+ent cycle and there i# little *r n* ti+e t* #pend *n detail# n*t related t* the ta#k at hand) Plu#, it# di99icult en*ugh t* create an e99ective >U- !hen y*u have direct acce## t* y*ur endEu#er#Q creating an e99ective >U- c*+p*nent that !ill 3e appr*priate in #ituati*n# that havent yet ari#en i# al+*#t i+p*##i3le) everthele##, Ci#ual Studi* ) ET +ake# it #* ea#y t* create a reu#a3le c*+p*nent G4u#t c*+pile y*ur c*+p*nent t* a )?LL and y*u can add it t* the T**l3arKH that y*u #h*uld al!ay# at lea#t c*n#ider P=C 9*r y*ur >Uarchitecture) *te1 c*ntr*l cant 3e in t!* c*ntr*l c*llecti*n# at *nce)
@odel;8iew;Controller
A*delECie!EC*ntr*ller, c*++*nly re9erred t* #i+ply a# IACC,J !a# the 9ir#t !idely kn*!n architectural pattern 9*r dec*upling the graphical u#er inter9ace 9r*+ underlying applicati*n l*gic) Un9*rtunately, +any pe*ple c*n9u#e ACC !ith any architecture that #eparate# pre#entati*n l*gic 9r*+ d*+ain l*gic) S* !hen #*+e*ne #tart# talking a3*ut ACC, it# !i#e t* all*! 9*r Duite a 3it *9 i+preci#i*n) -n ACC, the A*del encap#ulate# the #y#te+# l*gical 3ehavi*r and #tate, the Cie! reDue#t# and re9lect# that #tate *n the di#play, and the C*ntr*ller interpret# l*!Elevel input# #uch a# +*u#e and key3*ard #tr*ke#, re#ulting in c*++and# t* either the A*del *r the Cie!)
6)4
Thinking in C
www.ThinkingIn.!et
ACC trade# *99 a l*t *9 #tatic #tructure EE the de9initi*n *9 *34ect# 9*r each *9 the vari*u# re#p*n#i3ilitie# P 9*r the advantage *9 3eing a3le t* independently vary the vie! and the c*ntr*ller) Thi# i# n*t +uch *9 an advantage in ,ind*!# pr*gra+#, !here the vie! i# al!ay# a 3it+apped t!*Edi+en#i*nal di#play and the c*ntr*ller i# al!ay# a c*+inati*n *9 a key3*ard and a +*u#eElike p*inting device) H*!ever, USB# !ide#pread #upp*rt ha# already led t* intere#ting ne! c*ntr*ller# and the n*tE#*E di#tant 9uture !ill 3ring 3*th v*ice and ge#ture c*ntr*l and Ihy3rid realityJ di#play# t* #ea+le##ly integrate c*+puterEgenerated data int* real vi#i*n Ge)g), gla##e# that #uperi+p*#e arr*!# and la3el# *n realityH) -9 y*u happen t* 3e lucky en*ugh t* 3e !*rking !ith #uch advanced techn*l*gie#, ACC +ay 3e 4u#t the thing) Even i9 n*t, it# !*rth di#cu##ing 3rie9ly a# an e;a+ple *9 dec*upling >U- c*ncern# taken t* the l*gical e;tre+e) -n *ur e;a+ple, *ur d*+ain #tate i# #i+ply an array *9 B**lean value#Q !e !ant the di#play t* #h*! the#e value# a# 3utt*n# and di#play, in the title 3ar, !hether all the value# are true *r !hether #*+e are 9al#e1 //:c"T:GNC.c# u#ing Sy#te!3 u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.:ra.ing3 c a## Gode ; interna $oo JK a interna Gode 01; Rando! r 9 ne. int iBoo # 9 2 a Boo # 9 ne. for0int i 9 03 a Boo #JiK < < < c a## Nie. : Hor!; Gode !ode 3 ButtonJK $utton#3 Boo #3 Rando!013 R r.Cext0T13 $oo JiBoo #K3 i W iBoo #3 iRR1; 9 r.Cext:ou$ e01 Z 0.P3
6)5
!2 Contro
er c1;
int $uttonCount 9 !.a Boo #.Length3 $utton# 9 ne. ButtonJ$uttonCountK3 C ientSiMe 9 ne. SiMe0T002 P0 R $uttonCount = P013 for0int i 9 03 i W $uttonCount3 iRR1; $utton#JiK 9 ne. Button013 $utton#JiK.Location 9 ne. -oint0"02 P R i = P013 c.GatchContro 'oGode 0$utton#JiK2 i13 $utton#JiK.C ic% R9 ne. +*entUand er0c.C ic%Uand er13 < Ref ectGode 013 Contro #.)ddRange0$utton#13 < interna *oid Ref ectGode 01; $oo a )re'rue 9 true3 for0int i 9 03 i W !ode .a Boo #.Length3 iRR1; $utton#JiK.'ext 9 !ode .a Boo #JiK.'oString013 if0!ode .a Boo #JiK 99 fa #e1; a )re'rue 9 fa #e3 < < if0a )re'rue1; 'ext 9 &) are true&3 <e #e; 'ext 9 &So!e are not true&3 < < < c a## Contro er; Gode !ode 3 Nie. *ie.3 Contro JK *ie.Co!ponent#3
6)6
Thinking in C
www.ThinkingIn.!et
Contro er0Gode !1; !ode 9 !3 *ie.Co!ponent# 9 ne. Contro J!.a < interna *oid GatchContro 'oGode 0Button $2 int index1; *ie.Co!ponent#JindexK 9 $3 < interna *oid )ttachNie.0Nie. *1; thi#.*ie. 9 *3 <
Boo #.LengthK3
interna *oid C ic%Uand er 0O$Dect #rc2 +*ent)rg# ea1; //Godify !ode in re#pon#e to input int !ode 5ndex 9 )rray.5ndexOf0*ie.Co!ponent#2 #rc13 !ode .a Boo #J!ode 5ndexK 9 !!ode .a Boo #J!ode 5ndexK3 //Ua*e *ie. ref ect !ode *ie..Ref ectGode 013 < pu$ ic #tatic *oid Gain01; Gode ! 9 ne. Gode 013 Contro er c 9 ne. Contro er0!13 Nie. * 9 ne. Nie.0!2 c13 c.)ttachNie.0*13 )pp ication.Run0*13 < <///:8 The .odel cla## ha# an array *9 bools that are rand*+ly #et in the .odel c*n#truct*r) 5*r de+*n#trati*n purp*#e#, !ere e;p*#ing the array directly, 3ut in real li9e the #tate *9 the .odel !*uld 3e re9lected in it# entire ga+ut *9 pr*pertie#) The Hiew *34ect i# a :orm that c*ntain# a re9erence t* a .odel and it# r*le i# #i+ply t* re9lect the #tate *9 that .odel) The Hiew() c*n#truct*r
6)#
lay# *ut h*! thi# particular vie! i# g*ing t* d* that P it deter+ine# h*! +any bool# are in the .odel# allBools array and initiali7e# a Button<> array *9 the #a+e #i7e) 5*r each bool in allBools, it create# a c*rre#p*nding Button, and a##*ciate# thi# particular a#pect *9 the .odel# #tate Gthe inde; *9 thi# particular boolH !ith thi# particular a#pect *9 the Hiew Gthi# particular ButtonH) -t d*e# thi# 3y calling the Controller# .atchControl+o.odel( ) +eth*d and 3y adding t* the Button# Clic( event pr*perty a re9erence t* the Controller# Clic("andler( )) Once the Hiew ha# initiali7ed it# Controls, it call# it# *!n *eflect.odel( ) +eth*d) Hiew# *eflect.odel( ) +eth*d iterate# *ver all the bool# in .odel, #etting the te;t *9 the c*rre#p*nding 3utt*n t* the value *9 the B**lean 6 -9 all are true, the title *9 the :orm i# changed t* I=ll are true,J *ther!i#e, it declare# that IS*+e are 9al#e)J The Controller *34ect ulti+ately need# re9erence# t* 3*th the .odel and t* the Hiew, and the Hiew need# a re9erence t* 3*th the .odel and the Controller) Thi# lead# t* a little 3it *9 c*+ple;ity in the initiali7ati*n #h*!n in the .ain( ) +eth*dQ the .odel( ) i# created !ith n* re9erence# t* anything Gthe .odel i# acted up*n 3y the Controller and re9lected 3y the Hiew, the .odel it#el9 never need# t* call +eth*d# *r pr*pertie# in th*#e *34ect#H) The Controller i# then created !ith a re9erence t* the .odel) The Controller( ) c*n#truct*r #i+ply #t*re# a re9erence t* the .odel and initiali7e# an array *9 Control# t* #u99icient #i7e t* re9lect the #i7e *9 the .odel6allBools array) =t thi# p*int, the Controller6Hiew re9erence i# #till null, #ince the Hiew ha# n*t yet 3een initiali7ed) Back in the .ain( ) +eth*d, the 4u#tEcreated Controller i# pa##ed t* the Hiew( ) c*n#truct*r, !hich initiali7e# the Hiew a# de#cri3ed previ*u#ly) Once the Hiew i# initiali7ed, the Controller# 'ttachHiew( ) +eth*d #et# the re9erence t* the Hiew, c*+pleting the Controller# initiali7ati*n) G:*u c*uld a# ea#ily d* the *pp*#ite, creating a Hiew !ith 4u#t a re9erence t* the .odel, creating a Controller !ith a re9erence t* the Hiew and the .odel, and then 9ini#h the Hiew# initiali7ati*n !ith an 'ttachController( ) +eth*d)H
6)&
Thinking in C
www.ThinkingIn.!et
?uring the Hiew5# c*n#truct*r, it called the Controller# .atchControl+o.odel( ) +eth*d, !hich !e can n*! #ee #i+ply #t*re# a re9erence t* a Button in the viewComponents< > array) The Controller i# re#p*n#i3le 9*r interpreting event# and cau#ing update# t* the .odel and Hiew a# appr*priate) Clic("andler( ) i# called 3y the vari*u# Button# in the Hiew !hen they are clicked) The *riginating Control i# re9erenced in the src +eth*d argu+ent, and 3ecau#e the inde; in the viewComponents< > array !a# de9ined t* c*rre#p*nd t* the inde; *9 the .odel# allBools< > array, !e can learn !hat a#pect *9 the .odel# #tate !e !i#h t* update 3y u#ing the #tatic +eth*d 'rray6Bndex1f( )) ,e change the B**lean t* it# *pp*#ite u#ing the K *perat*r and then, having changed the .odel# #tate, !e call Hiew# *eflect.odel( ) +eth*d t* keep everything in #ynchr*ny) The clear delineati*n *9 dutie# in ACC i# appealing P the Hiew pa##ively re9lect# the .odel, the Controller +ediate# update#, and the .odel i# re#p*n#i3le *nly 9*r it#el9) :*u can have +any Hiew cla##e# that re9lect the #a+e .odel G#ay, *ne #h*!ing a graph *9 value#, the *ther #h*!ing a li#tH and dyna+ically #!itch 3et!een the+) H*!ever, the #tructural c*+ple;ity *9 ACC i# a c*n#idera3le 3urden and i# di99icult t* IintegrateJ !ith the Ci#ual ?e#igner t**l)
La5out
*! that !eve di#cu##ed the vari*u# architectural *pti*n# that #h*uld 3e *9 +a4*r i+p*rt in any real >U- de#ign di#cu##i*n, !ere g*ing t* +*ve 3ack t*!ard# the e;pedient I?* a# !e #ay, n*t a# !e d*J +*de *9 c*+3ining l*gic, event c*ntr*l, and vi#ual di#play in the #a+ple pr*gra+#) -t !*uld #i+ply c*n#u+e t** +uch #pace t* #eparate d*+ain l*gic int* #eparate cla##e# !hen, u#ually, *ur e;a+ple pr*gra+# are d*ing n*thing 3ut !riting *ut #i+ple line# *9 te;t t* the c*n#*le *r de+*n#trating the 3a#ic# *9 #*+e #i+ple !idget) =n*ther area !here the #a+ple pr*gra+# di99er +arkedly 9r*+ pr*9e##i*nal c*de i# in the lay*ut *9 Control#) S* 9ar, !e have u#ed the Location pr*perty *9 a Control, !hich deter+ine# the upperEle9t c*rner *9 this Control in the client area *9 it# c*ntaining Control G*r, in the
6)'
ca#e *9 a :orm, the ,ind*!# di#play c**rdinate# *9 it# upperEle9t c*rnerH) A*re 9reDuently, y*u !ill u#e the $oc( and 'nchor pr*pertie# *9 a Control t* l*cate a Control relative t* *ne *r +*re edges *9 the c*ntainer in !hich it re#ide#) The#e pr*pertie# all*! y*u t* create Control# !hich pr*perly re#i7e the+#elve# in re#p*n#e t* change# in !ind*!# #i7e) -n *ur e;a+ple# #* 9ar, re#i7ing the c*ntaining 5*r+ d*e#nt change the Control p*#iti*n#) That i# 3ecau#e 3y de9ault, Control# have an 'nchor pr*perty #et t* the 'nchor#tyles value# +op and Left G'nchor#tyles are 3it!i#e c*+3ina3leH) -n thi# e;a+ple, a 3utt*n +*ve# relative t* the *pp*#ite c*rner1 //:c"T:)nchorNa ue#.c# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.:ra.ing3 c a## )nchorNa ue#: Hor!; )nchorNa ue#01; Button $ 9 ne. Button013 $.Location 9 ne. -oint0"02 "013 $.)nchor 9 )nchorSty e#.Right S )nchorSty e#.Botto!3 Contro #.)dd0$13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. )nchorNa ue#0113 < <///:8 -9 y*u c*+3ine *pp*#ite 'nchor#tyles GLe9t and Right, T*p and B*tt*+H the Control !ill re#i7e) -9 y*u #peci9y 'nchor#tyles),one, the c*ntr*l !ill +*ve hal9 the di#tance *9 the c*ntaining area# change in #i7e) Thi# e;a+ple #h*!# the#e t!* type# *9 3ehavi*r1 //:c"T:)nchorRe#iMing.c# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.:ra.ing3
63(
Thinking in C
www.ThinkingIn.!et
c a## )nchorRe#iMing: Hor!; )nchorRe#iMing01; Button $ 9 ne. Button013 $.Location 9 ne. -oint0"02 "013 $.)nchor 9 )nchorSty e#.Left S )nchorSty e#.Right S )nchorSty e#.'op3 $.'ext 9 &Left S Right S 'op&3 Contro #.)dd0$13 Button $2 9 ne. Button013 $2.Location 9 ne. -oint0"002 "013 $2.)nchor 9 )nchorSty e#.Cone3 $2.'ext 9 &Cot anchored&3 Contro #.)dd0$213 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. )nchorRe#iMing0113 < <///:8 -9 y*u run thi# e;a+ple and +anipulate the #creen, y*ull #ee t!* unde#ira3le 3ehavi*r#1 b can *3#cure b8, and b8 can 9l*at *99 the page) ,ind*!# 5*r+# lay*ut 3ehavi*r trade# *99 tr*u3le#*+e 3ehavi*r like thi# 9*r it# #traight9*r!ard +*del) =n alternative +echani#+ 3a#ed *n cell#, #uch a# that u#ed in HTAL *r #*+e *9 "ava# Layout.anagers, +ay 3e +*re r*3u#t in av*iding the#e type# *9 tr*u3le, 3ut any*ne !h*# tried t* get a c*+ple; cellE3a#ed U- t* re#i7e the !ay they !i#h i# likely t* agree !ith ,ind*!# 5*r+# phil*#*phyK = pr*perty c*+ple+entary t* 'nchor i# $oc() The $oc( pr*perty +*ve# the c*ntr*l 9lu#h again#t the #peci9ied edge *9 it# c*ntainer, and re#i7e# the c*ntr*l t* 3e the #a+e #i7e a# that edge) -9 +*re than *ne c*ntr*l in a client area i# #et t* $oc( t* the #a+e edge, the c*ntr*l# !ill lay*ut #ideE3yE#ide in the re-erse o$ the order in !hich they !ere added t* the c*ntaining Controls array Gtheir re-erse ;9orderH) The $oc( pr*perty *verride# the Location value) -n thi# e;a+ple, t!* 3utt*n# are created and d*cked t* the le9t #ide *9 their c*ntaining :orm)
631
//:c"T::oc%.c# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.:ra.ing3 c a## :oc%: Hor!; :oc%01; Button $" 9 ne. Button013 $".:oc% 9 :oc%Sty e.Left3 $".'ext 9 &Button "&3 Contro #.)dd0$"13 Button $2 9 ne. Button013 $2.:oc% 9 :oc%Sty e.Left3 $2.'ext 9 &Button2&3 Contro #.)dd0$213 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. :oc%0113 < <///:8 ,hen y*u run thi#, y*ull #ee that b appear# to the right *9 b8 3ecau#e it !a# added t* $oc(# Controls 2e$ore b86 $oc(#tyle6:ill #peci9ie# that the Control !ill e;pand t* 9ill the client area 9r*+ the center t* the li+it# all*!ed 3y *ther $oc(ed Controls) $oc(#tyle6:ill !ill c*ver n*nE$oc(ed Controls that have a l*!er 7E *rder, a# thi# e;a+ple #h*!#1 //:c"T::oc%Hi .c# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.:ra.ing3 c a## :oc%Hi : Hor!; :oc%Hi 01; //Lo.er M6order Button *i#i$ e 9 ne. Button013 *i#i$ e.'ext 9 &Ni#i$ e&3 *i#i$ e.Location 9 ne. -oint0"02 "013 Contro #.)dd0*i#i$ e13
63)
Thinking in C
www.ThinkingIn.!et
//Vi co*er &5n*i#i$ e& Button doc%ed 9 ne. Button013 doc%ed.'ext 9 &:oc%ed&3 doc%ed.:oc% 9 :oc%Sty e.Hi 3 Contro #.)dd0doc%ed13 //Uigher M6order2 gonna' $e in*i#i$ e Button in*i#i$ e 9 ne. Button013 in*i#i$ e.'ext 9 &5n*i#i$ e&3 in*i#i$ e.Location 9 ne. -oint0"002 "0013 Contro #.)dd0in*i#i$ e13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. :oc%Hi 0113 < <///:8 ?evel*ping c*+ple; lay*ut# that lay the+#elve# *ut pr*perly !hen re#i7ed i# a challenge 9*r any #y#te+) ,ind*!# 5*r+# #traight9*r!ard +*del *9 c*ntain+ent, Location, 'nchor, and $oc( i# e#pecially #uited 9*r the P=C >U- architecture de#cri3ed previ*u#ly) Rather than trying t* create a +*n*lithic chunk *9 l*gic that atte+pt# t* re#i7e and rel*cate the hundred# *r d*7en# *9 !idget# that +ight c*+pri#e a c*+ple; U-, the P=C architecture !*uld encap#ulate the l*gic !ithin individual cu#t*+ c*ntr*l#)
(on;Code 6esources
,ind*!# 5*r+# !*uldnt 3e +uch *9 a graphical u#er inter9ace li3rary i9 it did n*t #upp*rt graphic# and *ther +edia) But !hile it# ea#y t* #peci9y a Button# l**k and 9eel !ith *nly a 9e! line# *9 c*de, i+age# are inherently dependent *n 3inary data #t*rage) -t# n*t #urpri#ing that y*u can l*ad an i+age int* a ,ind*!# 5*r+ 3y u#ing a #tream *r a 9ilena+e, a# thi# e;a+ple de+*n#trate#1 //:c"T:Si!p e-icture.c# //Loading i!age# fro! fi e #y#te!
633
c a## Si!p e-icture : Hor! ; pu$ ic #tatic *oid Gain0#tringJK arg#1; Si!p e-icture #p 9 ne. Si!p e-icture0arg#J0K13 )pp ication.Run0#p13 < Si!p e-icture0#tring fCa!e1; -ictureBox p$ 9 ne. -ictureBox013 p$.5!age 9 5!age.Hro!Hi e0fCa!e13 p$.:oc% 9 :oc%Sty e.Hi 3 p$.SiMeGode 9 -ictureBoxSiMeGode.Stretch5!age3 Contro #.)dd0p$13 int i!gVidth 9 p$.5!age.Vidth3 int i!gUeight 9 p$.5!age.Ueight3 thi#.C ientSiMe 9 ne. SiMe0i!gVidth2 i!gUeight13 < <///:8 The .ain( ) +eth*d take# the 9ir#t c*++andEline argu+ent a# a path t* an i+age G9*r in#tance1 ISi+plePicture c1d!ind*!#dcl*ud#)3+pJH and pa##e# that path t* the #imple!icture( ) c*n#truct*r) The +*#t c*++*n Control u#ed t* di#play a 3it+ap i# the !ictureBox c*ntr*l, !hich ha# an Bmage pr*perty) The #tatic +eth*d Bmage6:rom:ile( ) generate# an Bmage 9r*+ the given path Gthere i# al#* an Bmage6:rom#tream( ) #tatic +eth*d !hich pr*vide# general acce## t* all the p*##i3le #*urce# *9 i+age dataH) The !ictureBox# $oc( pr*perty i# #et t* $oc(style6:ill and the Client#iTe *9 the 9*r+ i# #et t* the #i7e *9 the Bmage) ,hen y*u run thi# pr*gra+, the #imple!icture 9*r+ !ill #tart at the #a+e #i7e *9 the i+age) Becau#e pb6#iTe.ode !a# #et t* #tretchBmage, h*!ever, y*u
634
Thinking in C
www.ThinkingIn.!et
can re#i7e the 9*r+ and the i+age !ill #tretch *r #hrink appr*priately) =lternate !ictureBox#iTe.ode value# are ,ormal G!hich clip# the Bmage t* the !ictureBox# #i7eH, 'uto#iTe G!hich re#i7e# the !ictureBox t* acc*++*date the Bmage# #i7eH, and CenterBmage6 L*ading re#*urce# 9r*+ e;ternal 9ile# i# certainly appr*priate in +any circu+#tance#, e#pecially !ith i#*lated #t*rage G#re9#H, !hich give# y*u a perEu#er, c*n#i#tent virtual 9ile #y#te+) H*!ever, real applicati*n# !hich are intended 9*r internati*nal c*n#u+pti*n reDuire +any re#*urce# l*cali7ed t* the current culture P la3el#, +enu na+e#, and ic*n# +ay all have t* change) The ) ET 5ra+e!*rk pr*vide# a #tandard +*del 9*r e99iciently #t*ring #uch re#*urce# and l*ading the+) A*+entarily putting a#ide the Due#ti*n *9 h*! #uch re#*urce# are created, retrieving the+ i# the !*rk *9 the *esource.anager cla##) Thi# e;a+ple #!itche# l*cali7ed la3el# indicating I+anJ and I!*+an)J //:c"T:5nternationa .c# u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Re#ource#3 u#ing Sy#te!._ o$a iMation3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## 5nternationa : Hor!; Re#ourceGanager r!3 La$e !an3 La$e .o!an3 pu$ ic 5nternationa 01; r! 9 ne. Re#ourceGanager0typeof05nternationa 113 RadioButton eng 9 ne. RadioButton013 eng.Chec%ed 9 true3 eng.Location 9 ne. -oint0"02 "013 eng.'ext 9 &)!erican&3 eng.Chec%edChanged R9 ne. +*entUand er0LoadOSRe#ource#13 RadioButton #.a 9 ne. RadioButton013 #.a.Location 9 ne. -oint0"02 T013
635
#.a.'ext 9 &S.ahi i&3 #.a.Chec%edChanged R9 ne. +*entUand er0LoadS.ahi iRe#ource#13 !an 9 ne. La$e 013 !an.Location 9 ne. -oint0"02 ?013 !an.'ext 9 &Gan&3 .o!an 9 ne. La$e 013 .o!an.Location 9 ne. -oint0"02 >013 .o!an.'ext 9 &Vo!an&3 Contro #.)ddRange0ne. Contro JK ; eng2 #.a2 !an2 .o!an<13 'ext 9 &5nternationa &3 < pu$ ic *oid LoadOSRe#ource# 0O$Dect #rc2 +*ent)rg# a1; if 0 00RadioButton1#rc1.Chec%ed 99 true1 ; Re#ourceSet r# 9 r!._etRe#ourceSet0 ne. Cu ture5nfo0&en6OS&12 true2 true13 SetLa$e #0r#13 < < pu$ ic *oid LoadS.ahi iRe#ource# 0O$Dect #rc2 +*ent)rg# a1; if 000RadioButton1#rc1.Chec%ed 99 true1 ; Re#ourceSet r# 9 r!._etRe#ourceSet0 ne. Cu ture5nfo0&#.&12 true2 true13 SetLa$e #0r#13 < < pri*ate *oid SetLa$e #0Re#ourceSet r#1; !an.'ext 9 r#._etString0&Gan&13 .o!an.'ext 9 r#._etString0&Vo!an&13
636
Thinking in C
www.ThinkingIn.!et
< pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. 5nternationa 0113 < < Here, !e !i#h t* create an applicati*n !hich u#e# la3el# in a l*cal culture Ga culture i# +*re #peci9ic than a languageQ 9*r in#tance, there i# a di#tincti*n 3et!een the culture *9 the United State# and the culture *9 the United Ningd*+H) The 3a#ic re9erence# !ell need are t* *esource.anager rm, !hich !ell l*ad t* 3e cultureE#peci9ic, and t!* la3el# 9*r the !*rd# IAanJ and I,*+an)J The 9ir#t line *9 the Bnternational c*n#truct*r initiali7e# rm t* 3e a re#*urce +anager 9*r the #peci9ied type) = *esource.anager i# a##*ciated !ith a #peci9ic type 3ecau#e ) ET u#e# a Ihu3 and #p*keJ +*del 9*r +anaging re#*urce#) The Ihu3J i# the a##e+3ly that c*ntain# the c*de *9 a #peci9ic type) The I#p*ke#J are 7er* *r +*re satellite assem2lies that c*ntain the re#*urce# 9*r #peci9ic culture#, and the *esource.anager i# the link that a##*ciate# a type Ga Ihu3JH !ith it# I#p*ke#J) Bnternational( ) then #h*!# the u#e *9 radi* 3utt*n# in ,ind*!# 5*r+#) The +*del i# #i+ple1 all radi* 3utt*n# !ithin a c*ntainer are +utually e;clu#ive) T* +ake +ultiple #et# *9 radi* 3utt*n# !ithin a #ingle 9*r+, y*u can u#e a roupBox *r !anel) Bnternational ha# t!* *adioButton#, eng ha# it# Chec(ed pr*perty #et t* true, and, !hen that pr*perty change#, the Load&nglish*esources +eth*d !ill 3e called) *adioButton swa i# #i+ilarly c*n9igured t* call Load#wahili*esources( ) and i# n*t initially checked) By de9ault, the man and woman la3el# are #et t* a hardEc*ded value) The Load"""*esources( ) +eth*d# are #i+ilarQ they check i9 their #*urce *adioButton i# checked G#ince they are handling the Chec(edChange event, the +eth*d# !ill 3e called !hen their #*urce 3ec*+e# deEchecked a# !ellH) -9 their #*urce is #et, the *esource.anager l*ad# *ne *9 the I#p*keJ *esource#et *34ect#) The *esource#et i# a##*ciated !ith a particular CultureBnfo in#tance, !hich i# initiali7ed !ith a language tag string c*+pliant !ith -ET5 R5C
63#
0%.. Gy*u can 9ind a li#t *9 #tandard c*de# in the ) ET 5ra+e!*rk d*cu+entati*n and read the R5C at http1<<!!!)iet9)*rg<r9c<r9c0%..)t;tH) The et*esource#et( ) +eth*d al#* take# t!* bools, the 9ir#t #peci9ying i9 the *esource#et #h*uld 3e l*aded i9 it d*e# n*t yet e;i#t in +e+*ry, and the #ec*nd #peci9ying i9 the *esource.anager #h*uld try t* l*ad Iparent#J *9 the culture i9 the #peci9ied CultureBnfo d*e# n*t !*rkQ 3*th *9 the#e bool# !ill al+*#t al!ay# 3e true) Once the *esource#et i# retrieved, it i# u#ed a# a para+eter t* the #etLabels( ) +eth*d) #etLabels( ) u#e# *esource#et6 et#tring( ) t* retrieve the appr*priate cultureE#peci9ic string 9*r the #peci9ied key and #et# the a##*ciated Label6+ext) *esource#et# *ther +a4*r +eth*d i# et1b)ect( ) !hich can 3e u#ed t* retrieve any type *9 re#*urce) ,eve n*t yet created the #atellite a##e+3lie# !hich !ill #erve a# the I#p*ke#J t* *ur Bnternational Ihu3,J 3ut it i# intere#ting t* run the pr*gra+ in thi# #tate) -9 y*u run the a3*ve c*de and click the IS!ahiliJ radi* 3utt*n, y*u !ill #ee thi# dial*g1
Thi# i# n*t a dial*g y*ud ever !ant an endEu#er t* #ee and a real applicati*n# e;cepti*n handling !*uld hide it, 3ut it# an intere#ting e;a+ple *9 the kind *9 3ehavi*r that y*u c*uld p*tentially include in y*ur *!n c*+p*nent# t* aid /rd party devel*per# during de3ugging)
63&
Thinking in C
www.ThinkingIn.!et
63'
Constant 6esources
,hile culturally appr*priate re#*urce# u#e #atellite a##e+3lie#, it +ay 3e the ca#e that y*u !i#h t* have certain re#*urce# #uch a# graphic# and ic*n# e+3edded directly in the +ain a##e+3ly) U#ing graphic# a# re#*urce# i# a little +*re di99icult than u#ing te;t 3ecau#e y*u +u#t u#e a utility cla## t* generate the re#*urce 9ile) Here# an e;a+ple c*++andE line cla## that take# t!* c*++andEline argu+ent#1 the na+e *9 a graphic# 9ile and the na+e *9 the de#ired re#*urce# 9ile1 //:c"T:_rafRe#_en.c# //_enerate# .re#ource fi e fro! a graphic# fi e //O#age: _rafRe#_en JinputHi eK JoutputHi eK u#ing Sy#te!.5O3 u#ing Sy#te!.Re#ource#3 u#ing Sy#te!.:ra.ing3 c a## _rafRe#_en ; _rafRe#_en0 #tring na!e2 Strea! inStr2 Strea! outStr1; Re#ourceVriter r. 9 ne. Re#ourceVriter0outStr13 5!age i!g 9 ne. Bit!ap0inStr13 r..)ddRe#ource0na!e2 i!g13 r.._enerate013 < pu$ ic #tatic *oid Gain0#tringJK arg#1; Hi eStrea! inH 9 nu 3 Hi eStrea! outH 9 nu 3 try ; #tring na!e 9 arg#J0K3 inH 9 ne. Hi eStrea!0na!e2 Hi eGode.Open13 #tring outCa!e 9 arg#J"K3 outH 9 ne. Hi eStrea!0outCa!e2 Hi eGode.Create13 _rafRe#_en g 9 ne. _rafRe#_en0na!e2 inH2 outH13 < fina y ; inH.C o#e013
64(
Thinking in C
www.ThinkingIn.!et
outH.C o#e013 < < <//:8 = *esource=riter generate# 3inary 6resource 9ile# t* a given #tream) = *es?*esource=riter Gn*t de+*n#tratedH can 3e u#ed t* create an BAL repre#entati*n *9 the re#*urce# that can then 3e c*+piled int* a 3inary 9ile u#ing the resgen pr*ce## de#cri3ed a3*ve Gan BAL repre#entati*n i# n*t very help9ul 9*r 3inary data, #* !e ch*#e t* u#e a *esource=riter directlyH) T* u#e thi# pr*gra+, c*py an i+age t* the l*cal direct*ry and run1 _rafRe#_en #o!ei!age.Dpg Con#tantRe#ource#.re#ource# Thi# !ill generate a 3inary re#*urce# 9ile that !ell e+3ed in thi# e;a+ple pr*gra+1 //:c"T:Con#tantRe#ource#.c# /= Co!pi e .ith: c#c /re#:Con#tantRe#ource#.re#ource# Con#tantRe#ource#.c# =/ //Load# re#ource# fro! the current a##e!$ y u#ing Sy#te!.Re#ource#3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Con#tantRe#ource#:Hor!; Con#tantRe#ource#01; -ictureBox p$ 9 ne. -ictureBox013 p$.:oc% 9 :oc%Sty e.Hi 3 Contro #.)dd0p$13 Re#ourceGanager r! 9 ne. Re#ourceGanager0thi#._et'ype0113 p$.5!age 9 05!age1 r!._etO$Dect0&#o!ei!age.Dpg&13 < pu$ ic #tatic *oid Gain01;
641
)pp ication.Run0ne. Con#tantRe#ource#0113 < <//:8 The c*de in Constant*esources i# very #i+ilar t* the c*de u#ed t* l*ad cultural re#*urce# 9r*+ #atellite#, 3ut !ith*ut the et*esource#et( ) call t* l*ad a particular #atellite) -n#tead, the *esource.anager l**k# 9*r re#*urce# a##*ciated !ith the Constant*esources type) aturally, th*#e are #t*red in the Constant*esources6resources 9ile generated 3y the raf*es en utility 4u#t de#cri3ed) 5*r the *esource.anager t* 9ind thi# 9ile, th*ugh, the re#*urce 9ile +u#t 3e linked int* the +ain a##e+3ly in thi# +anner1 c#c /re#:Con#tantRe#ource#.re# Con#tantRe#ource#.c# =##u+ing that the re#*urce# have 3een pr*perly e+3edded int* the Constant*esources6exe a##e+3ly, the *esource.anager can l*ad the Isomeimage6)pgJ re#*urce and di#play it in the !ictureBox pb)
64)
Thinking in C
www.ThinkingIn.!et
type9&.inT2& na!e9&'hin%ingin.C#harp.C"T.,-'he!e#& *er#ion9&".0.0.0& proce##or)rchitecture 9 &,I?& /Z Wde#criptionZ:e!on#trate ,- 'he!e#W/de#criptionZ W!66 Lin% to co!ct ? 66Z WdependencyZ Wdependent)##e!$ yZ Wa##e!$ y5dentity type9&.inT2& na!e9&Gicro#oft.Vindo.#.Co!!on6Contro #& *er#ion9&?.0.0.0& proce##or)rchitecture9&,I?& pu$ icaey'o%en9&?P>P$?E"EEccf"df& anguage9&=& /Z W/dependent)##e!$ yZ W/dependencyZ W/a##e!$ yZ The +ani9e#t 9ile i# an BALE9*r+atted #*urce *9 +etaEin9*r+ati*n a3*ut y*ur pr*gra+) -n thi# ca#e, a9ter #peci9ying *ur *!n assemblyBdentity, !e #peci9y the dependency *n Common-Controls ver#i*n .) a+e thi# 9ile "rogram!ame6exe6manifest and place it in the #a+e direct*ry a# y*ur pr*gra+) -9 y*u d*, the ) ET Runti+e !ill aut*+atically give the appr*priate Control# in y*ur pr*gra+ BP the+e#) Here# an e;a+ple pr*gra+1 //:c"T:,-'he!ed.c# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.:ra.ing3 c a## ,-'he!ed: Hor!; ,-'he!ed01; C ientSiMe 9 ne. SiMe02P02 "0013 Button $ 9 ne. Button013 $.'ext 9 &,- Sty e&3 $.Location 9 ne. -oint0"02 "013 $.H atSty e 9 H atSty e.Sy#te!3 Contro #.)dd0$13
643
Button $2 9 ne. Button013 $2.'ext 9 &Standard&3 $2.Location 9 ne. -oint0"002 "013 Contro #.)dd0$213 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. ,-'he!ed0113 < <///:8 ,hen run !ith*ut an appr*priate +ani9e#t 9ile, 3*th 3utt*n# !ill have a de9ault gray #tyle1
,hen ?!+hemed6exe6manifest i# availa3le, b !ill u#e the current BP the+e, !hile b8, !h*#e :lat#tyle i# the de9ault :lat#tyle6#tandard, !ill n*t)
7anc5 3uttons
-n additi*n t* creating the+eEa!are 3utt*n#, it i# an ea#y +atter t* create 3utt*n# that have a variety *9 graphical 9eature# and that change their appearance in re#p*n#e t* event#) -n *rder t* run thi# e;a+ple pr*gra+,
644
Thinking in C
www.ThinkingIn.!et
y*ull have t* have 9*ur i+age# in the active direct*ry Gin the e;a+ple c*de, theyre a##u+ed t* 3e na+ed Itic)gi9J, Ia!ay)gi9J,Jin)gi9J, and Ih*ver)gi9JH) //:c"T:ButtonHor!.c# ///:e!on#trate# *ariou# type# of $utton# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 u#ing Sy#te!.:ra.ing3 c a## ButtonHor! : Hor! ; ButtonHor!01 ; C ientSiMe 9 ne. Sy#te!.:ra.ing.SiMe0E002 20013 'ext 9 &Button#2 in a their g ory&3 Button #i!p e 9 ne. Button013 #i!p e.'ext 9 &Si!p e&3 #i!p e.Location 9 ne. -oint0"02 "013 Button i!age 9 ne. Button013 i!age.5!age 9 5!age.Hro!Hi e0&.^^'iC.gif&13 i!age.'ext 9 &'ext&3 i!age.Location 9 ne. -oint0"202 "013 Button popup 9 ne. Button013 popup.Location 9 ne. -oint02T02 "013 popup.'ext 9 &-opup&3 popup.H atSty e 9 H atSty e.-opup3 H yO*erButton f yO*er 9 ne. H yO*erButton0&).ay&2 &5n&2 &Uo*ering&13 f yO*er.Location 9 ne. -oint0"02 E013 H yO*er5!age# f yO*er5!age# 9 ne. H yO*er5!age# 0&.^^a.ay.gif&2&.^^in.gif&2&.^^ho*er.gif&13 f yO*er5!age#.Location 9 ne. -oint02T02 E013 Contro #.)ddRange0ne. Contro JK;
645
#i!p e2 i!age2 popup2 f yO*er2 f yO*er5!age#< 13 < pu$ ic #tatic *oid Gain01 ; )pp ication.Run0ne. ButtonHor!0113 < < c a## H yO*erButton : Button ; #tring a.ay3 #tring inStr3 #tring ho*er3 interna H yO*erButton0 #tring a.ay2 #tring inStr2 #tring ho*er1 ; thi#.a.ay 9 a.ay3 thi#.inStr 9 inStr3 thi#.ho*er 9 ho*er3 H atSty e 9 H atSty e.-opup3 'ext 9 a.ay3 Gou#e+nter R9 ne. +*entUand er0OnGou#e+nter13 Gou#eUo*er R9 ne. +*entUand er0OnGou#eUo*er13 Gou#eLea*e R9 ne. +*entUand er0OnGou#eLea*e13 < pri*ate *oid OnGou#e+nter0 o$Dect #ender2 Sy#te!.+*ent)rg# arg#1 ; 00Contro 1#ender1.'ext 9 inStr3 < pri*ate *oid OnGou#eUo*er0 o$Dect #ender2 Sy#te!.+*ent)rg# arg#1 ; 00Contro 1#ender1.'ext 9 ho*er3 < pri*ate *oid OnGou#eLea*e0 o$Dect #ender2 Sy#te!.+*ent)rg# arg#1 ; 00Contro 1#ender1.'ext 9 a.ay3 < < c a## H yO*er5!age# : Button ;
646
Thinking in C
www.ThinkingIn.!et
interna H yO*er5!age#0 #tring a.ay2 #tring inStr2 #tring ho*er1 ; 5!ageLi#t 9 ne. 5!ageLi#t013 5!ageLi#t.5!age#.)dd05!age.Hro!Hi e0a.ay113 5!ageLi#t.5!age#.)dd05!age.Hro!Hi e0inStr113 5!ageLi#t.5!age#.)dd05!age.Hro!Hi e0ho*er113 H atSty e 9 H atSty e.-opup3 5!age5ndex 9 03 Gou#e+nter R9 ne. +*entUand er0OnGou#e+nter13 Gou#eUo*er R9 ne. +*entUand er0OnGou#eUo*er13 Gou#eLea*e R9 ne. +*entUand er0OnGou#eLea*e13 < pri*ate *oid OnGou#e+nter0 o$Dect #ender2 Sy#te!.+*ent)rg# arg#1 ; 00Button1#ender1.5!age5ndex 9 "3 < pri*ate *oid OnGou#eUo*er0 o$Dect #ender2 Sy#te!.+*ent)rg# arg#1 ; 00Button1#ender1.5!age5ndex 9 23 < pri*ate *oid OnGou#eLea*e0 o$Dect #ender2 Sy#te!.+*ent)rg# arg#1 ; 00Button1#ender1.5!age5ndex 9 03 < <///:8 The 9ir#t 3utt*n created and placed *n the 9*r+ i# simple and it# appearance and 3ehavi*r #h*uld 3e 9a+iliar) The #ec*nd 3utt*n image, #et# it# Bmage pr*perty 9r*+ an Bmage l*aded 9r*+ a 9ile) The #a+e Bmage i# di#played at all ti+e#Q i9 the +ext pr*perty i# #et, the la3el !ill 3e dra!n o-er the Bmage) The third 3utt*n popup ha# a :lat#tyle *9 :lat#tyle6!opup) Thi# 3utt*n appear# 9lat until the +*u#e pa##e# *ver it, at !hich p*int it i# redra!n !ith a /E? l**k) The 9*urth and 9i9th 3utt*n# reDuire +*re c*de and #* are !ritten a# their *!n cla##e#1 :ly1verButton and :ly1verBmages) The :ly1verButton i# a regular 3utt*n, 3ut ha# event handler# 9*r
64#
.ouse&nter, .ouse"over, and .ouseLeave !hich #et the +ext pr*perty a# appr*priate) :ly1verBmages take# advantage *9 the BmageList pr*perty *9 Button) Like :ly1verButton, :ly1verBmages u#e# +*u#e event# t* change the i+age di#played *n the 3utt*n, 3ut in#tead *9 +anipulating the Bmage pr*perty, it #et# the BmageBndex pr*perty, !hich c*rre#p*nd indice# in the BmageList c*n9igured in the :ly1verBmages( ) c*n#truct*r)
-oolti$s
The *ne I9ancyJ thing that the previ*u# e;a+ple did n*t #h*! i# pr*3a3ly the *ne y*u +*#t e;pect P the help te;t that appear# !hen the +*u#e h*ver# *ver a c*ntr*l 9*r +*re than a 9e! +*+ent#) Such t**ltip# are, #urpri#ingly, n*t a pr*perty *9 the Control a3*ve !hich they appear, 3ut rather are c*ntr*lled 3y a #eparate +ool+ip *34ect) Thi# !*uld #ee+ t* vi*late a de#ign ruleE*9Ethu+31 *34ect# #h*uld generally c*ntain a naviga3le re9erence t* all *34ect# e;ternally c*n#idered a##*ciated) =# a u#er *r pr*gra++er, *ne !*uld de9initely c*n#ider the t**ltip t* 3e Ipart *9J !hat di#tingui#he# *ne c*ntr*l 9r*+ an*ther, #* *ne #h*uld e;pect a +ooltip pr*perty in Control) =n*ther #urpri#e i# that the +ool+ip d*e# n*t c*n9*r+ t* the c*ntain+ent +*del *9 ,ind*!# 5*r+#, it i# n*t placed !ithin the Controls c*llecti*n *9 an*ther Control) Thi# i# an e;a+ple *9 h*! even the 3e#tEde#igned li3rarie# Gand ,ind*!# 5*r+# i# t*pEn*tchH c*ntain inc*n#i#tencie# and Duirk#Q !hile it can 3e very help9ul t* #tudy the de#ign *9 a g**d li3rary t* aid y*ur de#ign educati*n, all li3rarie# c*ntain Due#ti*na3le ch*ice#) =dding a +ool+ip t* a Control reDuire# that a re9erence t* the Control and it# de#ired te;t 3e pa##ed t* an in#tance *9 +ool+ip G!hich pre#u+a3ly +aintain# an internal B$ictionary, !hich 3eg# the Due#ti*n *9 !hy a +ool+ip in#tance i# reDuired rather than u#ing a #tatic +eth*dH) Here# an e;a+ple that #h*!# the 3a#ic u#e *9 a +ool+ip1 //:c"T:'oo tip:i#p ay.c# u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3
64&
Thinking in C
www.ThinkingIn.!et
c a## 'oo tip:i#p ay : Hor!; 'oo tip:i#p ay01; Button $ 9 ne. Button013 $.'ext 9 &Button&3 $.Location 9 ne. -oint0"02 "013 Contro #.)dd0$13 'oo 'ip t 9 ne. 'oo 'ip013 t.Set'oo 'ip0$2 &:oe# nothing&13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. 'oo tip:i#p ay0113 < <
64'
Rich'extBox rt$3 Rando! rand 9 ne. Rando!013 'ext+diting01 ; C ientSiMe 9 ne. SiMe0EP02 E0013 'ext 9 &'ext +diting&3 t$ 9 ne. 'extBox013 t$.'ext 9 &So!e 'ext&3 t$.Location 9 ne. -oint0"02 "013 Button $o d 9 ne. Button013 $o d.'ext 9 &Bo d&3 $o d.Location 9 ne. -oint0TP02 "013 $o d.C ic% R9 ne. +*entUand er0$o dXC ic%13 Button co or 9 ne. Button013 co or.'ext 9 &Co or&3 co or.Location 9 ne. -oint0TP02 ?013 co or.C ic% R9 ne. +*entUand er0co orXC ic%13 Button #iMe 9 ne. Button013 #iMe.'ext 9 &SiMe&3 #iMe.Location 9 ne. -oint0TP02 ""013 #iMe.C ic% R9 ne. +*entUand er0#iMeXC ic%13 Button font 9 ne. Button013 font.'ext 9 &Hont&3 font.Location 9ne. -oint0TP02 "?013 font.C ic% R9 ne. +*entUand er0fontXC ic%13 rt$ 9 ne. Rich'extBox013 rt$.Location 9 ne. -oint0"02 P013 rt$.SiMe 9 ne. SiMe0T002 "I013 Contro #.)ddRange0 ne. Sy#te!.Vindo.#.Hor!#.Contro JK; t$2 rt$2 $o d2 co or2 #iMe2 font<13 <
65(
Thinking in C
www.ThinkingIn.!et
pri*ate *oid )dd)ndSe ect'ext01 ; #tring ne.'ext 9 t$.'ext R &^n&3 int in#ertion-oint 9 rt$.Se ectionStart3 rt$.)ppend'ext0ne.'ext13 rt$.Se ectionStart 9 in#ertion-oint3 rt$.Se ectionLength 9 ne.'ext.Length3 < pri*ate *oid Re#etSe ection)ndHont01 ; /= Setting $eyond end of text$ox p ace# in#ertion at end of text =/ rt$.Se ectionStart 9 5nt"?.GaxNa ue3 rt$.Se ectionLength 9 03 rt$.Se ectionHont 9 ne. Hont0&Nerdana&2 "02 HontSty e.Regu ar13 rt$.Se ectionCo or 9 Co or.B ac%3 < pri*ate *oid $o dXC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1 ; )dd)ndSe ect'ext013 rt$.Se ectionHont 9 ne. Hont0&Nerdana&2 "02 HontSty e.Bo d13 Re#etSe ection)ndHont013 < pri*ate *oid co orXC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1 ; )dd)ndSe ect'ext013 rt$.Se ectionCo or 9 0rand.Cext:ou$ e011 Z 0.P Y Co or.Red : Co or.B ue3 Re#etSe ection)ndHont013 < pri*ate *oid #iMeXC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1 ; )dd)ndSe ect'ext013 int fontSiMe 9 I R rand.Cext0"013 rt$.Se ectionHont 9 ne. Hont0&Nerdana&2 fontSiMe2
651
HontSty e.Regu ar13 Re#etSe ection)ndHont013 < pri*ate *oid fontXC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1 ; )dd)ndSe ect'ext013 HontHa!i yJK fa!i ie# 9 HontHa!i y.Ha!i ie#3 int iHa!i y 9 rand.Cext0fa!i ie#.Length13 rt$.Se ectionHont 9 ne. Hont0fa!i ie#JiHa!i yK2 "02 HontSty e.Regu ar13 Re#etSe ection)ndHont013 < #tatic *oid Gain01 ; )pp ication.Run0ne. 'ext+diting0113 < <///:8 Everything in the +ext&diting( ) c*n#truct*r #h*uld 3e 9a+iliar1 a nu+3er *9 Button# are created, event handler# attached, and a +extBox and *ich+extBox are placed *n the :orm a# !ell) The +eth*d# 'dd'nd#elect+ext( ) and *eset#election'nd:ont( ) are u#ed 3y the vari*u# event handler#) -n 'dd'nd#elect+ext( ) the te;t t* 3e in#erted i# taken 9r*+ the +extBox tb and a ne!line added) The current rtb6#election#tart i# re+e+3ered, the ne! te;t appended t* the *ich+extBox, and the #electi*n i# #et t* 3egin !ith the re+e+3ered insertion!oint and #electionLength t* the length *9 the in#erted te;t) *eset#election'nd:ont( ) #et# the in#erti*n p*int at the end *9 the te;t 3y giving it an i+p*##i3ly high value) The #electi*n i# re#et t* u#e the de9ault 9*nt G0* pt) Cerdana in 3lackH u#ing the appr*priate pr*pertie#) The vari*u# event handler# call 'dd'nd#elect+ext( ) and then +anipulate vari*u# a#pect# *9 the #elected te;t P di99erent #i7e#, c*l*r#, and 9*nt# are rand*+ly ch*#en)
65)
Thinking in C
www.ThinkingIn.!et
Lin*ing -e&t
-n the pa#t decade, hyperte;t ha# g*ne 9r*+ an e#*teric t*pic t* pr*3a3ly the d*+inant 9*r+ *9 hu+anEc*+puter interacti*n) H*!ever, inc*rp*rating te;t link# int* a U- ha# 3een a 3ig challenge) ,ind*!# 5*r+# change# that !ith it# Lin(Label c*ntr*l) The Lin(Label ha# p*!er9ul #upp*rt 9*r linking, all*!ing any nu+3er *9 link# !ithin the la3el area) The Lin(Label 9acilitate# the creati*n *9 even c*+ple; linking #e+antic#, #uch a# the BLink #tandard G!!!)!/)*rg<TR<;link<H) ,hile it# p*##i3le t* u#e a Lin(Label t* activate *ther ,ind*!# 5*r+# 3ehavi*r, the +*#t c*++*n u#e i# likely t* 3e activating the 9ullE9eatured ,e3 3r*!#er) T* d* that, !e need t* intr*duce the !rocess cla## 9r*+ the #ystem6$iagnostics na+e#pace) The !rocess cla## pr*vide# th*r*ugh acce## t* l*cal and re+*te pr*ce##e#, 3ut the c*re 9uncti*nality i# #tarting a l*cal pr*ce##, i)e), launching an*ther applicati*n !hile y*ur applicati*n c*ntinue# t* run G*r #hut# d*!n P the launched pr*ce## i# independent *9 y*ur applicati*nH) There are three *verl*aded ver#i*n# *9 !rocess6#tart( ) that pr*vide vari*u# degree# *9 c*ntr*l *ver the launched applicati*n) The +*#t 3a#ic !rocess6#tart( ) +eth*d 4u#t take# a string and u#e# the OS# underlying +echani#+ t* deter+ine the appr*priate !ay t* run the reDue#tQ i9 the #tring #peci9ie# a n*nEe;ecuta3le 9ile, the e;ten#i*n +ay 3e a##*ciated !ith a pr*gra+ and, i9 #*, that pr*gra+ !ill *pen it) 5*r in#tance, !rocess#tart(G:oo6csG) !ill *pen the edit*r a##*ciated !ith the 6cs e;ten#i*n) The +*#t advanced !rocess6#tart( ) take# a !rocess#tartBnfo in9*) !rocess#tartBnfo c*ntain# pr*pertie# 9*r #etting envir*n+ent varia3le#, !hether a !ind*! #h*uld 3e #h*!n and in !hat #tyle, input and *utput redirecti*n, etc) Thi# e;a+ple u#e# the third *verl*ad *9 !rocess6#tart( ), !hich take# an applicati*n na+e and a #tring repre#enting the c*++andEline argu+ent#, t* launch -nternet E;pl*rer and #ur9 t* !!!)Thinking-n) et) //:c"T:Lin%La$e :e!o.c# //:e!on#trate# the Lin%La$e u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.:iagno#tic#3
653
u#ing Sy#te!.Vindo.#.Hor!#3 c a## Lin%La$e :e!o : Hor! ; Lin%La$e :e!o01; Lin%La$e a$e " 9 ne. Lin%La$e 013 a$e ".'ext 9 &:o.n oad 'hin%ing in C(&3 a$e ".Lin%#.)dd0>2 "E2 &http://....thin%ingin.net/&13 a$e ".Lin%C ic%ed R9 ne. Lin%La$e Lin%C ic%ed+*entUand er0 5nternet+xp orerLaunch13 a$e ".Location 9 ne. -oint0"02 "013 a$e ".SiMe 9 ne. SiMe0"?02 T013 Contro #.)dd0 a$e "13 Lin%La$e a$e 2 9 ne. Lin%La$e 013 a$e 2.'ext 9 &Sho. !e##age&3 a$e 2.Lin%#.)dd002 E2 &Hoo&13 a$e 2.Lin%#.)dd0P2 I2 &Bar&13 a$e 2.Lin%C ic%ed R9 ne. Lin%La$e Lin%C ic%ed+*entUand er0 Ge##ageBoxSho.13 a$e 2.Location 9 ne. -oint0"02 ?013 Contro #.)dd0 a$e 213 < pu$ ic *oid 5nternet+xp orerLaunch 0o$Dect #rc2 Lin%La$e Lin%C ic%ed+*ent)rg# e1; #tring ur 9 0#tring1 e.Lin%.Lin%:ata3 -roce##.Start0&5+xp ore.exe&2 ur 13 e.Lin%.Ni#ited 9 true3 < pu$ ic *oid Ge##ageBoxSho. 0o$Dect #rc2 Lin%La$e Lin%C ic%ed+*ent)rg# e1; #tring !#g 9 0#tring1 e.Lin%.Lin%:ata3 Ge##ageBox.Sho.0!#g13 e.Lin%.Ni#ited 9 true3 < pu$ ic #tatic *oid Gain01;
654
Thinking in C
www.ThinkingIn.!et
)pp ication.Run0ne. Lin%La$e :e!o0113 < <//:8 *t all the Lin(Label6+ext need 3e a linkQ individual link# are added t* the Lin(s c*llecti*n 3y #peci9ying an *99#et and the length *9 the link) -9 y*u d* n*t need any in9*r+ati*n *ther than the 9act that the link !a# clicked, y*u d* n*t need t* include the third argu+ent t* Lin(s6'dd( ), 3ut typically y*u !ill #t*re #*+e data t* 3e u#ed 3y the event handler) -n the e;a+ple, the phra#e IThinking in C#J i# pre#ented underlined, in the c*l*r *9 the Lin(Color pr*perty G3y de9ault, thi# i# #et 3y the #y#te+ and i# u#ually 3lueH) Thi# link ha# a# it# a##*ciated data, a URL) Label8 ha# t!* link# !ithin it, *ne a##*ciated !ith the string I9**J and the *ther !ith I3ar)J ,hile a Lin(Label can have +any link#, all the link# #hare the #a+e event handler G*9 c*ur#e, it# a +ultica#t delegate, #* y*u can add a# +any +eth*d# t* the event handling chain a# de#ired, 3ut y*u cann*t directly a##*ciated a #peci9ic eventEhandling +eth*d !ith a #peci9ic linkH) The Lin( i# pa##ed t* the event handler via the event argu+ent#, #* the delegate i# the de#criptively na+ed Lin(LabelLin(Clic(ed&vent"andler) The Lin($ata Gi9 it !a# #peci9ied in the Lin(# c*n#truct*rH can 3e any ob)ect) -n the e;a+ple, !e d*!nca#t the Lin($ata t* string) The Bnternet&xplorerLaunch( ) +eth*d u#e# !rocess6#tart( ) t* launch Aicr*#*9t# ,e3 3r*!#er) .essageBox#how( ) de+*n#trate# the c*nvenient .essageBox cla##, !hich p*p# up a #i+ple alert dial*g) =t the end *9 the event handler#, the appr*priate Lin( i# #et t* Hisited, !hich redra!# the link in the Lin(Label)HisitedLin(Color)
655
u#ually y*u !ill u#e a !anel *r roupBox t* c*ntain a #et *9 l*gically related radi* 3utt*n# G*r *ther c*ntr*l#H) U#ually, a #et *9 related *adioButton# #h*uld have the #a+e event handler #ince generally the pr*gra+ need# t* kn*! I,hich *9 the radi* 3utt*n# in the gr*up i# #electedFJ Since &vent"andler delegate# pa## the #*urce ob)ect a# the 9ir#t para+eter in their argu+ent#, it i# ea#y 9*r a gr*up *9 3utt*n# t* #hare a #ingle delegate +eth*d and u#e the src argu+ent t* deter+ine !hich 3utt*n ha# 3een activated) The u#e *9 a roupBox and thi# 9*r+ *9 #haring a delegate +eth*d i# de+*n#trated in the ne;t e;a+ple) Chec(Box c*ntr*l# are n*t +utually e;clu#iveQ any nu+3er can 3e in any #tate !ithin a c*ntainer) Chec(Boxe# cycle 3et!een t!* #tate# GChec(#tate6Chec(ed and Chec(#tate6Vnchec(edH 3y de9ault, 3ut 3y #etting the +hree#tate pr*perty t* true, can cycle 3et!een Chec(ed, Vnchec(ed, and Chec(#tate6Bndeterminate) Thi# e;a+ple de+*n#trate# a #tandard Chec(Box, *ne that u#e# an Bmage in#tead *9 te;t Glike Button# and +any *ther Control#, the de9ault appearance can 3e changed u#ing a variety *9 pr*pertie#H, a threeE #tate Chec(Box, and gr*uped, delegateE#haring *adioButton#1 //:c"T:Chec%)ndRadio.c# //:e!on#trate# *ariou# type# of $utton# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 u#ing Sy#te!.:ra.ing3 c a## Chec%)ndRadio : Hor! ; Chec%)ndRadio01 ; C ientSiMe 9 ne. Sy#te!.:ra.ing.SiMe0E002 20013 'ext 9 &Chec%$oxe# and Radio Button#&3 Chec%Box #i!p e 9 ne. Chec%Box013 #i!p e.'ext 9 &Si!p e&3 #i!p e.Location 9 ne. -oint0"02 "013 #i!p e.C ic% R9 ne. +*entUand er0OnSi!p eChec%BoxC ic%13 Chec%Box i!age 9 ne. Chec%Box013
656
Thinking in C
www.ThinkingIn.!et
i!age.5!age 9 5!age.Hro!Hi e0&.^^'iC.gif&13 i!age.Location 9 ne. -oint0"202 "013 i!age.C ic% R9 ne. +*entUand er0OnSi!p eChec%BoxC ic%13 Chec%Box threeState 9 ne. Chec%Box013 threeState.'ext 9 &'hree #tate&3 threeState.'hreeState 9 true3 threeState.Location 9 ne. -oint02T02 "013 threeState.C ic% R9 ne. +*entUand er0On'hreeStateChec%BoxC ic%13 -ane r$-ane 9 ne. -ane 013 r$-ane .Location 9 ne. -oint0"02 P013 r$-ane .SiMe 9 ne. SiMe0E202 P013 r$-ane .)utoScro 9 true3 RadioButton f" 9 ne. RadioButton013 f".'ext 9 &Nani a&3 f".Location 9 ne. -oint002 "013 f".Chec%edChanged R9 ne. +*entUand er0OnRadioButtonChange13 RadioButton f2 9 ne. RadioButton013 f2.'ext 9 &Choco ate&3 f2.Location 9 ne. -oint0"E02 "013 f2.Chec%edChanged R9 ne. +*entUand er0OnRadioButtonChange13 RadioButton fT 9 ne. RadioButton013 fT.'ext 9 &Chun%y Gon%ey&3 fT.Location 9 ne. -oint 02I02 "013 fT.Chec%edChanged R9 ne. +*entUand er0OnRadioButtonChange13 fT.Chec%ed 9 true3 r$-ane .Contro #.)ddRange0 ne. Contro JK; f"2 f22 fT<13 Contro #.)ddRange0 ne. Contro JK; #i!p e2 i!age2 threeState2 r$-ane <13 <
65#
pri*ate *oid OnSi!p eChec%BoxC ic%0 o$Dect #ender2 +*ent)rg# arg#1; Chec%Box c$ 9 0Chec%Box1 #ender3 Sy#te!.Con#o e.VriteLine0 c$.'ext R & i# & R c$.Chec%ed13 < pri*ate *oid On'hreeStateChec%BoxC ic%0 o$Dect #ender2 +*ent)rg# arg#1; Chec%Box c$ 9 0Chec%Box1 #ender3 Sy#te!.Con#o e.VriteLine0 c$.'ext R & i# & R c$.Chec%State13 < pri*ate *oid OnRadioButtonChange0 o$Dect #ender2 +*ent)rg# arg#1; RadioButton r$ 9 0RadioButton1 #ender3 if 0r$.Chec%ed 99 true1 Sy#te!.Con#o e.VriteLine0 &H a*or i# & R r$.'ext13 < pu$ ic #tatic *oid Gain01 ; )pp ication.Run0ne. Chec%)ndRadio0113 < <//:8
65&
Thinking in C
www.ThinkingIn.!et
3e ch*#en G.ulti&xtended #h*uld 3e u#ed t* all*! SH-5T, CTRL, and arr*! #h*rtcut#H) -9 the #electi*n +*de i# #election.ode6#ingle, the Btem pr*perty c*ntain# the *neEandE*nly #elected ite+, 9*r *ther +*de# the Btems pr*perty i# u#ed) //:c"T:Li#tBox:e!o.c# //:e!on#trate# Li#tBox #e ection u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Li#tBox:e!o : Hor!; Li#tBox:e!o01; Li#tBox $ 9 ne. Li#tBox013 for0int i 9 03 i W "03 iRR1; $.5te!#.)dd0i.'oString0113 < $.Location 9 ne. -oint0"02 "013 $.Se ectedNa ueChanged R9 ne. +*entUand er0OnSe ect13 Contro #.)dd0 $13 < pu$ ic *oid OnSe ect0o$Dect #rc2 +*ent)rg# ea1; Li#tBox $ 9 0Li#tBox1 #rc3 Con#o e.VriteLine0 $.Se ected5te!13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Li#tBox:e!o0113 < <///:8 The ComboBox i# #i+ilarly ea#y t* u#e, alth*ugh it can *nly 3e u#ed 9*r #ingle #electi*n) Thi# e;a+ple de+*n#trate# the ComboBox, including it# a3ility t* #*rt it# *!n c*ntent#1 //:c"T:Co!$oBox:e!o.c# ///:e!on#trate# the Co!$oBox u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3
65'
c a## Co!$oBox:e!o : Hor! ; Co!$oBox pre#ident#3 Chec%Box #orted3 Co!$oBox:e!o01 ; C ientSiMe 9 ne. SiMe0T202 20013 'ext 9 &Co!$oBox :e!o&3 pre#ident# 9 ne. Co!$oBox013 pre#ident#.Location 9 ne. -oint0"02 "013 pre#ident#.5te!#.)ddRange0 ne. #tringJK; &Va#hington&2 &)da!# `&2 &`effer#on&2 &Gadi#on&2 &Gonroe&2 &)da!#2 `Q&2 &`ac%#on&2 &Nan Buren&2 &Uarri#on&2 &'y er&2 &-o %&2 &'ay or&2 &Hi !ore&2 &-ierce&2 &Buchanan&2 &Linco n&2 &`ohn#on )&2 &_rant&2 &Uaye#&2 &_arfie d&2 &)rthur&2 &C e*e and&2 &Uarri#on&2 &Gcain ey&2 &Roo#e*e t '&2 &'aft&2 &Vi #on&2 &Uarding&2 &Coo idge&2 &Uoo*er&2 &Roo#e*e t H:&2 &'ru!an&2 &+i#enho.er&2 &aennedy&2 &`ohn#on LB&2 &Cixon&2 &Hord&2 &Carter&2 &Reagan&2 &Bu#h _&2 &C inton&2 &Bu#h _V&<13 pre#ident#.Se ected5ndexChanged R9 ne. +*entUand er0On-re#identSe ected13 #orted 9 ne. Chec%Box013 #orted.'ext 9 &) pha$etica y #orted&3 #orted.Chec%ed 9 fa #e3 #orted.C ic% R9 ne. +*entUand er0ConRe*er#i$ eSort13 #orted.Location 9 ne. -oint0"P02 "013 Button $tn 9 ne. Button013 $tn.'ext 9 &Read #e ected&3 $tn.C ic% R9 ne. +*entUand er0_et-re#ident13 $tn.Location 9 ne. -oint0"P02 P013 Contro #.)ddRange0
66(
Thinking in C
www.ThinkingIn.!et
ne. Contro JK;pre#ident#2 #orted2 $tn<13 < pri*ate *oid ConRe*er#i$ eSort 0o$Dect #ender2 +*ent)rg# arg#1 ; //$ug2 #ince non6re*er#i$ e pre#ident#.Sorted 9 #orted.Chec%ed3 < pri*ate *oid On-re#identSe ected 0o$Dect #ender2 +*ent)rg# arg#1 ; int #e 5dx 9 pre#ident#.Se ected5ndex3 if 0#e 5dx Z 6"1 ; Sy#te!.Con#o e.VriteLine0 &Se ected pre#ident i#: & R pre#ident#.5te!#J#e 5dxK13 < e #e ; Sy#te!.Con#o e.VriteLine0 &Co pre#ident i# #e ected&13 < < pri*ate *oid _et-re#ident 0o$Dect #ender2 +*ent)rg# arg#1 ; //:oe#n't .or%2 #ince can $e $ an% // or gar$age *a ue Sy#te!.Con#o e.VriteLine0pre#ident#.'ext13 //So you ha*e to do #o!ething i%e thi#... #tring #ugge#tion 9 pre#ident#.'ext3 if0pre#ident#.5te!#.Contain#0#ugge#tion11; Sy#te!.Con#o e.VriteLine0 &Se ected pre#ident i#: & R #ugge#tion13 <e #e; Sy#te!.Con#o e.VriteLine0 &Co pre#ident i# #e ected&13 < < pu$ ic #tatic *oid Gain01 ; )pp ication.Run0ne. Co!$oBox:e!o0113 <
661
<//:8 =9ter the na+e# *9 the pre#ident# are l*aded int* the ComboBox, a 9e! handler# are de9ined1 the check 3*; !ill trigger ,on*eversible#ort( ) and the 3utt*n !ill trigger et!resident( )) The i+ple+entati*n *9 ,on*eversible#ort( ) #et# the ComboBox# #orted pr*perty depending *n the #electi*n #tate *9 the sorted Chec(box) Thi# i# a de9ect a#, *nce #*rted, #etting the #orted pr*perty t* false !ill not return the ComboBox t* it# *riginal chr*n*l*gicallyE*rdered #tate) et!resident( ) reveal# an*ther Duirk) The value *9 ComboBox6+ext i# the value *9 the edita3le 9ield in the ComboBox, even i9 n* value ha# 3een ch*#en, *r i9 the u#er ha# typed in n*nEvalid data) -n *rder t* c*n9ir+ that the data in ComboBox6+ext i# valid, y*u have t* #earch the Btems c*llecti*n 9*r the te;t, a# de+*n#trated) The Chec(edListBox i# the +*#t c*+ple; *9 the li#tE#electi*n c*ntr*l#) Thi# e;a+ple let# y*u #peci9y y*ur +u#ical ta#te#, printing y*ur like# and di#like# t* the C*n#*le) //:c"T:Chec%edLi#tBox:e!o.c# ///:e!on#trate# the Chec%edLi#tBox u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Chec%edLi#tBox:e!o : Hor! ; Chec%edLi#tBox !u#ica 'a#te#3 Chec%edLi#tBox:e!o01; C ientSiMe 9 ne. SiMe0T202 20013 'ext 9 &Chec%edLi#tBox :e!o&3 !u#ica 'a#te# 9 ne. Chec%edLi#tBox013 !u#ica 'a#te#.Location 9 ne. -oint0"02 "013 !u#ica 'a#te#.5te!#.)dd0 &C a##ica &2 Chec%State.5ndeter!inate13 !u#ica 'a#te#.5te!#.)dd0 &`aMM&2 Chec%State.5ndeter!inate13 !u#ica 'a#te#.5te!#.)ddRange0 ne. #tringJK; &B ue#&2 &Roc%&2
66)
Thinking in C
www.ThinkingIn.!et
Button get'a#te# 9 ne. Button013 get'a#te#.Location 9 ne. -oint02002 "013 get'a#te#.Vidth 9 "003 get'a#te#.'ext 9 &_et ta#te#&3 get'a#te#.C ic% R9 ne. +*entUand er0On_et'a#te#13 Contro #.)dd0!u#ica 'a#te#13 Contro #.)dd0get'a#te#13 < pri*ate *oid Ga%e) 5ndeter!inate01; Chec%edLi#tBox.O$DectCo ection ite!# 9 !u#ica 'a#t#.5te!#3 for 0int i 9 03 i W ite!#.Count3 iRR1 ; !u#ica 'a#te#.Set5te!Chec%State0i2 Chec%State.5ndeter!inate13 < < pri*ate *oid On_et'a#te#0o$Dect o2 +*ent)rg# arg#1; //Return# chec%ed X)C:X indeter!inate! Chec%edLi#tBox.Chec%ed5ndexCo ection chec%ed5ndice# 9 !u#ica 'a#te#.Chec%ed5ndice#3 foreach0int i in chec%ed5ndice#1; if 0!u#ica 'a#te#._et5te!Chec%State0i1 !9 Chec%State.5ndeter!inate1 ; Sy#te!.Con#o e.VriteLine0 &Li%e#: & R !u#ica 'a#te#.5te!#JiK13 < < //Or2 to iterate o*er the .ho e co ection for 0int i 9 03 i W !u#ica 'a#te#.5te!#.Count3 iRR1 ; if 0!u#ica 'a#te#._et5te!Chec%State0i1 99 Chec%State.Onchec%ed1 ;
663
Sy#te!.Con#o e.VriteLine0 &:i# i%e: & R !u#ica 'a#te#.5te!#JiK13 < < < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Chec%edLi#tBox:e!o0113 < <//:8 The Chec(edListBox$emo( ) c*n#truct*r #h*!# that ite+# can 3e added either *ne at a ti+e, !ith their Chec(#tate pr*perty de9ined, *r en +a##e) The 1n et+astes( ) +eth*d #h*!# a de9ect in the Chec(edListBox c*ntr*lQ the Chec(edBndices pr*perty return# n*t 4u#t th*#e ite+# !ith Chec(#tate6Chec(ed, 3ut al#* th*#e !ith Chec(#tate6BndeterminateK =n e;plicit check +u#t 3e added t* +ake #ure that the value at the inde; really is checked) Once an appr*priate inde; i# in hand, the value can 3e retrieved 3y u#ing the Btems< > array *perat*r)
664
Thinking in C
www.ThinkingIn.!et
-n thi# e;a+ple, !e u#e !anel# that !e +ake vi#i3le 3y #etting their Bac(Color pr*pertie#) //:c"T:Sp itter:e!o.c# u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Sp itter:e!o : Hor!; Sp itter:e!o01; -ane r 9 ne. -ane 013 r.Bac%Co or 9 Co or.Red3 r.:oc% 9 :oc%Sty e.Left3 r.Vidth 9 2003 -ane g 9 ne. -ane 013 g.Bac%Co or 9 Co or._reen3 g.:oc% 9 :oc%Sty e.Hi 3 -ane $ 9 ne. -ane 013 $.Bac%Co or 9 Co or.B ue3 $.:oc% 9 :oc%Sty e.Right3 $.Vidth 9 2003 Sp itter rg 9 ne. Sp itter013 //Set doc% to #a!e a# re#iMed contro rg.:oc% 9 :oc%Sty e.Left3 Sp itter g$ 9 ne. Sp itter013 //Set doc% to #a!e a# re#iMed contro g$.:oc% 9 :oc%Sty e.Right3 Contro #.)dd0g13 //Sp itter added X$eforeX pane Contro #.)dd0g$13 Contro #.)dd0$13 //Sp itter added X$eforeX pane Contro #.)dd0rg13 Contro #.)dd0r13 0p"1
0pT1
665
Vidth 9 ?E03 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Sp itter:e!o0113 < <//:8 =9ter creating panel# r, g, and b and #etting their Bac(Color# appr*priately, !e create a #plitter rg !ith the #a+e $oc( value a# the r !anel and an*ther called gb !ith the #a+e $oc( value a# b) -t i# critical that the #plitter# are added t* the :orm i++ediately pri*r t* the !anel# they re#i7e) The e;a+ple #tart# !ith r and b at their pre9erred =idth *9 2$$ pi;el#, !hile the entire :orm i# #et t* take .&$) H*!ever, y*u can re#i7e the !anel# +anually)
-ree8iew I List8iew
Every*ne #ee+# t* have a di99erent idea *9 !hat the ideal +reeHiew c*ntr*l #h*uld l**k like and every di#cu##i*n gr*up 9*r every U- t**lkit i# regularly #!a+ped !ith the intricacie# *9 +reeHiew pr*gra++ing) ,ind*!# 5*r+# i# n* e;cepti*n, 3ut the general ea#e *9 pr*gra++ing ,ind*!# 5*r+# +ake# 3a#ic +reeHiew pr*gra++ing 9airly #traight9*r!ard) The c*re c*ncept *9 the +reeHiew i# that a +reeHiew c*ntain# +ree,odes, !hich in turn c*ntain *ther +ree,odes) Thi# +*del i# e##entially the #a+e a# the ,ind*!# 5*r+# +*del in !hich Control# c*ntain *ther Control#) S* 4u#t a# y*u #tart !ith a :orm and add Control# and Control# t* th*#e Control#, #* t** y*u create a +reeHiew and add +ree,ode# and +ree,ode# t* th*#e +ree,ode#) H*!ever, the general pr*gra++ing +*del 9*r ,ind*!# 5*r+# i# that event# are a##*ciated !ith the piece# that +ake up the !h*le Gthe Control# !ithin their c*ntainer#H, !hile the pr*gra++ing +*del 9*r the +reeHiew i# that event# are a##*ciated !ith the !h*leQ +ree,ode# have n* event#) Thi# e;a+ple #h*!# the #i+ple#t p*##i3le u#e *9 +reeHiew)
666
Thinking in C
www.ThinkingIn.!et
//:c"T:'reeNie.:e!o".c# //:e!on#trate# 'reeNie. contro u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## 'reeNie.:e!o" : Hor!; 'reeNie.:e!o"01; 'reeNie. t* 9 ne. 'reeNie.013 'reeCode root 9 ne. 'reeCode0&Hi#h&13 'reeCode cart 9 ne. 'reeCode0&Shar%# @ Ray#&13 'reeCode $ony 9 ne. 'reeCode0&Bony fi#he#&13 t*.Code#.)dd0root13 root.Code#.)dd0cart13 root.Code#.)dd0$ony13 t*.)fterSe ect R9 ne. 'reeNie.+*entUand er0)fterSe ectUand er13 Contro #.)dd0t*13 < pu$ ic *oid )fterSe ectUand er 0o$Dect #rc2 'reeNie.+*ent)rg# a1; 'reeCode #e 9 00'reeNie.1 #rc1.Se ectedCode3 Sy#te!.Con#o e.VriteLine0#e 13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. 'reeNie.:e!o"0113 < <//:8 -n the c*n#truct*r, a9ter a +reeHiew c*ntr*l i# initiali7ed, three +ree,ode# are created) The root n*de i# added t* the ,odes c*llecti*n *9 the +reeHiew) The 3ranch n*de# cart and bony are added t* the ,odes c*llecti*n, n*t *9 the +reeHiew, 3ut *9 the root n*de) = +reeHiew&vent"andler delegate i# created t* *utput the value *9 the #elected n*de t* the C*n#*le) The delegate i# added t* the +reeHiew# 'fter#elect event P the +reeHiew ha# a d*7en uniDue event# relating t* n*de #electi*n, c*llap#ing and e;panding, and change# t* the ite+# check3*; Git#el9 an *pti*nal pr*pertyH)
66#
List8iew
ListHiew +ay 9inally replace +reeHiew a# I+*#t di#cu##ed U- !idget)J The ListHiew i# an in#anely cu#t*+i7a3le !idget that i# #i+ilar t* the rightEhand #ide *9 ,ind*!# E;pl*rer P ite+# placed !ithin a ListHiew can 3e vie!ed in a detail vie!, a# a li#t, and a# grid# *9 large *r #+all ic*n#) Like the +reeHiew, the ListHiew u#e# a 3a#ic c*ntain+ent +*del1 a +reeHiew c*ntain# a c*llecti*n *9 ListHiewBtem# !hich d* n*t the+#elve# have event#) The ListHiewBtem# are added t* the Btems pr*perty *9 the ListHiew) Cari*u# pr*pertie# *9 the ListHiew and the individual ListHiewBtem# c*ntr*l the vari*u# di#play#)
Icon 8iews
The ListHiew c*ntain# t!* BmageList#, !hich h*ld ic*n# G*r *ther #+all graphic#H that can 3e a##*ciated !ith di99erent type# *9 ListHiewBtem#) One BmageList #h*uld 3e a##igned t* the #mallBmageList and the *ther t* the LargeBmageList pr*perty *9 the ListHiew) C*rre#p*nding i+age# #h*uld 3e added t* 3*th BmageList# at the #a+e *99#et#, #ince the #electi*n *9 either BmageList i# deter+ined 3y the ListHiewBtem# BmageBndex pr*perty) -n *ther !*rd#, i9 the ListHiewBtem6BmageBndex i# #et t* /, i9 ListHiew6Hiew i# #et t* ListHiew6LargeBcon the &th i+age in LargeBmageList !ill 3e di#played 9*r that ListHiewBtem, !hile i9 ListHiew6Hiew II Hiew6#mallBcon, the &th i+age in #mallBmageList !ill 3e di#played)
4etails 8iew
The detail# vie! *9 a ListHiew c*n#i#t# *9 a #erie# *9 c*lu+n#, the 9ir#t *9 !hich di#play# the ListHiewBtem and it# a##*ciated ic*n 9r*+ the #mallBmageList) Su3#eDuent c*lu+n# di#play te;t de#cri3ing vari*u# a#pect# related t* the ListHiewBtem) The te;t di#played 3y the 2nd and #u3#eDuent c*lu+n# i# deter+ined 3y the c*llecti*n *9 ListHiew#ubBtem# in the ListHiewBtem# #ubBtems pr*perty) The c*lu+n header te;t i# #et !ith the ListHiew6Columns pr*perty) The pr*gra++er i# re#p*n#i3le 9*r c**rdinating the c*n#i#tency *9 c*lu+n header *99#et# and the indice# *9 ListHiew#ubBtem#)
66&
Thinking in C
www.ThinkingIn.!et
Thi# e;a+ple de+*n#trate# the ListHiew# vari*u# +*de#) //:c"T:Li#tNie.:e!o.c# //:e!on#trate# the Li#tNie. contro u#ing Sy#te!3 u#ing Sy#te!.5O3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Li#tNie.:e!o : Hor!; Li#tNie. *3 Li#tNie.:e!o01; //Set up contro pane -ane p 9 ne. -ane 013 RadioButtonJK $tn 9 ne. RadioButtonJK; ne. RadioButton012 ne. RadioButton012 ne. RadioButton012 ne. RadioButton01 <3 $tnJ0K.Chec%ed 9 true3 $tnJ0K.'ext 9 &:etai #&3 $tnJ"K.'ext 9 &Large 5con#&3 $tnJ2K.'ext 9 &Li#t&3 $tnJTK.'ext 9 &S!a 5con#&3 for0int i 9 03 i W E3 iRR1; $tnJiK.Location 9 ne. -oint0"02 20 = 0i R "113 $tnJiK.Chec%edChanged R9 ne. +*entUand er0Se ectNie.13 < p.Contro #.)ddRange0$tn13 p.:oc% 9 :oc%Sty e.Left3 p.Vidth 9 "003 Sp itter # 9 ne. Sp itter013 #.:oc% 9 :oc%Sty e.Left3 //Li#tNie. initia #tuff * 9 ne. Li#tNie.013 *.:oc% 9 :oc%Sty e.Hi 3
66'
*.Co u!n#.)dd0 &Hi e Ca!e&2 "P02 UoriMonta ) ign!ent.Left13 *.Co u!n#.)dd0 &SiMe&2 "P02 UoriMonta ) ign!ent.Left13 *.Nie. 9 Nie..:etai #3 //Load i!age# 5!age #!a CS 9 5!age.Hro!Hi e0&c#X#!.$!p&13 5!age #!a +xe 9 5!age.Hro!Hi e0&exeX#!.$!p&13 5!ageLi#t i 9 ne. 5!ageLi#t013 i .5!age#.)dd0#!a CS13 i .5!age#.)dd0#!a +xe13 *.S!a 5!ageLi#t 9 i 3 5!age argeCS 9 5!age.Hro!Hi e0&c#X rg.$!p&13 5!age arge+xe 9 5!age.Hro!Hi e0&exeX rg.$!p&13 5!ageLi#t i 2 9 ne. 5!ageLi#t013 i 2.5!age#.)dd0 argeCS13 i 2.5!age#.)dd0 arge+xe13 *.Large5!ageLi#t 9 i 23 :irectory5nfo dir 9 ne. :irectory5nfo0&.&13 foreach0Hi e5nfo f in dir._etHi e#0&=.=&11; #tring fCa!e 9 f.Ca!e3 #tring #iMe 9 f.Length.'oString013 #tring ext 9 f.+xten#ion3 Li#tNie.5te! ite! 9 ne. Li#tNie.5te!0fCa!e13 if0ext 99 &.c#&1; ite!.5!age5ndex 9 03 <e #e; ite!.5!age5ndex 9 "3 < ite!.Su$5te!#.)dd0#iMe13 *.5te!#.)dd0ite!13 < Contro #.)dd0 *13 Contro #.)dd0#13 Contro #.)dd0p13 Vidth 9 ?E03
6#(
Thinking in C
www.ThinkingIn.!et
< pu$ ic *oid Se ectNie.0O$Dect #rc2 +*ent)rg# ea1; RadioButton r$ 9 0RadioButton1 #rc3 #tring *ie.:e#ired 9 r$.'ext3 #.itch0*ie.:e#ired1; ca#e &:etai #& : *.Nie. 9 Nie..:etai #3 $rea%3 ca#e &Large 5con#& : *.Nie. 9 Nie..Large5con3 $rea%3 ca#e &Li#t& : *.Nie. 9 Nie..Li#t3 $rea%3 ca#e &S!a 5con#& : *.Nie. 9 Nie..S!a 5con3 $rea%3 < < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Li#tNie.:e!o0113 < <//:8 The ListHiew$emo( ) c*n#truct*r de9ine# a !anel and *adioButton array t* #elect the vari*u# ListHiew6Hiew value#) = #plitter i# al#* de9ined t* all*! thi# panel t* 3e re#i7ed) The ListHiew lv i# created and it# $oc( pr*perty #et t* $oc(#tyle6:ill) ,e #peci9y that !hen the ListHiew i# #!itched t* detail# vie!, the t!* c*lu+n# !ill 3e la3eled I5ile a+eJ and ISi7e,J each !ill initially 3e 0'$ pi;el# !ide, and each !ill di#play it# te;t le9tEaligned) ,e then #et lv# initial vie! #tate t*, in 9act, 3e Hiew6$etails) The ne;t #ecti*n *9 the c*n#truct*r, la3eled IL*ad-+age#,J l*ad# #+all and then larger i+age#, and place# the c*rre#p*nding i+age# GcsAsm6bmp and csAlrg6bmp and exeAsm6bmp and exeAlrg6bmpH in BmageList# !hich are a##igned t* the ListHiew# #mallBmageList and LargeBmageList pr*pertie#)
6#1
The ListHiew i# p*pulated !ith the 9ile# in the current direct*ry) 5*r each 9ile 9*und, !e deter+ine the na+e, 9ile length, and e;ten#i*n and create a ListHiewBtem !ith it# I+ainJ +ext #et t* the 9ile# na+e) -9 the e;ten#i*n i# I)c#J !e #et that ListHiewBtem# BconBndex t* c*rre#p*nd t* the C# i+age# in the ListHiew# BmageList#, *ther!i#e !e #et the inde; t* 0) The string value repre#enting the 9ile# length i# added t* the #ubBtems c*llecti*n *9 the ListHiewBtem) The ListHiewBtem it#el9 i# al!ay# the $irst ite+ in the #ubBtems li#tQ in thi# ca#e that !ill appear in the I5ile a+eJ c*lu+n *9 the +reeHiew) The siTe #tring !ill appear in the second c*lu+n *9 the +reeHiew, under the ISi7eJ heading) The la#t p*rti*n *9 the c*n#truct*r add# the Control# t* the ListHiew$emo 9*r+ in the appr*priate *rder Gre+e+3er, 3ecau#e there# a #plitter inv*lved, the #plitter +u#t 3e added t* the 9*r+ i++ediately 3e9*re the !anel it re#i7e#H) The #electHiew( ) delegate +eth*d, called 3y the #electionChanged event *9 the *adioButton#, #et# ListHiew6Hiew t* the appr*priate value 9r*+ the Hiew enu+erati*n)
Cli$+oard
O34ect# *n the Clip3*ard are #upp*#ed t* 3e a3le t* tran#9*r+ the+#elve# int* a variety *9 9*r+at#, depending *n !hat the pa#ting applicati*n !ant#) 5*r in#tance, a vect*r dra!ing placed *n the Clip3*ard #h*uld 3e a3le t* tran#9*r+ it#el9 int* a 3it+ap 9*r Paint *r a Scala3le Cect*r >raphic# d*cu+ent 9*r an BAL edit*r) ?ata tran#9er in ,ind*!# 5*r+# i# +ediated 3y cla##e# !hich i+ple+ent the B$ata1b)ect inter9ace) = c*n#u+ing applicati*n *r Control 9ir#t get# a re9erence t* the Clipboard# current B$ata1b)ect 3y calling the #tatic +eth*d
6#)
Thinking in C
www.ThinkingIn.!et
Clipboard6 et$ata1b)ect( )) Once in hand, the B$ata1b)ect +eth*d et$ata!resent( ) i# called !ith the de#ired type in a string *r +ype argu+ent) -9 the B$ata1b)ect can tran#9*r+ it#el9 int* the reDue#ted type, et$ata!resent( ) return# true, and et$ata( ) can then 3e u#ed t* retrieve the data in the reDue#ted 9*r+) -n thi# e;a+ple, *ne Button place# a string *n the Clip3*ard, and the *ther 3utt*n put# the Clip3*ard# c*ntent Gi9 availa3le a# a stringH int* a Label) -9 y*u c*py an i+age *r *ther +edia that cann*t 3e tran#9*r+ed int* a string *nt* the Clip3*ard and atte+pt t* pa#te it !ith thi# pr*gra+, the la3el !ill di#play I *thing)J //:c"T:C ip$oard:e!o.c# //Cut# to and pa#te# fro! the #y#te! C ip$oard u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.'hreading3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## C ip$oard:e!o : Hor! ; La$e 3 C ip$oard:e!o01; Button $ 9 ne. Button013 $.Location 9 ne. -oint0"02 "013 $.'ext 9 &C ip&3 $.C ic% R9 ne. +*entUand er0)dd'oC ip$oard13 Contro #.)dd0$13 Button $2 9 ne. Button013 $2.Location 9 ne. -oint0"002 "013 $2.'ext 9 &-a#te&3 $2.C ic% R9 ne. +*entUand er0CopyHro!C ip13 Contro #.)dd0$213 9 ne. La$e 013 .'ext 9 &Cothing&3 .Location 9 ne. -oint0"002 P013 .SiMe 9 ne. SiMe02002 2013
6#3
Contro #.)dd0 13 < pu$ ic *oid )dd'oC ip$oard0O$Dect #2 +*ent)rg# a1; C ip$oard.Set:ataO$Dect0&'ext. On c ip$oard.&13 < pu$ ic *oid CopyHro!C ip0O$Dect #2 +*ent)rg# a1; 5:ataO$Dect o 9 C ip$oard._et:ataO$Dect013 if0o._et:ata-re#ent0typeof0#tring111; .'ext 9 o._et:ata0typeof0#tring11.'oString013 <e #e; .'ext 9 &Cothing&3 < < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. C ip$oard:e!o0113 < <//:8 *thing unu#ual i# d*ne in the Clipboard$emo( ) c*n#truct*rQ the *nly thing #*+e!hat di99erent 9r*+ *ther de+*# i# that the Label l i# +ade an in#tance varia3le #* that !e can #et it# c*ntent# in the Copy:romClip( ) +eth*d) The 'dd+oClipboard( ) +eth*d take# an ob)ect, in thi# ca#e a string) -9 the Clip3*ard i# given a string *r Bmage, that value can 3e pa#ted int* *ther applicati*n# Gu#e *ich+extBox6*tf *r #elected*tf 9*r pa#ting int* Aicr*#*9t ,*rdH) Copy:romClip( ) +u#t 3e a little cauti*u#, a# there i# n* guarantee that the Clip3*ard c*ntain# data that can 3e turned int* a string Gevery ) ET 5ra+e!*rk ob)ect can 3e turned int* a string, 3ut the Clip3*ard +ay very !ell c*ntain data that i# n*t a ) ET 5ra+e!*rk ob)ectH) -9 the B$ata1b)ect in#tance can indeed 3e e;pre##ed a# a string, !e retrieve it, again #peci9ying string a# the type !ere l**king 9*r) Even th*ugh !eve #peci9ied the type in the argu+ent, !e #till need t* change the return value *9 et$ata( ) 9r*+ ob)ect t* string, !hich !e d* 3y calling the +o#tring( ) +eth*d G!e c*uld al#* have u#ed a (string) ca#tH)
6#4
Thinking in C
www.ThinkingIn.!et
6#5
3y !riting t* the C*n#*le) *! !e need t* de9ine an B$ata1b)ect i+ple+entati*n that i# ver#atile en*ugh t* de+*n#trate #uper lo1 //0continuation1 //:c"T:Super_ oGo*er.c# //Cu#to! 5:ataO$Dect2 can expo#e Super_ o a#: //H oorVax2 :e##ert'opping2 or text c a## Super_ oGo*er : 5:ataO$Dect ; //Concern ": Vhat for!at# are #upportedY pu$ ic #tringJK _etHor!at#01 ; return ne. #tringJK; &H oorVax&2 &:e##ert'opping&2 &Super_ o&<3 < pu$ ic #tringJK _etHor!at#0$oo autoCon*ert1 ; if 0autoCon*ert1 ; return ne. #tringJK; &H oorVax&2 &:e##ert'opping&2 &Super_ o&2 :ataHor!at#.'ext<3 < e #e ; return _etHor!at#013 < < //Concern 2: Setting the data //Storage Super_ o #uperg o3 pu$ ic *oid Set:ata0o$Dect o1 ; if 0o i# Super_ o1 ; #uperg o 9 0Super_ o1 o3 < < pu$ ic *oid Set:ata0#tring f!t2 o$Dect o1 ; if 0f!t 99 &H oorVax& SS f!t 99 &:e##ert'opping& SS f!t 99 &Super_ o&1 ; Set:ata0o13 < e #e ;
6#6
Thinking in C
www.ThinkingIn.!et
if 0f!t 99 :ataHor!at#.'ext1 ; #uperg o 9 ne. Super_ o013 < e #e ; Sy#te!.Con#o e.VriteLine0 &Can't #et data to type & R f!t13 < < < pu$ ic *oid Set:ata0'ype t2 o$Dect o1 ; Set:ata0t.Ca!e2 o13 < pu$ ic *oid Set:ata 0String f!t2 $oo con*ert2 o$Dect o1 ; if 0f!t 99 :ataHor!at#.'ext @@ con*ert 99 fa #e1 ; Sy#te!.Con#o e.VriteLine0 &Refu#ing to change a #tring & R &to a #uperg o&13 < e #e ; Set:ata0f!t2 o13 < < //Concern T: 5# there a for!at c ient can u#eY pu$ ic $oo _et:ata-re#ent0#tring f!t1 ; if 0f!t 99 &:e##ert'opping& SS f!t 99 &H oorVax& SS f!t 99 :ataHor!at#.'ext SS f!t 99 &Super_ o&1 ; return true3 < e #e ; return fa #e3 < < pu$ ic $oo _et:ata-re#ent0'ype t1 ; return0_et:ata-re#ent0t.Ca!e113 < pu$ ic $oo _et:ata-re#ent
6##
0String f!t2 $oo con*ert1 ; if 0f!t 99 :ataHor!at#.'ext @@ con*ert 99 fa #e1 ; return fa #e3 < e #e ; return _et:ata-re#ent0f!t13 < < //Concern E: _et the data in re7ue#ted for!at pu$ ic o$Dect _et:ata0#tring f!t1 ; #.itch 0f!t1 ; ca#e &H oorVax& : return #uperg o3 ca#e &:e##ert'opping& : return #uperg o3 ca#e &Super_ o& : return #uperg o3 ca#e &'ext& : return &Super_ o 66 5t'# a H oorVax! & R &)nd a de##ert topping!&3 defau t : Con#o e.VriteLine0 &Super_ o i# !any thing#2 $ut not a & R f!t13 return nu 3 < < pu$ ic o$Dect _et:ata0'ype t1 ; #tring f!t 9 t.Ca!e3 return _et:ata0f!t13 < pu$ ic o$Dect _et:ata0#tring f!t2 $oo if 0f!t 99 :ataHor!at#.'ext @@ con*ert 99 fa #e1 ; return nu 3 < e #e ; return _et:ata0f!t13 < con*ert1 ;
6#&
Thinking in C
www.ThinkingIn.!et
< <//:8 0exa!p e continue# .ith :rag)nd:rop:e!o.c#1 T* i+ple+ent B$ata1b)ect, y*u +u#t addre## & c*ncern#1 !hat are the 9*r+at# that are #upp*rted, #etting the data, i# the data in a 9*r+at the client can u#e, and getting the data in the #peci9ic 9*r+at the client !ant#) The 9ir#t c*ncern i# addre##ed 3y the t!* *verl*aded et:ormats( ) +eth*d#) B*th return string array# !hich repre#ent the ) ET cla##e# int* !hich the #t*red data can 3e tran#9*r+ed) -n additi*n t* the type# !hich the #uper lo cla## actually in#tantiate#, !e al#* #peci9y that #uper lo can aut*+atically 3e c*nverted t*EandE9r*+ te;t) The $ata:ormats cla## c*ntain# al+*#t t!* d*7en #tatic pr*pertie# de9ining vari*u# Clip3*ard 9*r+at# that ,ind*!# 5*r+# already under#tand#) Setting the data i# d*ne, in the #i+ple#t ca#e, 3y pa##ing in an ob)ect, !hich i# #t*red in the in#tance varia3le superglo) -9 a per#*n atte+pt# t* #t*re a n*nE#uper lo *34ect, the reDue#t !ill 3e Duietly ign*red) The ) ET d*cu+entati*n i# #ilent *n !hether #et$ata( ) #h*uld thr*! an e;cepti*n i9 called !ith an argu+ent *9 the !r*ng typeQ and typically #ilence +ean# that *ne #h*uld not thr*! an e;cepti*n) Thi# g*e# again#t the grain *9 g**d pr*gra++ing practice Gu#ually, the argu+ent t* a +eth*d #h*uld al!ay# either a99ect the return value *9 the +eth*d, a99ect the #tate *9 the *34ect *r the #tate *9 the argu+ent, *r re#ult in an e;cepti*nH) The #ec*nd #et$ata( ) +eth*d take# a string repre#enting a data 9*r+at and an *34ect) -9 the string i# any *ne *9 the native type# *9 #uper lo GISuper>l*J, I?e##ertJ, *r I5l**r,a;JH, the *34ect i# pa##ed t* the #et$ata(ob)ect) +eth*d) -9 the string i# #et t* $ata:ormats6+ext, a ne! #uper lo i# in#tantiated and #t*red) -9 the string i# n*t *ne *9 the#e 9*ur value#, a diagn*#tic i# printed and the +eth*d 9ail#) The third #et$ata( ) +eth*d take# a +ype a# it# 9ir#t argu+ent and #i+ply pa##e# that argu+ent# ,ame pr*perty 9*r!ard t* #et$ata(string, ob)ect)) The 9*urthEandE9inal #et$ata( ) +eth*d take#, in additi*n t* a 9*r+at string and the data ob)ect it#el9, a bool that +ay 3e u#ed t* turn *99 aut*Ec*nver#i*n Gin thi# ca#e, the Ic*nver#i*nJ 9r*+ $ata:ormat6+ext that 4u#t in#tantiate# a ne! #uper loH)
6#'
The et$ata!resent( ) +eth*d# return true i9 the argu+ent i# *ne *9 the #uper lo type# *r $ata+ypes6+ext Ge;cept i9 the convert argu+ent i# #et t* falseH) The et$ata( ) +eth*d return# a re9erence t* the #t*red #uper lo i9 the 9*r+at reDue#ted i# ISuper>l*J, I5l**r,a;J, *r I?e##ertT*pping)J -9 the 9*r+at reDue#ted i# ITe;t,J the +eth*d return# a pr*+*ti*nal re9erence) -9 anything el#e, et$ata( ) return# a null re9erence) *! that !e have the d*+ain *34ect# and #uper lo.over, !e can put it all t*gether vi#ually1 //0continuation1 //:c"T::rag)nd:rop:e!o.c# //:e!on#trate# drag6and6drop .ith Super_ o and //Super_ oGo*er u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## :rag)nd:rop:e!o : Hor! ; :rag)nd:rop:e!o01 ; C ientSiMe 9 ne. SiMe0?E02 T2013 'ext 9 &:rag @ :rop&3 Button $ 9 ne. Button013 $.'ext 9 &-ut Super_ o on c ip$oard&3 $.Location 9 ne. -oint0"02 E013 $.Vidth 9 "003 $.C ic% R9 ne. +*entUand er0On-utSuper_ o13 -ictureBox p$ 9 ne. -ictureBox013 p$.5!age 9 5!age.Hro!Hi e0\&.^#uperg o.Dpg&13 p$.SiMeGode 9 -ictureBoxSiMeGode.)utoSiMe3 p$.Location 9 ne. -oint02202 "0013 p$.Gou#e:o.n R9 ne. Gou#e+*entUand er0OnBegin:rag13 -ane f oor 9 ne. -ane 013 f oor.BorderSty e 9 BorderSty e.HixedT:3 f oor.Location 9 ne. -oint0"02 I013
6&(
Thinking in C
www.ThinkingIn.!et
La$e f 9 ne. La$e 013 f.'ext 9 &H oor&3 f oor.Contro #.)dd0f13 f oor.) o.:rop 9 true3 f oor.:rag+nter R9 ne. :rag+*entUand er0On:rag+nterH oorVax13 f oor.:rag:rop R9 ne. :rag+*entUand er0On:ropH oorVax13 -ane de##ert 9 ne. -ane 013 de##ert.BorderSty e 9 BorderSty e.HixedT:3 de##ert.Location 9 ne. -oint0T002 I013 La$e d 9 ne. La$e 013 d.'ext 9 &:e##ert&3 de##ert.Contro #.)dd0d13 de##ert.) o.:rop 9 true3 de##ert.:rag+nter R9 ne. :rag+*entUand er0 On:rag+nter:e##ert'opping13 de##ert.:rag:rop R9 ne. :rag+*entUand er0On:rop:e##ert'opping13 'extBox text'arget 9 ne. 'extBox013 text'arget.Vidth 9 E003 text'arget.Location 9 ne. -oint0"202 2P013 text'arget.) o.:rop 9 true3 text'arget.:rag+nter R9 ne. :rag+*entUand er0On:rag+nter'ext13 text'arget.:rag:rop R9 ne. :rag+*entUand er0On:rop'ext13 Contro #.)ddRange0 ne. Contro JK; $2 p$2 f oor2 de##ert2 text'arget<13 < pri*ate *oid On-utSuper_ o0o$Dect #2 +*ent)rg# a1; Super_ o #uperg o 9 ne. Super_ o013 Super_ oGo*er !o*er 9 ne. Super_ oGo*er013 !o*er.Set:ata0#uperg o13
6&1
C ip$oard.Set:ataO$Dect0!o*er13 < pri*ate *oid OnBegin:rag 0o$Dect #2 Gou#e+*ent)rg# arg#1 ; Super_ oGo*er #g! 9 ne. Super_ oGo*er013 #g!.Set:ata0ne. Super_ o0113 00Contro 1 #1.:o:rag:rop0 #g!2 :rag:rop+ffect#.Copy 13 < pri*ate *oid On:rag+nterH oorVax 0o$Dect #2 :rag+*ent)rg# arg#1 ; if 0arg#.:ata._et:ata-re#ent0&H oorVax&11 ; arg#.+ffect 9 :rag:rop+ffect#.Copy3 < < pri*ate *oid On:ropH oorVax 0o$Dect #2 :rag+*ent)rg# arg#1 ; H oorVax f 9 0H oorVax1 arg#.:ata._et:ata0&H oorVax&13 f.-o i#h013 < pri*ate *oid On:rag+nter:e##ert'opping 0o$Dect #2 :rag+*ent)rg# arg#1 ; if0arg#.:ata._et:ata-re#ent0&:e##ert'opping&11 ; arg#.+ffect 9 :rag:rop+ffect#.Copy3 < < pri*ate *oid On:rop:e##ert'opping 0o$Dect #2 :rag+*ent)rg# arg#1 ; :e##ert'opping d 9 0:e##ert'opping1 arg#.:ata._et:ata 0&:e##ert'opping&13 d.+at013 <
6&)
Thinking in C
www.ThinkingIn.!et
pri*ate *oid On:rag+nter'ext 0o$Dect #2 :rag+*ent)rg# arg#1 ; if 0arg#.:ata._et:ata-re#ent0&'ext&11 ; arg#.+ffect 9 :rag:rop+ffect#.Copy3 < < pri*ate *oid On:rop'ext 0o$Dect #ender2 :rag+*ent)rg# arg#1 ; #tring # 9 0#tring1 arg#.:ata._et:ata0&'ext&13 00Contro 1#ender1.'ext 9 #3 < pu$ ic #tatic *oid Gain01 ; )pp ication.Run0ne. :rag)nd:rop:e!o0113 < < //:8 ,hen run, thi# applicati*n l**k# like thi#1
-9 y*u click *n the i+age, y*u can drag it t* either *9 the t!* !anel#, the +ext&dit di#play, *r int* a te;t edit*r #uch a# Aicr*#*9t ,*rd) =# y*u drag, the +*u#e cur#*r !ill change t* indicate !hether *r n*t the
6&3
#uper lo can 3e dr*pped) -9 y*u dr*p the #uper lo *n the I5l**rJ panel y*ull #ee *ne +e##age *n the c*n#*le, i9 *n the I?e##ertJ panel an*ther, and i9 in the +ext&dit 3*; *r in an*ther applicati*n, the pr*+*ti*nal +e##age !ill 3e pa#ted) -9 y*u click *n the 3utt*n, y*u can put a ne! #uper lo *n the Clip3*ard) The $rag'nd$rop$emo( ) c*n#truct*r #h*uld have n* #urpri#e# until !e add a .ouse&vent"andler *n 9*r the .ouse$own event *9 the !ictureBox c*ntr*l) That event !ill trigger the creati*n *9 a ne! #uper lo.over Ga# !ill the pre##ing *9 the Button)6 The !anel# 3*th have their 'llow$rop pr*perty #et t* true, #* !hen the +*u#e enter# the+ !hile dragging an *34ect, the +*u#e !ill give vi#ual 9eed3ack that a dr*p target i# 3eing traver#ed) =dditi*nally, the !anel# $rag&nter and $rag$rop event# are !ired t* event handler#) ,hen the 3utt*n i# pre##ed, it end# up calling 1n!ut#uper lo( )) = ne! #uper lo d*+ain *34ect i# created, a# i# a ne! #uper lo.over) The mover# data i# #et t* the 4u#tEcreated #uper lo and the mover i# placed *n the #y#te+ Clip3*ard) -n an*ther applicati*n #uch a# a te;t edit*r that accept# Clip3*ard te;t data, y*u #h*uld 3e a3le t* pa#te data) That *ther applicati*n !ill end up calling #uper lo.over6 et$ata( ) reDue#ting $ata+ype6+ext, re#ulting in the +e##age ISuper>l* P -t# a 5l**r,a;K =nd a de##ert t*ppingKJ 3eing pa#ted int* the *ther applicati*n) The +eth*d 1nBegin$rag( ) i# pretty #i+ilar t* 1n!ut#uper lo( ) 3ut a9ter the #uper lo.over i# in#tantiated, the +eth*d $o$rag$rop( ) i# called *n the originating Control) Thi# i# #*+e!hat c*n9u#ing, a# y*u +ight think that the de#tinati*n #h*uld 3e in charge, 3ut *n re9lecti*n it +ake# #en#e that the *riginat*r kn*!# the +*#t a3*ut the data, even !hen the data i# I9ar a!ayJ *n the #creen) There are #everal di99erent $rag$rop&ffects, !hich are 3it!i#e c*+3ina3leQ in thi# ca#e, the e99ect !e !ant i# t* c*py the data t* the target) B*th !anel# have very #i+ilar 1n$rag&nter"""( ) +eth*d#) The $rag&vent'rgs args ha# a $ata pr*perty that c*ntain# the #uper lo.over created in 1nBegin$rag( )6 Thi# $ata i# checked t* +ake #ure that it can pre#ent the appr*priate type GI5l**r,a;J *r
6&4
Thinking in C
www.ThinkingIn.!et
I?e##ertT*ppingJH and i9 #*, #etting the args6&ffect pr*perty +ake# the +*u#e #h*! the appr*priate vi#ual cue 9*r $rag$rop&ffects6Copy) Si+ilarly, 3*th !anel# have #i+ilar 1n$rop"""( ) +eth*d#) The $ata pr*perty Gthe #uper lo.overH ha# it# et$ata( ) +eth*d called !ith the de#ired type, either a :loor=ax *r $essert+opping) Thi# !ill return the #uper lo) Either :loor=ax6!olish( ) *r $essert+opping6&at( ) i# called, and the appr*priate +e##age printed *n the C*n#*le) The +extBox ha# #i+ilar 1n$rag&nter+ext( ) and 1n$rop+ext( ) +eth*d#, e;cept the #uper lo.over i# Dueried 9*r the ITe;tJ type)
4ata;+ound Controls
,ind*!# 5*r+# and =?O) ET c*+3ine t* +ake dataEdriven u#er inter9ace# very ea#y t* pr*gra+) -n Chapter #re9#, !e #a! h*! =?O) ET #eparate# the c*ncern# *9 +*ving data in and *ut 9r*+ a per#i#tent data#t*re 9r*+ the c*ncern# *9 +anipulating the inE+e+*ry $ata#et) Once a $ata#et i# p*pulated, in#tance# *9 the $ataBinding cla## +ediate 3et!een Control# and $ata#et#) One *9 the +*re i+pre##ive Control# 9*r di#playing data i# the $ata rid, !hich can di#play all the c*lu+n# in a ta3le) Thi# e;a+ple revi#it# the I *rth!ind)+d3J =cce## data3a#e1 //:c"T::ataBound:e!o.c# //:e!on#trate# the $a#ic# of data6$inding u#ing Sy#te!3 u#ing Sy#te!.:ata3 u#ing Sy#te!.:ata.O e:$3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## :ataBound:e!o : Hor! ; O e:$:ata)dapter adapter3 :ataSet e!p#3 :ataBound:e!o01; :ata_rid dg 9 ne. :ata_rid013 dg.:oc% 9 :oc%Sty e.Hi 3
6&5
Contro #.)dd0dg13 Read+!p oyee#0&CVind.!d$&13 dg.Set:ataBinding0e!p#2 &'a$ e&13 < pri*ate *oid Read+!p oyee#0#tring path'o)cce##:B1; O e:$Connection cnctn 9 ne. O e:$Connection013 cnctn.ConnectionString9 &-ro*ider9Gicro#oft.`+'.OL+:B.E.03& R &data #ource9& R path'o)cce##:B3 cnctn.Open013 #tring #e Str 9 &S+L+C' = HROG +G-LO/++S&3 adapter 9 ne. O e:$:ata)dapter0#e Str2 cnctn13 ne. O e:$Co!!andBui der0adapter13 e!p# 9 ne. :ataSet0&+!p oyee#&13 adapter.Hi 0e!p#13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. :ataBound:e!o0113 < <//:8 = $ata rid dg c*ntr*l i# created and #et #* that it !ill 9ill the entire client area *9 the $ataBound$emo 9*r+) Then, the *ead&mployees( ) +eth*d 9ill# the $ata#et emps, 4u#t a# in the e;a+ple# in Chapter #re9#) Once emps i# 9illed, the dg)#et$ataBinding( ) a##*ciate# the $ata rid !ith the ITa3leJ ta3le in emps, !hich in thi# ca#e i# the *nly ta3le in the $ata#et) The re#ult #h*!# the c*ntent# *9 the *rth!ind data3a#e1
6&6
Thinking in C
www.ThinkingIn.!et
Even +*re p*!er9ully, the Binding.anagerBase cla## can c**rdinate a #et *9 Binding#, all*!ing y*u t* have #everal Control# !h*#e data3*und pr*pertie# are #i+ultane*u#ly and tran#parently changed t* c*rre#p*nd t* a #ingle rec*rd in the $ata#et) Thi# e;a+ple all*!# y*u t* navigate thr*ugh the e+pl*yee data1 //:c"T:Corre#ponder.c# //:e!on#trate# ho. $ound contro # can $e !ade to !atch u#ing u#ing u#ing u#ing u#ing Sy#te!3 Sy#te!.:ra.ing3 Sy#te!.Vindo.#.Hor!#3 Sy#te!.:ata3 Sy#te!.:ata.O e:$3
c a## Corre#ponder : Hor! ; O e:$:ata)dapter adapter3 :ataSet e!p#3 Corre#ponder01; Read+!p oyee#0&CVind.!d$&13
6&#
La$e fCa!e 9 ne. La$e 013 fCa!e.Location 9 ne. -oint0"02 "013 Binding fBound 9 ne. Binding0&'ext&2 e!p#2 &'a$ e.Hir#tCa!e&13 fCa!e.:ataBinding#.)dd0fBound13 Contro #.)dd0fCa!e13 La$e Ca!e 9 ne. La$e 013 //! Ca!e.:ataBinding#.)dd0fBound13 Ca!e.Location 9 ne. -oint0"02 E013 Binding Bound 9 ne. Binding0&'ext&2 e!p#2 &'a$ e.La#tCa!e&13 Ca!e.:ataBinding#.)dd0 Bound13 Contro #.)dd0 Ca!e13 Button next 9 ne. Button013 next.Location 9 ne. -oint0"002 F013 next.'ext 9 &Z&3 next.C ic% R9 ne. +*entUand er0OnCext13 Contro #.)dd0next13 Button pre* 9 ne. Button013 pre*.Location 9 ne. -oint0"02 F013 pre*.'ext 9 &W&3 pre*.C ic% R9 ne. +*entUand er0On-re*13 Contro #.)dd0pre*13 < *oid OnCext0o$Dect #rc2 +*ent)rg# ea1; BindingGanagerBa#e !gr 9 BindingContextJe!p#2 &'a$ e&K3 !gr.-o#itionRR3 < *oid On-re*0o$Dect #rc2 +*ent)rg# ea1; BindingGanagerBa#e !gr 9 BindingContextJe!p#2 &'a$ e&K3 !gr.-o#ition663 <
6&&
Thinking in C
www.ThinkingIn.!et
pri*ate *oid Read+!p oyee#0 #tring path'o)cce##:B1; O e:$Connection cnctn 9 ne. O e:$Connection013 cnctn.ConnectionString9 &-ro*ider9Gicro#oft.`+'.OL+:B.E.03& R &data #ource9& R path'o)cce##:B3 cnctn.Open013 #tring #e Str 9 &S+L+C' = HROG +G-LO/++S&3 adapter 9 ne. O e:$:ata)dapter0#e Str2 cnctn13 ne. O e:$Co!!andBui der0adapter13 e!p# 9 ne. :ataSet0&+!p oyee#&13 adapter.Hi 0e!p#13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Corre#ponder0113 < <//:8 =9ter p*pulating the $ata#et emps 9r*+ the data3a#e, !e create a Label t* h*ld the 9ir#t na+e *9 the current e+pl*yee) = ne! Binding *34ect i# createdQ the 9ir#t para+eter #peci9ie# the na+e *9 the Pr*perty t* !hich the data !ill 3e 3*und G*9ten, thi# !ill 3e the ITe;tJ pr*pertyH , the #ec*nd the $ata#et that !ill 3e the data #*urce, and the third the #peci9ic c*lu+n in the $ata#et t* 3ind t*) Once the Binding i# created, adding it t* f,ame6Bindings #et# the Label# +ext pr*perty t* the $ata#et value) The c*++entedE*ut line i++ediately a9ter l,ame# c*n#truct*r call i# a call that !ill lead t* a runti+e e;cepti*n P Binding# cann*t 3e #hared 3et!een Control#) -9 y*u !i#h +ultiple c*ntr*l# t* re9lect the #a+e $ata#et value, y*u have t* create +ultiple Binding#, *ne 9*r each Control) = #i+ilar pr*ce## i# u#ed t* c*n9igure the l,ame la3el 9*r the la#t na+e, and t!* Button# are created t* pr*vide rudi+entary navigati*n) The Button# event handler# u#e the BindingContext# #tatic < > *perat*r *verl*ad !hich take# a $ata#et and a string repre#enting a data +e+3er) The data +e+3er in thi# ca#e i# the ITa3leJ re#ult) The
6&'
re#ulting Binding.anagerBase6!roperty value i# then incre+ented *r decre+ented !ithin the event handler) =# that happen#, the Binding.anagerBase update# it# a##*ciated Binding#, !hich in turn update their 3*und Control# !ith the appr*priate data 9r*+ the Binding# $ata#et6 Thi# diagra+ illu#trate# the #tatic #tructure *9 the relati*n#hip#)
:*ull n*tice that the Binding.anagerBase i# an a3#tract cla## in#tantiated 3y Currency.anager and !roperty.anager) -9 the call t* BindingContext<ob)ect, string> return# an ob)ect that i+ple+ent# BList, y*ull get a Currency.anager !h*#e !osition pr*perty +*ve# 3ack and 9*rth 3et!een ite+# in the BList Gthi# i# !hat !a# #h*!n in the e;a+pleQ +anipulating the !osition in the event handler #!itche# 3et!een e+pl*yee#H) -9 the call t* BindingContext<ob)ect, string> d*e# n*t return an *34ect i+ple+enting BList, a !roperty.anager i# returned)
6'(
Thinking in C
www.ThinkingIn.!et
#t*re, the B$ata'dapter i# re#p*n#i3le 9*r +ediating 3et!een the inE +e+*ry $ata#tore and the B$bConnection) Thi# e;a+ple de+*n#trate# updating the data3a#e, pr*vide# a +*re detailed l**k at the event# that *ccur during data 3inding, and illu#trate# a u#e9ul U- technigue 9*r +anipulating data3a#e# *r *ther large data #tructure#) The U- techniDue i# 3a#ed *n the pre+i#e that it +ay 3e e;pen#ive in ter+# *9 +e+*ry *r re#*urce# *r redra!ing t* have every edita3le p*rti*n *9 the #creen actually 2e edita3leQ rather, the Control that +anage# the editing pr*ce## i# dyna+ically p*#iti*ned *n the #creen at the in#erti*n p*int G*r, in thi# ca#e, !hen the +*u#e click# *n a dataE 3*und Label !hich !e !i#h t* editH) Thi# techniDue i# n*t !*rth the e99*rt *n #i+ple #creen#, 3ut really c*+e# int* it# *!n *n c*+ple; U-# #uch a# y*u +ight have *n a !*rd pr*ce##*r, #pread#heet, *r a !*rk9l*! applicati*n) -9 y*u u#e thi# techniDue, y*u #h*uld i+ple+ent it u#ing the P=C >U- architecture #* that the re#ult appear# a# a #ea+le## c*+p*nent) //:c"T:Hor!+dit.c# //:e!on#trate# data .rite fro! Hor! u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 u#ing Sy#te!.:ata3 u#ing Sy#te!.:ata.O e:$3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Hor!+dit : Hor!; Ua#hta$ e co HorLa$e 9 ne. Ua#hta$ e013 $oo editVindo.)cti*e 9 fa #e3 'extBox editVindo. 9 ne. 'extBox013 La$e a$e Being+dited 9 nu 3 O e:$:ata)dapter adapter3 :ataSet e!p#3 Hor!+dit01; Read+!p oyee#0&CVind.!d$&13 5nit:ataStructure013 5nitLa$e #013
6'1
5nitCo!!itter013 < pri*ate *oid 5nit:ataStructure01; co HorLa$e Jne. La$e 01K 9 &Hir#tCa!e&3 co HorLa$e Jne. La$e 01K 9 &La#tCa!e&3 < pri*ate *oid 5nitLa$e #01; int x 9 "03 int y 9 "03 int y5ncre!ent 9 TP3 foreach0#tring co Ca!e in co HorLa$e .Na ue#1; //Biha#hta$ e . aeyHorNa ue01 not in i$rary foreach0La$e $ in co HorLa$e .aey#1; #tring aCo Ca!e 9 0#tring1 co HorLa$e J $ K3 if 0aCo Ca!e 99 co Ca!e1 ; //Right %ey 0 a$e 1 for *a ue 0co Ca!e1 5nitLa$e 0 $ 2 co Ca!e2 x2 y13 y R9 y5ncre!ent3 < < < < pri*ate *oid 5nitLa$e 0La$e $ 2 #tring co Ca!e2 int x2 int y1; $ .Location 9 ne. -oint0x2 y13 $ .C ic% R9 ne. +*entUand er0OnLa$e C ic%13 $ .'extChanged R9 ne. +*entUand er0On'extChange13 Contro #.)dd0 $ 13 #tring na*-ath 9 &'a$ e.& R co Ca!e3 Binding $ 9 ne. Binding0&'ext&2 e!p#2 na*-ath13 $.-ar#e R9 ne. Con*ert+*entUand er0OnBound:ataChange13 $ .:ataBinding#.)dd0$13
6')
Thinking in C
www.ThinkingIn.!et
< pri*ate *oid 5nitCo!!itter01; Button $ 9 ne. Button013 $.Vidth 9 "203 $.Location 9 ne. -oint0"P02 "013 $.'ext 9 &Co!!it change#&3 $.C ic% R9 ne. +*entUand er0OnCo!!it13 Contro #.)dd0$13 < pu$ ic *oid OnLa$e C ic%0O$Dect #rc2 +*ent)rg# ea1; La$e #rcLa$e 9 0La$e 1 #rc3 if0editVindo.)cti*e1 Hina iMe+dit013 - ace+ditVindo.O*erLa$e 0#rcLa$e 13 )##ociate+ditorVithLa$e 0#rcLa$e 13 < pri*ate *oid - ace+ditVindo.O*erLa$e 0La$e $ 1; editVindo..Location 9 $ .Location3 editVindo..SiMe 9 $ .SiMe3 if0Contro #.Contain#0editVindo.1 99 fa #e1; Contro #.)dd0editVindo.13 < editVindo..Ni#i$ e 9 true3 editVindo..Bring'oHront013 editVindo..Hocu#013 editVindo.)cti*e 9 true3 < pri*ate *oid )##ociate+ditorVithLa$e 0La$e editVindo..'ext 9 .'ext3 a$e Being+dited 9 3 < 1;
pu$ ic *oid Hina iMe+dit01; Sy#te!.Con#o e.VriteLine0&Hina iMing edit&13 a$e Being+dited.'ext 9 editVindo..'ext3 Sy#te!.Con#o e.VriteLine0&'ext changed&13 //Ceeded to trigger $inding e*ent
6'3
a$e Being+dited.Hocu#013 editVindo..Ni#i$ e 9 fa #e3 editVindo..Send'oBac%013 editVindo.)cti*e 9 fa #e3 < pu$ ic *oid On'extChange0O$Dect #rc2 +*ent)rg# ea1; La$e $ 9 0La$e 1 #rc3 #tring co Ca!e 9 0#tring1 co HorLa$e J $ K3 Sy#te!.Con#o e.VriteLine0 co Ca!e R & ha# changed&13 < pu$ ic *oid OnBound:ataChange 0O$Dect #rc2 Con*ert+*ent)rg# ea1; Sy#te!.Con#o e.VriteLine0&Bound data changed&13 < pri*ate *oid OnCo!!it0O$Dect #rc2 +*ent)rg# ea1; Hina iMe+dit013 adapter.Opdate0e!p#13 < pri*ate *oid Read+!p oyee# 0#tring path'o)cce##:B1; O e:$Connection cnctn 9 ne. O e:$Connection013 cnctn.ConnectionString9 &-ro*ider9Gicro#oft.`+'.OL+:B.E.03& R &data #ource9& R path'o)cce##:B3 cnctn.Open013 #tring #e Str 9 &S+L+C' = HROG +G-LO/++S&3 adapter 9 ne. O e:$:ata)dapter0#e Str2 cnctn13 ne. O e:$Co!!andBui der0adapter13 e!p# 9 ne. :ataSet0&+!p oyee#&13 adapter.Hi 0e!p#13 < pu$ ic #tatic *oid Gain01;
6'4
Thinking in C
www.ThinkingIn.!et
)pp ication.Run0ne. Hor!+dit0113 < <//:8 The :orm&dit cla## ha# #everal in#tance varia3le#1 col:orLabel i# a "ashtable that i# u#ed t* e#ta3li#h a c*rre#p*ndence 3et!een a $ata#et c*lu+n na+e and a Label c*ntr*l) The ne;t / in#tance varia3le#, edit=indow'ctive, edit=indow, and labelBeing&dited are u#ed in the Idyna+icJ editing #che+e P all editing i# d*ne in the edit=indow +extBox, !hile a re9erence t* the editing target i# held in the labelBeing&dited varia3le) The adapter and emps varia3le# are the 9a+iliar varia3le# h*lding the B$ata'dapter and $ata#et a##*ciated !ith the *rth!ind data3a#e) The :orm&dit( ) c*n#truct*r initiali7e# emps and adapter in *ead&mployees( ), !hich d*e# n*t di99er 9r*+ the previ*u# e;a+ple#) Bnit$ata#tructure( ) initiali7e# the col:orLabel data #tructureQ an an*ny+*u# Label i# u#ed a# the key and the c*lu+n# na+e i# the value) One can i+agine a +*re #*phi#ticated ver#i*n *9 thi# +eth*d that iterate# *ver the $ata#et, creating a# +any Control# a# are nece##ary) BnitLabels( ) i# re#p*n#i3le 9*r #etting up the di#play *9 the data #tructure initiali7ed in Bnit$ata#tructure( )) Becau#e the ) ET 5ra+e!*rk d*e# n*t have a 3idirecti*nal ver#i*n *9 the B$ictionary inter9ace that can l**k up a key 3a#ed *n the value, !e have t* u#e a ne#ted l**p t* 9ind the Label a##*ciated !ith the col,ame) Once 9*und, BnitLabels( ) call# BnitLabel( ) t* c*n9igure the #peci9ic Label) =gain, a +*re #*phi#ticated ver#i*n *9 thi# +eth*d +ight d* a +*re #*phi#ticated 4*3 *9 laying *ut the di#play) BnitLabel( ) i# re#p*n#i3le 9*r !iring up the Label t* the $ata#et# c*lu+n na+e) T!* event handler# are added t* the Label1 1nLabelClic(( ) and 1n+extChange( )) The +eth*d al#* a##*ciate# 1nBound$ataChange( ) !ith the Binding# !arse event, !hich *ccur# !hen the value *9 a data3*und c*ntr*l change#) The Binding i# created 9r*+ the c*lu+n na+e that !a# pa##ed in a# an argu+ent and a##*ciated !ith the Label that !a# al#* pa##ed in) The la#t +eth*d called 3y the c*n#truct*r i# BnitCommitter( ), !hich initiali7e# a Button that !ill 3e u#ed t* trigger a data3a#e update)
6'5
=9ter the c*n#truct*r run#, the $ata#et emps i# 9illed !ith *rth!ind# e+pl*yee data and the Label# *n the &dit:orm #h*! the 9ir#t and la#t na+e *9 the 9ir#t rec*rd Gthi# e;a+ple d*e#nt have any navigati*nH) ,hen the u#er click# *n *ne *9 the#e la3el#, they activate 1nLabelClic(( )) =ll Label# *n the 9*r+ #hare the 1nLabelClic(( ) event handler, 3ut #i+ply ca#ting the src t* Label give# u# the needed in9*r+ati*n t* +anipulate the edit=indow) The 9ir#t ti+e thr*ugh 1nLabelClic(( ), the edit=indow'ctive B**lean !ill 3e false, #* let# +*+entarily delay di#cu##i*n *9 the :inaliTe&dit( ) +eth*d) Our dyna+ic editing techniDue i# t* place the editing c*ntr*l *n the U- at the appr*priate place, and then t* a##*ciate the editing c*ntr*l !ith the underlying data) !lace&dit=indow1verLabel( ) #et# the edit=indow t* *verlay the Label the u#er clicked *n, +ake# it vi#i3le, and reDue#t# the 9*cu#) 'ssociate&ditor=ithLabel( ) #et# the te;t *9 the editor=indow t* !hat i# in the underlying Label and #et# the labelBeing&dited in#tance varia3le t* the clickedE*n Label) The vi#ual e99ect *9 all thi# i# that !hen #*+e*ne click# *n either Label, it appear# a# i9 the Label turn# int* an &ditBox) =gain, thi# i# n* 3ig deal !ith t!* la3el# *n the 9*r+, 3ut i9 there !ere a c*uple d*7en 9ield# 3eing# di#played *n the #creen, there can 3e a #igni9icant re#*urce and #peed i+pr*ve+ent 3y having a #ingle, dyna+ic editing c*ntr*l) Since !lace&dit=indow1verLabel( ) #et edit=indow'ctive t* true, #u3#eDuent call# t* 1nLabelClic(( ) !ill call :inaliTe&dit( )) :inaliTe&dit( ) put# the te;t 9r*+ the edit=indow int* the underlying labelBeing&dited) Thi# al*ne does not u"date the $ataBinding, y*u +u#t give the la3el the 9*cu#, even 9*r a +*+ent, in *rder t* update the data) 1nBound$ataChanged( ) i# called #u3#eDuent t* the data update, and !hen run, y*ull #ee1 Hina iMing edit Hir#tCa!e ha# changed 'ext changed Bound data changed -ndicating thi# #eDuence1
6'6
Thinking in C
www.ThinkingIn.!et
The a3*ve diagra+ i# a UAL acti-it4 diagram and i# *ne *9 the +*#t help9ul diagra+# 9*r !hite3*ard #e##i*n# Ga# argued e99ectively 3y Sc*tt =+3ler at !!!)agile+*diling)*rg, y*u !ill derive +*re 3ene9it 9r*+ l*!E tech +*deling !ith *ther# than y*u can ever derive 9r*+ highEtech +*deling 3y y*ur#el9H) The activity diagra+ ha# ti+e *n the vertical a;i# and +e##age# and *34ect# *n the h*ri7*ntal) The 3*;e# *n the vertical line# c*rre#p*nd t* +eth*d inv*cati*n# and the call #tack) Thu#, this61nBound$ataChanged( ) i# called 9r*+ an an*ny+*u# Binding1b)ect# Vpdate( )8 +eth*d, !hich i# called 9r*+ labelBeing&dited6:ocus(), !hich !e call in this6:inaliTe&dit( )) =lth*ugh :inaliTe&dit( ) +*di9ie# the $ata#et emps, the call t* adapter6Vpdate( ) in 1nCommit( ) i# reDuired t* actually +*ve the data 3ack int* the data3a#e) Be #ure t* 3e 9a+iliar !ith =?O) ET#
2 =ctually, the na+e# and #eDuence *9 event# that happen in Control6:ocus( ) i#
c*n#idera3ly +*re c*+ple; than !hat i# p*rtrayed here, 3ut gl*##ing *ver detail# n*t relevant t* the ta#k at hand i# *ne *9 the great 3ene9it# *9 diagra++ing) Thi# i# *ne *9 the rea#*n# diagra++ing t**l# that dyna+ically 3ind t* actual #*urce c*de are *9ten le## u#e9ul than, #ay, a piece *9 paper)
6'#
*pti+i#tic c*ncurrency 3ehavi*r, a# di#cu##ed in chapter #ad*)net# 3e9*re engaging in any data3a#e pr*4ect#)
@enus
U#er inter9ace e;pert# #ay that +enu# are *verrated) Pr*gra++er#, !h* are trained t* think in ter+# *9 hierarchie#, and !h*#e career# are c*+puterEcentric, d*nt 3at an eye at ca#cading +enu *pti*n# and 9*ndly recall the ?OS day# !hen y*u c*uld #peci9y incredi3ly c*+ple; #pread#heet and !*rd pr*ce##ing 3ehavi*r# 3y rattling *99 the 9ir#t letter# *9 +enu #eDuence# Gn*!aday#, y*u have t* #ay IS* are y*u #eeing a dial*g that #ay# T?i#play Pr*pertie# and that ha# a 3unch *9 ta3#F Okay, 9ind the ta3 that #ay# T=ppearance and click *n it) ?* y*u #ee the 3utt*n that read# T=dvancedF -t #h*uld 3e in the l*!erEright c*rnerLJH) 5*r +any u#er#, th*ugh, +enu# are #urpri#ingly di99icult t* navigate) everthele##, unle## y*ure creating a purely ,e3E3a#ed inter9ace, the *dd# are Duite g**d that y*ull !ant t* add +enu# and c*nte;t +enu# t* y*ur U-#) There are t!* type# *9 +enu in ,ind*!# 5*r+#, a .ain.enu that di#play# acr*## the t*p *9 a :orm, and a Context.enu that can 3e a##*ciated !ith any Control and i# typically di#played *n a rightE3utt*n +*u#e click *ver the Control) B*th 9*r+# *9 +enu c*ntain .enuBtem# and .enuBtem# +ay, in turn, c*ntain *ther .enuBtem# G*nce again, the 9a+iliar c*ntain+ent +*del *9 ,ind*!# 5*r+#H ) ,hen #elected, the .enuBtem trigger# a Clic( event, even i9 the .enuBtem !a# ch*#en via a #h*rtcut *r acce## key) Thi# e;a+ple #h*!# 3*th type# *9 +enu# and h*! t* create ca#cading +enu#1 //:c"T:Genu:e!o.c# //:e!on#trate# !enu# u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Genu:e!o : Hor! ; Genu:e!o01;
6'&
Thinking in C
www.ThinkingIn.!et
'ext 9 &Genu :e!o&3 GainGenu cour#eGenu 9 ne. GainGenu013 Genu5te! appetiMer# 9 ne. Genu5te!013 appetiMer#.'ext 9 &@)ppetiMer#&3 Genu5te!JK #tarter# 9 ne. Genu5te!JTK3 #tarter#J0K 9 ne. Genu5te!013 #tarter#J0K.'ext 9 &@-ot #tic%er#&3 #tarter#J"K 9 ne. Genu5te!013 #tarter#J"K.'ext 9 &@Spring ro #&3 #tarter#J2K 9 ne. Genu5te!013 //Cote e#caped &@& #tarter#J2K.'ext 9 &@Uot @@ Sour Soup&3 appetiMer#.Genu5te!#.)ddRange0#tarter#13 foreach0Genu5te! i in #tarter#1; i.C ic% R9 ne. +*entUand er0OnCo!$ina$ eGenuSe ected13 < Genu5te! !ainCour#e 9 ne. Genu5te!013 !ainCour#e.'ext 9 &@Gain Cour#e&3 Genu5te!JK !ain 9 ne. Genu5te!JEK3 !ainJ0K 9 ne. Genu5te!013 !ainJ0K.'ext 9 &@S.eet @@ Sour -or%&3 !ainJ"K 9 ne. Genu5te!013 !ainJ"K.'ext 9 &@Goo #hu&3 !ainJ2K 9 ne. Genu5te!013 !ainJ2K.'ext 9 &@aung -ao Chic%en&3 //Out of aung -ao Chic%en !ainJ2K.+na$ ed 9 fa #e3 !ainJTK 9 ne. Genu5te!013 !ainJTK.'ext 9 &_enera '# Chic%en&3 !ainCour#e.Genu5te!#.)ddRange0!ain13 foreach0Genu5te! i in !ain1; i.RadioChec% 9 true3 i.C ic% R9 ne. +*entUand er0On+xc u#i*eGenuSe ected13 < Genu5te! *eg 9 ne. Genu5te!013
6''
*eg.'ext 9 &Negetarian&3 *eg.RadioChec% 9 true3 *eg.C ic% R9 ne. +*entUand er0On+xc u#i*eGenuSe ected13 Genu5te! por% 9 ne. Genu5te!013 por%.'ext 9 &-or%&3 por%.RadioChec% 9 true3 por%.C ic% R9 ne. +*entUand er0On+xc u#i*eGenuSe ected13 !ainJ"K.Genu5te!#.)ddRange0 ne. Genu5te!JK;*eg2por%<13 cour#eGenu.Genu5te!#.)dd0appetiMer#13 cour#eGenu.Genu5te!#.)dd0!ainCour#e13 ContextGenu contextGenu 9 ne. ContextGenu013 foreach0Genu5te! a in #tarter#1; contextGenu.Genu5te!#.)dd0a.C oneGenu0113 < contextGenu.Genu5te!#.)dd0 ne. Genu5te!01.'ext 9 &6&13 foreach0Genu5te! ! in !ain1; contextGenu.Genu5te!#.)dd0!.C oneGenu0113 < Genu 9 cour#eGenu3 ContextGenu 9 contextGenu3 < pri*ate *oid OnCo!$ina$ eGenuSe ected 0o$Dect #ender2 +*ent)rg# arg#1; Genu5te! #e ection 9 0Genu5te!1 #ender3 #e ection.Chec%ed 9 !#e ection.Chec%ed3 < pri*ate *oid On+xc u#i*eGenuSe ected 0o$Dect #ender2 +*ent)rg# arg#1; Genu5te! #e ection 9 0Genu5te!1 #ender3 $oo #e ect)fterC ear 9 !#e ection.Chec%ed3 //Gu#t i!p e!ent radio6$utton functiona ity progra!!atica y Genu parent 9 #e ection.-arent3
#((
Thinking in C
www.ThinkingIn.!et
foreach0Genu5te! i in parent.Genu5te!#1; i.Chec%ed 9 fa #e3 < #e ection.Chec%ed 9 #e ect)fterC ear3 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Genu:e!o0113 < <//:8 The .enu$emo( ) c*n#truct*r create# a #erie# .enuBtem#) The a+per#and G8H in the .enuBtem6+ext pr*perty #et# the accelerat*r key 9*r the ite+ G#* I=ltE=J !ill activate the I=ppeti7er#J +enu and I=ltEAJ the IAain C*ur#eJ +enuH) T* include an a+per#and in the +enu te;t, y*u +u#t u#e a d*u3le a+per#and G9*r in#tance, I"ot LL #our #oupJH) Each .enuBtem created i# added t* either the main.enu).enuBtems c*llecti*n *r t* the .enuBtems c*llecti*n *9 *ne *9 the *ther .enuBtem#) The .enuBtem# in the appetiTers .enu have the de9ault false value 9*r their *adioChec( pr*perty) Thi# +ean# that i9 their #election6Chec(ed pr*perty i# #et t* true, they !ill di#play a #+all check+ark) The .enuBtem# in mainCourse have *adioChec( #et t* true, and !hen they have #elected6Chec(ed #et t* true, they di#play a #+all circle) H*!ever, thi# i# a di#play *pti*n *nly, the +utual e;clu#i*n l*gic *9 a radi* 3utt*n +u#t 3e i+ple+ented 3y the pr*gra++er, a# i# #h*!n in the 1n&xclusive.enu#elected( ) +eth*d) = .enuBtem i# deactivated 3y #etting it# &nabled pr*perty t* 9al#e, a# i# d*ne !ith the INung Pa* ChickenJ entree) T* duplicate a .enu, y*u u#e n*t Clone( ) 3ut Clone.enu( ), a# #h*!n in the l**p# that p*pulate the context.enu) The context.enu al#* de+*n#trate# that a .enuBtem !ith it# +ext pr*perty #et t* a #ingle da#h i# di#played a# a #eparat*r 3ar in the re#ulting +enu)
#(1
'tandard 4ialogs
,ind*!# 5*r+# pr*vide# #everal #tandard dial*g# 3*th t* ea#e c*++*n ch*re# and +aintain c*n#i#tency 9*r the endEu#er) The#e dial*g# include 9ile *pen and #ave, c*l*r ch*ice, 9*nt dial*g#, and print previe! and print dial*g#) ,ere g*ing t* h*ld *99 *n the di#cu##i*n *9 the printing dial*g# until the #ecti*n *n printing in the >?-@ chapter, 3ut thi# e;a+ple #h*!# the ea#e !ith !hich the *ther# are u#ed1 //:c"T:Std:ia og#.c# u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Std:ia og# : Hor!; La$e a$e 9 ne. La$e 013 Std:ia og#01; GainGenu !enu 9 ne. GainGenu013 Genu 9 !enu3 Genu5te! fGenu 9 ne. Genu5te!0&@Hi e&13 !enu.Genu5te!#.)dd0fGenu13 Genu5te! oGenu 9 ne. Genu5te!0&@Open...&13 oGenu.C ic% R9 ne. +*entUand er0OnOpen13 fGenu.Genu5te!#.)dd0oGenu13 Genu5te! cGenu 9 ne. Genu5te!0&@Sa*e...&13 cGenu.C ic% R9 ne. +*entUand er0OnC o#e13 fGenu.Genu5te!#.)dd0cGenu13 fGenu.Genu5te!#.)dd0ne. Genu5te!0&6&113 Genu5te! opGenu 9 ne. Genu5te!0&@Option#&13 !enu.Genu5te!#.)dd0opGenu13 Genu5te! c rGenu 9 ne. Genu5te!0&@Co or...&13 c rGenu.C ic% R9 ne. +*entUand er0OnCo or13 opGenu.Genu5te!#.)dd0c rGenu13
#()
Thinking in C
www.ThinkingIn.!et
Genu5te! fntGenu 9 ne. Genu5te!0&@Hont...&13 fntGenu.C ic% R9 ne. +*entUand er0OnHont13 opGenu.Genu5te!#.)dd0fntGenu13 a$e .'ext 9 &So!e text&3 a$e .:oc% 9 :oc%Sty e.Hi Contro #.)dd0 a$e 13 < pu$ ic *oid OnOpen0o$Dect #rc2 +*ent)rg# ea1; OpenHi e:ia og ofd 9 ne. OpenHi e:ia og013 ofd.Hi ter 9 &C( fi e# 0=.c#1S=.c#S) fi e# 0=.=1S=.=&3 ofd.Hi ter5ndex 9 23 :ia ogRe#u t fi eCho#en 9 ofd.Sho.:ia og013 if0fi eCho#en 99 :ia ogRe#u t.Oa1; foreach0#tring fCa!e in ofd.Hi eCa!e#1; Con#o e.VriteLine0fCa!e13 < <e #e; Sy#te!.Con#o e.VriteLine0&Co fi e cho#en&13 < < pu$ ic *oid OnC o#e0o$Dect #rc2 +*ent)rg# ea1; Sa*eHi e:ia og #fd 9 ne. Sa*eHi e:ia og013 :ia ogRe#u t #a*eCho#en 9 #fd.Sho.:ia og013 if0#a*eCho#en 99 :ia ogRe#u t.Oa1; Con#o e.VriteLine0#fd.Hi eCa!e13 < < pu$ ic *oid OnCo or0o$Dect #rc2 +*ent)rg# ea1; Co or:ia og cd 9 ne. Co or:ia og013 if0cd.Sho.:ia og01 99 :ia ogRe#u t.Oa1; Co or c 9 cd.Co or3 a$e .HoreCo or 9 c3 Opdate013 < < 3
#(3
pu$ ic *oid OnHont0o$Dect #rc2 +*ent)rg# ea1; Hont:ia og fd 9 ne. Hont:ia og013 if0fd.Sho.:ia og01 99 :ia ogRe#u t.Oa1; Hont f 9 fd.Hont3 a$e .Hont 9 f3 Opdate013 < < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Std:ia og#0113 < <//:8 The #td$ialogs( ) c*n#truct*r initiali7e# a +enu #tructure and place# a Label *n the 9*r+) 1n1pen( ) create# a ne! 1pen:ile$ialog and #et# it# :ilter pr*perty t* #h*! either all 9ile# *r 4u#t th*#e !ith 6cs e;ten#i*n#) 5ile dial*g 9ilter# are c*n9u#ing) They are #peci9ied !ith a l*ng #tring, deli+ited !ith the pipe #y+3*l G[H) The di#played na+e# *9 the 9ilter# are placed in the *dd p*#iti*n#, !hile the 9ilter# the+#elve# are placed in the even p*#iti*n#) The :ilterBndex i# one92ased5 S* 3y #etting it# value t* 2, !ere #etting# it# value t* the b)b 9ilter, the 9*urth ite+ in the li#t) Like all the dial*g#, the 1pen:ile$ialog i# #h*!n !ith the #how$ialog( ) +eth*d) Thi# *pen# the dial*g in modal 9*r+Q the u#er +u#t cl*#e the +*dal dial*g 3e9*re returning t* any *ther kind *9 input t* the #y#te+) ,hen the dial*g i# cl*#ed, it return# a value 9r*+ the $ialog*esult enu+erati*n) $ialog*esult61E i# the h*pedE9*r valueQ *ther# are1 =3*rt Cancel -gn*re * *ne
#(4
Thinking in C
www.ThinkingIn.!et
Retry :e# O3vi*u#ly, n*t all dial*g# !ill return all G*r +*#tH *9 the#e value#) B*th the 1pen:ile$ialog and the #ave:ile$ialog have 1pen:ile( ) +eth*d# that *pen the #peci9ied 9ile G9*r reading *r !riting, re#pectivelyH, 3ut in the e;a+ple, !e 4u#t u#e the :ile,ames and :ile,ame pr*pertie# t* get the li#t *9 #elected 9ile# Gin 1n1pen( ) H and the #peci9ied 9ile t* 3e !ritten t* in 1n#ave( )) The #ave:ile$ialog61verwrite!rompt pr*perty, !hich de9ault# t* true, #peci9ie# !hether the dial*g !ill aut*+atically a#k the u#er I=re y*u #ureLFJ 1nColor( ) and 1n:ont( ) 3*th have appr*priate pr*pertie# GColor and :ontH that can 3e read a9ter the dial*g# cl*#e) The label i# changed t* u#e that value and then the Vpdate( ) +eth*d i# called in *rder t* redra! and relay*ut the #td$ialogs 9*r+)
>sage;Centered 4esign
-n the di#cu##i*n *9 >U- =rchitecture#, !e +enti*ned the adage that IT* the end u#er, the U- is the applicati*n)J Thi# i# *ne *9 the tenet# *9 usage9 centered design, an appr*ach t* #y#te+ devel*p+ent that 9it# very !ell !ith the +*ve t*!ard# agile de-elo"ment that pr*p*#e that #h*rter pr*duct cycle# Ga# #h*rt a# a 9e! !eek# 9*r internal pr*4ect#H that are inten#ely 9*cu#ed *n delivering reDue#ted endEu#er value are +uch +*re #ucce##9ul than the traditi*nal appr*ach *9 creating a 3alance *9 9uncti*nal, n*nE9uncti*nal, and +arketEdriven 9eature# that are relea#ed in I+a4*r r*llE*ut#)J 5ar t** +any di#cu##i*n# *9 #*9t!are devel*p+ent 9ail t* include the endE u#er, +uch le## acc*rd the+ the appr*priate re#pect a# the driver *9 !hat the applicati*n #h*uld d* and h*! it #h*uld appear) -+agine that *ne day y*u !ere given a #urvey *n y*ur eating ha3it# a# part *9 a +a4*r initiative t* pr*vide y*u a !*rldEcla## diet) Eighteen +*nth# later, !hen y*ud 9*rg*tten a3*ut the !h*le thing, y*ure given a #peci9ic 3reak9a#t, lunch, and dinner and t*ld that thi# !a# all y*u c*uld eat 9*r the ne;t eighteen
#(5
+*nth#) =nd that the +eal# !ere prepared 3y dietician#, n*t che9#, and that the +eal# had never actually 3een ta#ted 3y any*ne) That# h*! +*#t #*9t!are i# devel*ped) * inter9ace li3rary i# en*ugh t* +ake a u#a3le inter9ace) :*u must actively !*rk !ith end u#er# t* di#c*ver their need# Gy*ull *9ten help them di#c*ver the !*rd# t* e;pre## a need they a##u+ed c*uld n*t 3e 9i;edH , y*u must #ilently !atch endEu#er# u#ing y*ur #*9t!are Ga hu+3ling e;perienceH, and y*u must ev*lve the u#er inter9ace 3a#ed *n the need# *9 the u#er, n*t the ae#thetic !hi+# *9 a graphic de#igner/) One *9 u# GLarryH had the *pp*rtunity t* !*rk *n a pr*4ect that u#ed u#ageEcentered de#ign t* create ne! type# *9 cla##r**+ +anage+ent t**l# 9*r NE02 teacher# Ga gr*up that i# right9ully di#tru#t9ul *9 the technical Ig*lden 3ullet#J that are regularly 9*i#ted up*n the+H) The U- had l*t# *9 #tandard c*+p*nent#, and three cu#t*+ c*ntr*l#) T!* *9 the cu#t*+ c*ntr*l# !ere ne-er noticed 3y endEu#er# Gthey 4u#t u#ed the+, n*t reali7ing that they !ere #eeing c*+ple;, n*nE#tandard 3ehavi*rH) ,e c*uld al!ay# tell !hen u#er# #a! the third, th*ugh, 3ecau#e they literally gas"ed !hen they #a! it) -t !a# a heck *9 a g**d inter9ace&)
'u##ar5
C# ha# an *34ectE*riented 3*und +eth*d type called delegate) ?elegate# are 9ir#tEcla## type#, and can 3e in#tantiated 3y any +eth*d !h*#e #ignature e;actly +atche# the delegate type) There are #everal architecture# that +ay 3e u#ed t* #tructure the >U-, either a# an independent #u3#y#te+ *r 9*r the pr*gra+ a# a !h*le) The Ci#ual ?e#igner t**l in Ci#ual Studi* ) ET 9acilitate# an architecture called 5*r+EEventEC*ntr*l, !hich pr*vide# a +ini+al #eparati*n *9 the inter9ace 9r*+ the d*+ain l*gic) A*delECie!EC*ntr*ller pr*vide# the
/ Thi# i# n*t t* di#parage graphic de#igner# *r their !*rk) But creating a u#a3le inter9ace i#
nothing like creating a reada3le page *r an eyeEcatching adverti#e+ent) -9 y*u cant get a de#igner !ith a 3ackgr*und in C*+puterEHu+an -nteracti*n GCH-H, at lea#t u#e a de#igner !ith a 3ackgr*und in indu#trial de#ign)
& Un9*rtunately, the CEO #a! 9it t* #pend *ur U0',$$$,$$$ in venture capital *n
pr*#titute#, drug#, and a "aguar #edan !ith #atellite navigati*n 9*r the c*+pany car) Oh yeah, !e al#* had 9ree #*da)
#(6
Thinking in C
www.ThinkingIn.!et
+a;i+u+ #eparati*n *9 inter9ace, input, and d*+ain l*gic, 3ut i# *9ten +*re tr*u3le than it# !*rth) Pre#entati*nE=3#tracti*nEC*ntr*l i# an architecture that create# #el9Ec*ntained c*+p*nent# that are re#p*n#i3le 9*r 3*th their *!n di#play and d*+ain l*gicQ it i# *9ten the 3e#t ch*ice 9*r !*rking in ,ind*!# 5*r+#) ,ind*!# 5*r+# i# a !ellEarchitected cla## li3rary that #i+pli9ie# the creati*n *9 the va#t +a4*rity *9 u#er inter9ace#) -t i# pr*gra++ed 3y a #erie# *9 pu3lic delegate pr*pertie# called e-ents that are a##*ciated !ith individual Control#) Control# c*ntain *ther Control#) = :orm i# a type *9 Control that take# the 9*r+ *9 a !ind*!) Control# are laid *ut !ithin their c*ntaining Control 3y +ean# *9 the Location, $oc(, and 'nchor pr*pertie#) Thi# lay*ut +*del i# #i+ple, 3ut n*t #i+pli#tic, and i9 c*+3ined !ith a pr*per attenti*n t* >Uarchitecture, can lead t* ea#ily +*di9ied, ea#yEt*Eu#e u#er inter9ace#) Pr*pertie# *9 Control# can 3e 3*und t* value# !ithin a $ata#et via a c*llecti*n *9 Binding#) O9ten, the 3*und pr*perty i# the ITe;tJ pr*perty *9 the Control) = c*llecti*n *9 Binding# +ay 3e c**rdinated 3y a Binding.anagerBase pr*vided 3y a BindingContext) Such c**rdinated Binding# !ill re9er t* a #ingle data rec*rd *r #et *9 pr*pertie# and thu#, Control# 3*und t* th*#e Binding# !ill #i+ultane*u#ly update) ,hile ,ind*!# 5*r+# i# !ellEarchitected, there are +any Duirk# and inc*n#i#tencie# in the vari*u# Control#) The#e Duirk# range 9r*+ !hat are clearly de9ect# GChec(edListBox6Chec(edBndexCollection include ite+# !h*#e check#tate i# indeterminateH, t* de#ign 9la!# Gther #h*uld 3e a Control6+ooltip pr*pertyH, t* und*cu+ented 3ehavi*r# G!hen handed an *34ect *9 illegal type, #h*uld B$ata1b)ect6#et1b)ect( ) thr*! an e;cepti*nFH, t* 3ehavi*r# that re9lect an underlying Duirk in the *perating #y#te+ Gthe #tring that #peci9ie# 1pen:ile$ialog6:ilterH) Ci#ual Studi* ) ET +ake# the creati*n *9 ,ind*!# 5*r+# inter9ace very ea#y 3ut i# n* #u3#titute 9*r !*rking directly !ith the i+ple+enting c*de) A*#t real applicati*n# !ill u#e a c*+3inati*n *9 Ci#ual ?e#ignerE generated c*de and handE!ritten i+ple+entati*n#) One !ay *r the *ther, the #ucce## *9 y*ur applicati*n i# dependent *n the u#a3ility *9 y*ur
#(#
inter9aceQ i9 at all p*##i3le, !*rk !ith a c*+puterEhu+an inter9ace #peciali#t t* guide the creati*n *9 y*ur U-)
%&ercises
#(&
Thinking in C
www.ThinkingIn.!et
1 , G4IU Overview
,hile ,ind*!# 5*r+# pr*vide# a great 3a#i# 9*r #*+e large +a4*rity *9 u#er inter9ace#, the ) ET 5ra+e!*rk e;p*#e#
#('
u#ing Sy#te!.Vindo.#.Hor!#3 c a## -rinting : Hor! ; -aperVa#ter p. 9 ne. -aperVa#ter013 -rinting01; GainGenu !enu 9 ne. GainGenu013 Genu 9 !enu3 Genu5te! fGenu 9 ne. Genu5te!0&@Hi e&13 !enu.Genu5te!#.)dd0fGenu13 Genu5te! pr*Genu 9 ne. Genu5te!0&-@re*ie....&13 fGenu.Genu5te!#.)dd0pr*Genu13 pr*Genu.C ic% R9 ne. +*entUand er0On-re*ie.13 Genu5te! prtGenu 9 ne. Genu5te!0&@-rint...&13 fGenu.Genu5te!#.)dd0prtGenu13 prtGenu.C ic% R9 ne. +*entUand er0On-rint13 < pu$ ic *oid On-re*ie.0o$Dect #rc2 +*ent)rg# ea1; -rint-re*ie.:ia og ppd 9 ne. -rint-re*ie.:ia og013 ppd.:ocu!ent 9 p..:ocu!ent3 if0ppd.Sho.:ia og01 99 :ia ogRe#u t.Oa1; < < pu$ ic *oid On-rint0o$Dect #rc2 +*ent)rg# ea1;
#1(
-rint:ia og pd 9 ne. -rint:ia og013 pd.:ocu!ent 9 p..:ocu!ent3 if0pd.Sho.:ia og01 99 :ia ogRe#u t.Oa1; < < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. -rinting0113 < < c a## -aperVa#ter; -rint:ocu!ent pd 9 ne. -rint:ocu!ent013 interna -rint:ocu!ent :ocu!ent; get ; return pd3 < < interna -aperVa#ter01; pd.-rint-age R9 ne. -rint-age+*entUand er0-rint)-age13 < *oid -rint)-age0o$Dect #rc2 -rint-age+*ent)rg# ea1; _raphic# g 9 ea._raphic#3 Hont f 9 ne. Hont0&)ria &2 T?13 So idBru#h $ 9 ne. So idBru#h0Co or.B ac%13 -ointH p 9 ne. -ointH0"0.0f2 "0.0f13 g.:ra.String0&Reduce2 Reu#e2 Recyc e&2 f2 $2 p13 < <//:8
#11
)ccessing 4irectT Creating a screensvaer Creating a s5ste# service >sage;Centered 4esign Creating an a$$lication 1Windows I @enus2
)#+ient Pro$erties )$$lication )$$licationConte&t )&9ost %rrorProvider 7eature'u$$ort 9el$ @essage @essage3o& (oti05Icon
#1)
Thinking in C
www.ThinkingIn.!et
Progress 3ar Pro$ert5Grid 'election6ange -a+Control? -a++ed Pages -i#er -ool3ar -rac*3ar >serControl
1 , @ultithreaded Progra##ing
O34ect# divide the #*luti*n #pace int* l*gical chunk# *9 #tate and 3ehavi*r) O9ten, y*u need gr*up# *9 y*ur *34ect# t* per9*r+ their 3ehavi*r #i+ultane*u#ly, a# independent #u3ta#k# that +ake up the !h*le)
Each *9 the#e independent #u3ta#k# i# called a thread, and y*u pr*gra+ a# i9 each thread run# 3y it#el9 and ha# the CPU t* it#el9) S*+e underlying +echani#+ i# actually dividing up the CPU ti+e 9*r y*u, 3ut in general, y*u d*nt have t* think a3*ut it, !hich +ake# pr*gra++ing !ith +ultiple thread# a +uch ea#ier ta#k) = "rocess i# a #el9Ec*ntained running pr*gra+ !ith it# *!n addre## #pace) = multitasking *perating #y#te+ i# capa3le *9 running +*re than *ne pr*ce## Gpr*gra+H at a ti+e, !hile +aking it l**k like each *ne i# chugging al*ng *n it# *!n, 3y peri*dically pr*viding CPU cycle# t* each pr*ce##) = thread i# a #ingle #eDuential 9l*! *9 c*ntr*l !ithin a pr*ce##) = #ingle pr*ce## can thu# have +ultiple c*ncurrently e;ecuting thread#)
#15
There are +any p*##i3le u#e# 9*r +ultithreading, 3ut in general, y*ull have #*+e part *9 y*ur pr*gra+ tied t* a particular event *r re#*urce, and y*u d*nt !ant t* hang up the re#t *9 y*ur pr*gra+ 3ecau#e *9 that) S* y*u create a thread a##*ciated !ith that event *r re#*urce and let it run independently *9 the +ain pr*gra+) = g**d e;a+ple i# a IcancelJ 3utt*n t* #t*p a lengthy calculati*n Ry*u d*nt !ant t* 3e 9*rced t* p*ll the cancel 3utt*n in every piece *9 c*de y*u !rite in y*ur pr*gra+ and yet y*u !ant the cancel 3utt*n t* 3e re#p*n#ive, a# i9 y*u were checking it regularly) -n 9act, *ne *9 the +*#t i++ediately c*+pelling rea#*n# 9*r +ultithreading i# t* pr*duce a re#p*n#ive u#er inter9ace)
#16
.(%-s -hreading @odel -hread 'cheduling -hreading Pro+le#s -he Cardinal 6ules o0 -hreading -hread Li0ec5cle 'tarting -hreads 'to$$ing -hreads Pausing and 6estarting 3loc*ing and Waiting %&ce$tion 9andling in -hreads -hreads and Intero$era+ilit5
Cha"ter 15* Cistri2uted Com"uting #1#
-hreads and Gar+age Collection -hreads and 'cala+ilit5 6es$onsive user inter0aces
=# a #tarting p*int, c*n#ider a pr*gra+ that per9*r+# #*+e CPUEinten#ive *perati*n and thu# end# up ign*ring u#er input and 3eing unre#p*n#ive) Thi# *ne #i+ply c*ver# the di#play in a rand*+ patch!*rk *9 red #p*t#1 //Wexa!p eZ ///WchapterZGu tithreadedW/chapterZ ///Wprogra!ZCounter".c#W/progra!Z // ) non6re#pon#i*e u#er interface. u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.'hreading3 c a## Counter" : Hor! ; int nu!$er'oCount'o3 Counter"0int nu!$er'oCount'o1 ; thi#.nu!$er'oCount'o 9 nu!$er'oCount'o3 C ientSiMe 9 ne. Sy#te!.:ra.ing.SiMe0P002 T0013 'ext 9 &Conre#pon#i*e interface&3 Button #tart 9 ne. Button013 #tart.'ext 9 &Start&3 #tart.Location 9 ne. -oint0"02 "013 #tart.C ic% R9 ne. +*entUand er0StartCounting13 Button onOff 9 ne. Button013 onOff.'ext 9 &'ogg e&3 onOff.Location 9 ne. -oint0"02 E013 onOff.C ic% R9 ne. +*entUand er0StopCounting13
#1&
Thinking in C
www.ThinkingIn.!et
Contro #.)ddRange0ne. Contro JK; #tart2 onOff <13 < pu$ ic *oid StartCounting0O$Dect #ender2 +*ent)rg# arg#1 ; Rectang e $ound# 9 Screen._etBound#0thi#13 int .idth 9 $ound#.Vidth3 int height 9 $ound#.Ueight3 _raphic# g 9 _raphic#.Hro!U.nd0thi#.Uand e13 -en pen 9 ne. -en0Co or.Red2 "13 Rando! rand 9 ne. Rando!013 runH ag 9 true3 for 0int i 9 03 runH ag @@ i W nu!$er'oCount'o3 iRR1 ; //:o #o!ething !i d y ti!e6con#u!ing int x 9 rand.Cext0.idth13 int y 9 rand.Cext0height13 g.:ra.Rectang e0pen2 x2 y2 "2 "13 'hread.S eep0"013 < < $oo runH ag 9 true3
pu$ ic *oid StopCounting0O$Dect #ender2 +*ent)rg# arg#1; runH ag 9 fa #e3 < pu$ ic #tatic *oid Gain01 ; )pp ication.Run0ne. Counter"0"0000113 < < //W/exa!p eZ =t thi# p*int, the graphic# c*de #h*uld 3e rea#*na3ly 9a+iliar 9r*+ Chapter 0/) The startCounting( ) +eth*d i# !here the pr*gra+ #tay# 3u#y1 it l**p# number+oCount+o ti+e#, pick# a rand*+ #p*t *n the 9*r+, and dra!# a 0Epi;el rectangle their)
#1'
Part *9 the l**p in#ide startCounting( ) call# +hread6#leep( )) ) +hread6#leep() pau#e# the currently e;ecuting thread 9*r #*+e a+*unt *9 +illi#ec*nd#) Regardle## *9 !hether y*ure e;plicitly u#ing thread#, y*u can pr*duce the current thread u#ed 3y y*ur pr*gra+ !ith +hread and the #tatic #leep( ) +eth*d) ,hen the #tart 3utt*n i# pre##ed, startCounting( ) i# inv*ked) On e;a+ining startCounting( ), y*u +ight think that it #h*uld all*! +ultithreading 3ecau#e it g*e# t* #leep) That i#, !hile the +eth*d i# a#leep, it #ee+# like the CPU c*uld 3e 3u#y +*nit*ring *ther 3utt*n pre##e#) But it turn# *ut that the real pr*3le+ i# that startCounting( ) d*e#nt return until a$ter it# 9ini#hed, and thi# +ean# that stopCounting( ) i# never called until it# t** late 9*r it# 3ehavi*r t* 3e +eaning9ul) Since y*ure #tuck in#ide startCounting( ) 9*r the 9ir#t 3utt*n pre##, the pr*gra+ cant handle any *ther event#) GT* get *ut, y*u +u#t either !ait until startCounting() end#, *r kill the pr*ce##Q the ea#ie#t !ay t* d* thi# i# t* pre## C*ntr*lEC *r t* click a c*uple ti+e# t* trigger ,ind*!# IPr*gra+ *t Re#p*ndingJ dial*gue)H The 3a#ic pr*3le+ here i# that startCounting( ) need# t* c*ntinue per9*r+ing it# *perati*n#, and at the #a+e ti+e it need# t* return #* that stopCounting( ) can 3e activated and the u#er inter9ace can c*ntinue re#p*nding t* the u#er) But in a c*nventi*nal +eth*d like startCounting( ) it cann*t c*ntinue and at the #a+e ti+e return c*ntr*l t* the re#t *9 the pr*gra+) Thi# #*und# like an i+p*##i3le thing t* acc*+pli#h, a# i9 the CPU +u#t 3e in t!* place# at *nce, 3ut thi# i# preci#ely the illu#i*n that threading pr*vide#) The thread +*del Gand it# pr*gra++ing #upp*rt in C#H i# a pr*gra++ing c*nvenience t* #i+pli9y 4uggling #everal *perati*n# at the #a+e ti+e !ithin a #ingle pr*gra+) ,ith thread#, the CPU !ill p*p ar*und and give each thread #*+e *9 it# ti+e) Each thread ha# the c*n#ci*u#ne## *9 c*n#tantly having the CPU t* it#el9, 3ut the CPU# ti+e i# actually #liced 3et!een all the thread#) The e;cepti*n t* thi# i# i9 y*ur pr*gra+ i# running *n +ultiple CPU#) But *ne *9 the great thing# a3*ut threading i# that y*u are a3#tracted a!ay 9r*+ thi# layer, #* y*ur c*de d*e# n*t need t* kn*! !hether it i# actually running *n a #ingle CPU *r +any) Thu#, thread# are a !ay t* create tran#parently #cala3le pr*gra+#)
#)(
Thinking in C
www.ThinkingIn.!et
Threading reduce# c*+puting e99iciency #*+e!hat, 3ut the net i+pr*ve+ent in pr*gra+ de#ign, re#*urce 3alancing, and u#er c*nvenience i# *9ten Duite valua3le) O9 c*ur#e, i9 y*u have +*re than *ne CPU, then the *perating #y#te+ can dedicate each CPU t* a #et *9 thread# *r even a #ingle thread and the !h*le pr*gra+ can run +uch 9a#ter) Aultita#king and +ultithreading tend t* 3e the +*#t rea#*na3le !ay# t* utili7e +ultipr*ce##*r #y#te+#)
Creating -hreads
T* u#e Thread# in C#, y*u #i+ply create a +hread *34ect and a delegate called +hread#tart) +hread take# care# *9 the underlying creati*n and +anage+ent *9 the thread, !hile +hread#tart #peci9ie# the actual c*de that !ill 3e e;ecuted !hen the thread i# active) Thu#, !hatever +eth*d i# pa##ed t* the +hread#tart c*n#truct*r i# the c*de that !ill 3e e;ecuted I#i+ultane*u#lyJ !ith the *ther thread# in a pr*gra+) The 9*ll*!ing e;a+ple create# any nu+3er *9 thread# that it keep# track *9 3y a##igning each thread a uniDue nu+3er, generated !ith a static varia3le) The delegated 3ehavi*r i# in the run( ) +eth*d, !hich i# *verridden t* c*unt d*!n each ti+e it pa##e# thr*ugh it# l**p and 9ini#he# !hen the c*unt i# 7er* Gat the p*int !hen the delegated +eth*d return#, the thread i# ter+inatedH) //Wexa!p eZ ///WchapterZc"EW/chapterZ ///Wprogra!ZSi!p e'hreading.c#W/progra!Z // Nery #i!p e 'hreading exa!p e. u#ing Sy#te!.'hreading3 pu$ ic c a## Si!p e'hreading ; pri*ate int count:o.n 9 P3 pri*ate #tatic int threadCount 9 03 pri*ate int threadCu!$er 9 RRthreadCount3 pu$ ic Si!p e'hreading01 ; Sy#te!.Con#o e.VriteLine0&Ga%ing & R threadCu!$er13 < pu$ ic *oid run01 ; .hi e0true1 ; Sy#te!.Con#o e.VriteLine0&'hread & R
#)1
threadCu!$er R &0& R count:o.n R &1&13 if066count:o.n 99 01 return3 < < pu$ ic #tatic *oid Gain01 ; for0int i 9 03 i W P3 iRR1; Si!p e'hreading #t 9 ne. Si!p e'hreading013 'hread a'hread 9 ne. 'hread0 ne. 'hreadStart0#t.run113 a'hread.Start013 < Sy#te!.Con#o e.VriteLine0&) 'hread# Started&13 < < //W/exa!p eZ = threadEdelegate +eth*d G*9ten called run( )H virtually al!ay# ha# #*+e kind *9 l**p that c*ntinue# until the thread i# n* l*nger nece##ary, #* y*u +u#t e#ta3li#h the c*nditi*n *n !hich t* 3reak *ut *9 thi# l**p G*r, in the ca#e a3*ve, #i+ply return 9r*+ run( )H) O9ten, run( ) i# ca#t in the 9*r+ *9 an in9inite l**p, !hich +ean# that, 3arring #*+e e;ternal 9act*r that cau#e# run( ) t* ter+inate, it !ill c*ntinue 9*rever) -n .ain( ) y*u can #ee a nu+3er *9 thread# 3eing created and run) The #tart( ) +eth*d in the +hread cla## per9*r+# the initiali7ati*n 9*r the thread and then call# run( )) S* the #tep# are1 the c*n#truct*r i# called t* 3uild the *34ect that !ill d* the !*rk, the +hread#tart delegate i# given the na+e *9 the !*rking 9uncti*n, the +hread#tart i# pa##ed t* a ne!ly created +hread, then #tart( ) c*n9igure# the thread and call# the delegated 9uncti*n EE run( )) -9 y*u d*nt call #tart( ), the thread !ill never 3e #tarted) The *utput 9*r *ne run *9 thi# pr*gra+ Git !ill 3e di99erent 9r*+ *ne run t* an*therH i#1 Ga%ing Ga%ing Ga%ing 'hread 'hread 'hread 'hread 'hread " 2 T "0P1 "0E1 "0T1 "021 "0"1
#))
Thinking in C
www.ThinkingIn.!et
Ga%ing E Ga%ing P ) 'hread# Started 'hread 20P1 'hread 20E1 'hread 20T1 'hread 2021 'hread 20"1 'hread P0P1 'hread P0E1 'hread P0T1 'hread P021 'hread P0"1 'hread E0P1 'hread E0E1 'hread E0T1 'hread E021 'hread E0"1 'hread T0P1 'hread T0E1 'hread T0T1 'hread T021 'hread T0"1 :*ull n*tice that n*!here in thi# e;a+ple i# +hread6#leep( ) called, and yet the *utput indicate# that each thread get# a p*rti*n *9 the CPU# ti+e in !hich t* e;ecute) Thi# #h*!# that #leep( ), !hile it relie# *n the e;i#tence *9 a thread in *rder t* e;ecute, i# n*t inv*lved !ith either ena3ling *r di#a3ling threading) -t# #i+ply an*ther +eth*d) :*u can al#* #ee that the thread# are n*t run in the *rder that theyre created) -n 9act, the *rder that the CPU attend# t* an e;i#ting #et *9 thread# i# indeter+inate, unle## y*u g* in and ad4u#t the Pri*rity pr*perty *9 the thread) ,hen .ain( ) create# the +hread *34ect# it i#nt capturing the re9erence# 9*r any *9 the+) Ot*d*1 Check thi#EW =n *rdinary *34ect !*uld 3e 9air ga+e 9*r gar3age c*llecti*n, 3ut n*t a +hread) Each +hread Iregi#ter#J it#el9 #* there i# actually a re9erence t* it #*+eplace and the gar3age c*llect*r cant clean it up)
#)3
#)4
Thinking in C
www.ThinkingIn.!et
pu$ ic *oid StartCounting0O$Dect #ender2 +*ent)rg# arg#1 ; 'hreadStart de 9 ne. 'hreadStart0paintScreen13 'hread t 9 ne. 'hread0de 13 t.Start013 < pu$ ic *oid paintScreen01; Rectang e $ound# 9 Screen._etBound#0thi#13 int .idth 9 $ound#.Vidth3 int height 9 $ound#.Ueight3 _raphic# g 9 _raphic#.Hro!U.nd0thi#.Uand e13 -en pen 9 ne. -en0Co or.Red2 "13 Rando! rand 9 ne. Rando!013 runH ag 9 true3 for 0int i 9 03 runH ag @@ i W nu!$er'oCount'o3 iRR1 ; //:o #o!ething !i d y ti!e6con#u!ing int x 9 rand.Cext0.idth13 int y 9 rand.Cext0height13 g.:ra.Rectang e0pen2 x2 y2 "2 "13 'hread.S eep0"013 < < $oo runH ag 9 true3
pu$ ic *oid StopCounting0O$Dect #ender2 +*ent)rg# arg#1; runH ag 9 fa #e3 < pu$ ic #tatic *oid Gain01 ; )pp ication.Run0ne. Counter20"0000113 < < //W/exa!p eZ
#)5
Counter8 i# a #traight9*r!ard pr*gra+, !h*#e *nly 4*3 i# t* #et up and +aintain the u#er inter9ace) But n*!, !hen the u#er pre##e# the start 3utt*n, the eventEhandling c*de d*e# n*t d* the ti+eEc*n#u+ing !*rk) -n#tead a thread i# created and #tarted, and then the Counter8 inter9ace can c*ntinue t* re#p*nd t* event#) ,hen y*u pre## the on1ff 3utt*n it t*ggle# the run:lag in#ide the Counter8 *34ect) Then, !hen the I!*rkerJ thread call# paint#creen(), it can l**k at that 9lag and decide !hether t* c*ntinue *r #t*p) Pre##ing the on1ff 3utt*n pr*duce# an apparently in#tant re#p*n#e) O9 c*ur#e, the re#p*n#e i#nt really in#tant, n*t like that *9 a #y#te+ that# driven 3y interrupt#) The painting #t*p# *nly !hen the thread ha# the CPU and n*tice# that the 9lag ha# changed)
#)6
Thinking in C
www.ThinkingIn.!et
//Wexa!p eZ ///WchapterZc"EW/chapterZ ///Wprogra!ZSharing".c#W/progra!Z // -ro$ e!# .ith re#ource #haring .hi e threading. u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.'hreading3 pu$ ic c a## Sharing" : Hor! ; pri*ate 'extBox acce##CountBox 9 ne. 'extBox013 pri*ate Button #tart 9 ne. Button013 pri*ate Button .atch 9 ne. Button013 pri*ate int acce##Count 9 03 pu$ ic *oid incre!ent)cce##01 ; acce##CountRR3 acce##CountBox.'ext 9 acce##Count.'oString013 < pri*ate int nu!Counter# 9 "23 pri*ate int nu!Vatcher# 9 "P3 pri*ate '.oCounterJK #3 pu$ ic Sharing"01 ; C ientSiMe 9 ne. SiMe0EP02 EI013 -ane p 9 ne. -ane 013 p.SiMe 9 ne. SiMe0E002 P013 #tart.C ic% R9 ne. +*entUand er0Start) .atch.C ic% R9 ne. +*entUand er0Start) Vatcher#13 'hread#13
acce##CountBox.'ext 9 &0&3 acce##CountBox.Location 9 ne. -oint0"02 "013 #tart.'ext 9 &Start thread#&3 #tart.Location 9 ne. -oint0""02 "013 .atch.'ext 9 &Begin .atching&3 .atch.Location 9 ne. -oint02"02 "013
#)#
p.Contro #.)dd0#tart13 p.Contro #.)dd0.atch13 p.Contro #.)dd0acce##CountBox13 # 9 ne. '.oCounterJnu!Counter#K3 for 0int i 9 03 i W #.Length3 iRR1 ; #JiK 9 ne. '.oCounter0ne. '.oCounter.5ncre!ent)cce##0incre!ent)cce##113 #JiK.Location 9 ne. -oint0"02 P0 R #JiK.Ueight = i13 Contro #.)dd0#JiK13 < thi#.C o#ed R9 ne. +*entUand er0Stop) Contro #.)dd0p13 < pu$ ic *oid Start) 'hread#0O$Dect #ender2 +*ent)rg# arg#1 ; for 0int i 9 03 i W #.Length3 iRR1 #JiK.Start013 < pu$ ic *oid Stop) 'hread#0O$Dect #ender2 +*ent)rg# arg#1; for0int i 9 03 i W #.Length3 iRR1; if0#JiK !9 nu 1; #JiK.Stop013 < < < pu$ ic *oid Start) Vatcher#0O$Dect #ender2 +*ent)rg# arg#1 ; for 0int i 9 03 i W nu!Vatcher#3 iRR1 ne. Vatcher0#13 < pu$ ic #tatic *oid Gain0#tringJK arg#1 ; Sharing" app 9 ne. Sharing"013 'hread#13
#)&
Thinking in C
www.ThinkingIn.!et
if 0arg#.Length Z 01 ; app.nu!Counter# 9 SByte.-ar#e0arg#J0K13 if 0arg#.Length 99 21 ; app.nu!Vatcher# 9 SByte.-ar#e0arg#J"K13 < < )pp ication.Run0app13 < < c a## '.oCounter : -ane ; pri*ate $oo #tarted 9 fa #e3 pri*ate La$e t"3 pri*ate La$e t23 pri*ate La$e $ 3 pri*ate 'hread t3 pri*ate int count" 9 02 count2 9 03 pu$ ic de egate *oid 5ncre!ent)cce##013 5ncre!ent)cce## de 3 // )dd the di#p ay co!ponent# pu$ ic '.oCounter05ncre!ent)cce## de 1 ; thi#.de 9 de 3 thi#.SiMe 9 ne. SiMe0TP02 T013 thi#.BorderSty e 9 BorderSty e.HixedT:3 t" 9 ne. La$e 013 t".Location 9 ne. -oint0"02 "013 t2 9 ne. La$e 013 t2.Location 9 ne. -oint0""02 "013 $ 9 ne. La$e 013 $ .'ext 9 &Count" 99 Count2&3 $ .Location 9 ne. -oint02"02 "013 Contro #.)ddRange0ne. Contro JK;t"2 t22 $ <13 //5nitia iMe the 'hread t 9 ne. 'hread0ne. 'hreadStart0run113 < pu$ ic *oid Start01 ;
#)'
if 0!#tarted1 ; #tarted 9 true3 t.Start013 < < pu$ ic *oid Stop01; t.)$ort013 < pu$ ic *oid run01 ; .hi e 0true1 ; t".'ext 9 RRcount".'oString013 t2.'ext 9 RRcount2.'oString013 'hread.S eep0P0013 < < pu$ ic *oid #ynch'e#t01 ; de 013 if 0count" !9 count21 $ .'ext 9 &On#ynched&3 < < c a## Vatcher ; '.oCounterJK #3 pu$ ic Vatcher0'.oCounterJK #1 ; thi#.# 9 #3 ne. 'hread0ne. 'hreadStart0run11.Start013 < pu$ ic *oid run01 ; .hi e 0true1 ; for 0int i 9 03 i W #.Length3 iRR1 #JiK.#ynch'e#t013 'hread.S eep0P0013 < < < //W/exa!p eZ
#3(
Thinking in C
www.ThinkingIn.!et
=# 3e9*re, each c*unter c*ntain# it# *!n di#play c*+p*nent#1 t!* te;t 9ield# and a la3el that initially indicate# that the c*unt# are eDuivalent) The#e c*+p*nent# are added t* the panel *9 the #haring7 *34ect in the #haring7 c*n#truct*r) Becau#e a +woCounter thread i# #tarted via a 3utt*n pre## 3y the u#er, it# p*##i3le that #tart( ) c*uld 3e called +*re than *nce) -t# illegal 9*r +hread6#tart( ) t* 3e called +*re than *nce 9*r a thread Gan e;cepti*n i# thr*!nH) :*u can #ee the +achinery t* prevent thi# in the started 9lag and the #tart( ) +eth*d) The accessCountBox in #haring7 keep# track *9 h*! +any t*tal acce##e# have 3een +ade *n all +woCounter thread#) One !ay t* d* thi# !*uld have 3een t* have a #tatic pr*perty that each +woCounter c*uld have incre+ented during synch+est()) -n#tead, !e declared an Bncrement'ccess() delegate !ithin +woCounter that #haring7 pr*vide# a# a para+eter t* the +woCounter c*n#truct*r) -n run( ), count7 and count8 are incre+ented and di#played in a +anner that !*uld #ee+ t* keep the+ identical) Then #leep( ) i# calledQ !ith*ut thi# call the U- 3ec*+e# unre#p*n#ive 3ecau#e all the CPU ti+e i# 3eing c*n#u+ed !ithin the l**p#) The synch+est( ) call# it# Bncrement'ccess delegate and then per9*r+# the apparently #uper9lu*u# activity *9 checking t* #ee i9 count7 i# eDuivalent t* count8Q i9 they are n*t eDuivalent it #et# the la3el t* IUn#ynchedJ t* indicate thi#) The =atcher cla## i# a thread !h*#e 4*3 i# t* call synch+est( ) 9*r all *9 the +woCounter *34ect# that are active) -t d*e# thi# 3y #tepping thr*ugh the array *9 +woCounters pa##ed t* it 3y the #haring7 *34ect) :*u can think *9 the =atcher a# c*n#tantly peeking *ver the #h*ulder# *9 the +woCounter *34ect#) #haring7 c*ntain# an array *9 +woCounter *34ect# that it initiali7e# in it# c*n#truct*r and #tart# a# thread# !hen y*u pre## the IStart Thread#J 3utt*n) Later, !hen y*u pre## the IBegin ,atchingJ 3utt*n, *ne *r +*re !atcher# are created and 9ree t* #py up*n the un#u#pecting +woCounter thread#)
#31
By changing the numCounters and num=atchers value#, !hich y*u can d* at the c*++andEline, y*ull change the 3ehavi*r *9 the pr*gra+) Here# the #urpri#ing part) -n +woCounter6run( ), the in9inite l**p i# 4u#t repeatedly pa##ing *ver the ad4acent line#1 t".'ext 9 RRcount".'oString013 t2.'ext 9 RRcount2.'oString013 Ga# !ell a# #leeping, 3ut that# n*t i+p*rtant hereH) ,hen y*u run the pr*gra+, h*!ever, y*ull di#c*ver that count7 and count8 !ill 3e *3#erved G3y the =atcher#H t* 3e uneDual at ti+e#K Thi# i# 3ecau#e *9 the nature *9 thread#Rthey can 3e #u#pended at any ti+e) S* at ti+e#, the #u#pen#i*n *ccur# 2etween the ti+e c*unt0 and c*unt2 are incre+ented, and the =atcher thread happen# t* c*+e al*ng and per9*r+ the c*+pari#*n at 4u#t thi# +*+ent, thu# 9inding the t!* c*unter# t* 3e di99erent) Thi# e;a+ple #h*!# a 9unda+ental pr*3le+ !ith u#ing thread#) :*u never kn*! !hen a thread +ight 3e run) -+agine #itting at a ta3le !ith a 9*rk, a3*ut t* #pear the la#t piece *9 9**d *n y*ur plate and a# y*ur 9*rk reache# 9*r it, the 9**d #uddenly vani#he# G3ecau#e y*ur thread !a# #u#pended and an*ther thread ca+e in and #t*le the 9**dH) That# the pr*3le+ that y*ure dealing !ith) =ny ti+e y*u rely *n the #tate *9 an *34ect 3eing c*n#i#tent, and that #tate can 3e +anipulated 3y a di99erent thread, y*u are vulnera3le t* thi# type *9 pr*3le+) Thi# i# !hat i# kn*!n a# a race condition G3ecau#e y*ur pr*gra+# pr*per 9uncti*ning i# dependent *n it# thread !inning the IraceJ t* the re#*urceH) Thi# type *9 3ug Gand all 3ug# relating t* threadingH i# di99icult t* track d*!n, a# they !ill *9ten #lip under the radar *9 y*ur unit te#ting c*de and appear and di#appear depending *n l*ad, hard!are and *perating #y#te+ di99erence#, and the !hi+#y *9 the 9ate#) Preventing thi# kind *9 c*lli#i*n i# #i+ply a +atter *9 putting a l*ck *n a re#*urce !hen *ne thread i# relying *n that re#*urce) The 9ir#t thread that acce##e# a re#*urce l*ck# it, and then the *ther thread# cann*t acce## that re#*urce until it i# unl*cked, at !hich ti+e an*ther thread l*ck# and u#e#
#3)
Thinking in C
www.ThinkingIn.!et
it, etc) -9 the 9r*nt #eat *9 the car i# the li+ited re#*urce, the child !h* #h*ut# I?i3#KJ a##ert# the l*ck)
>sing the @onitor class to $revent collisions Ktodo S con0ir# #echanis# o0 @onitor and add @ute& sa#$le code and Interloc*ed
RealE!*rld pr*gra+# have t* #hare +any type# *9 re#*urce# P net!*rk #*cket#, data3a#e c*nnecti*n#, #*und channel#, etc) By 9ar the +*#t c*++*n c*lli#i*n#, th*ugh, *ccur !hen #*+e thread# are changing the #tate# *9 *34ect# and *ther thread# are relying *n the #tate 3eing c*n#i#tent) Thi# i# the ca#e !ith *ur +woCounter and =atcher *34ect#, !here a thread c*ntr*lled 3y +woCounter incre+ent# the count7 and count8 varia3le#, !hile a thread c*ntr*lled 3y =atcher check# the#e varia3le# 9*r c*n#i#tency) The A*nit*r cla## in the na+e#pace Sy#te+)Threading help# prevent c*lli#i*n# *ver *34ect #tate) Every ob)ect in C# ha# an a##*ciated I#ynchr*ni7ati*n 3l*ckJ *34ect !hich +aintain# a l*ck 9*r that *34ect and a Dueue *9 thread# !aiting t* acce## the l*ck) The .onitor cla## i# the pu3lic inter9ace t* the 3ehindEtheE#cene# #ync 3l*ck i+ple+entati*n) The +eth*d .onitor6&nter( ob)ect o) act# a# gatekeeper P !hen a thread e;ecute# thi# line, the #ynchr*ni7ati*n 3l*ck 9*r o i# checkedQ i9 n* *ne currently ha# the l*ck, the thread get# the l*ck and pr*ce##ing c*ntinue#, 3ut i9 an*ther thread ha# already acDuired the l*ck, the thread !ait#, *r I3l*ck#,J until the l*ck 3ec*+e# availa3le) ,hen the critical #ecti*n *9 c*de ha# 3een e;ecuted, the thread #h*uld call .onitor6&xit( ob)ect o) t* relea#e the l*ck) The ne;t 3l*cking thread !ill then 3e given a chance t* *3tain the l*ck) Becau#e y*u virtually al!ay# !ant t* relea#e the l*ck *n a thread at the end *9 a critical #ecti*n, even !hen thr*!ing an &xception, call# t* .onitor6&nter() and .onitor6&xit() are u#ually !rapped in a try 3l*ck1 try;
#33
#34
Thinking in C
www.ThinkingIn.!et
p.SiMe 9 ne. SiMe0E002 P013 #tart.C ic% R9 ne. +*entUand er0Start) .atch.C ic% R9 ne. +*entUand er0Start) Vatcher#13 aCount.'ext 9 &0&3 aCount.Location 9 ne. -oint0"02 "013 #tart.'ext 9 &Start thread#&3 #tart.Location 9 ne. -oint0""02 "013 .atch.'ext 9 &Begin .atching&3 .atch.Location 9 ne. -oint02"02 "013 p.Contro #.)dd0#tart13 p.Contro #.)dd0.atch13 p.Contro #.)dd0aCount13 # 9 ne. '.oCounterJnu!Counter#K3 for 0int i 9 03 i W #.Length3 iRR1 ; #JiK 9 ne. '.oCounter0ne. '.oCounter.5ncre!ent)cce##0incre!ent)cce##113 #JiK.Location 9 ne. -oint0"02 P0 R #JiK.Ueight = i13 Contro #.)dd0#JiK13 < thi#.C o#ed R9 ne. +*entUand er0Stop) Contro #.)dd0p13 < pu$ ic *oid Start) 'hread#0O$Dect #ender2 +*ent)rg# arg#1 ; for 0int i 9 03 i W #.Length3 iRR1 #JiK.Start013 < pu$ ic *oid Stop) 'hread#0O$Dect #ender2 +*ent)rg# arg#1; for0int i 9 03 i W #.Length3 iRR1; if0#JiK !9 nu 1; 'hread#13 'hread#13
#35
#JiK.Stop013 < < for0int i 9 03 i W ..Length3 iRR1; if0.JiK !9 nu 1; .JiK.Stop013 < < < pu$ ic *oid Start) Vatcher#0O$Dect #ender2 +*ent)rg# arg#1 ; . 9 ne. VatcherJnu!Vatcher#K3 for 0int i 9 03 i W nu!Vatcher#3 iRR1 .JiK 9 ne. Vatcher0#13 < pu$ ic #tatic *oid Gain0#tringJK arg#1 ; Sharing" app 9 ne. Sharing"013 if 0arg#.Length Z 01 ; app.nu!Counter# 9 SByte.-ar#e0arg#J0K13 if 0arg#.Length 99 21 ; app.nu!Vatcher# 9 SByte.-ar#e0arg#J"K13 < < )pp ication.Run0app13 < < c a## '.oCounter : -ane ; pri*ate $oo #tarted 9 fa #e3 pri*ate La$e t"3 pri*ate La$e t23 pri*ate La$e $ 3 pri*ate 'hread t3 pri*ate int count" 9 02 count2 9 03 pu$ ic de egate *oid 5ncre!ent)cce##013 5ncre!ent)cce## de 3 // )dd the di#p ay co!ponent#
#36
Thinking in C
www.ThinkingIn.!et
pu$ ic '.oCounter05ncre!ent)cce## de 1 ; thi#.de 9 de 3 thi#.SiMe 9 ne. SiMe0TP02 T013 thi#.BorderSty e 9 BorderSty e.HixedT:3 t" 9 ne. La$e 013 t".Location 9 ne. -oint0"02 "013 t2 9 ne. La$e 013 t2.Location 9 ne. -oint0""02 "013 $ 9 ne. La$e 013 $ .'ext 9 &Count" 99 Count2&3 $ .Location 9 ne. -oint02"02 "013 Contro #.)ddRange0ne. Contro JK;t"2 t22 $ <13 //5nitia iMe the 'hread t 9 ne. 'hread0ne. 'hreadStart0run113 < pu$ ic *oid Start01 ; if 0!#tarted1 ; #tarted 9 true3 t.Start013 < < pu$ ic *oid Stop01; t.)$ort013 < pu$ ic *oid run01 ; .hi e 0true1 ; try; Gonitor.+nter0thi#13 t".'ext 9 0RRcount"1.'oString013 t2.'ext 9 0RRcount21.'oString013 <fina y; Gonitor.+xit0thi#13 < 'hread.S eep0P0013 < < pu$ ic *oid #ynch'e#t01 ;
#3#
de 013 try ; Gonitor.+nter0thi#13 if 0count" !9 count21 ; $ .'ext 9 &On#ynched&3 < < fina ; < < < c a## Vatcher ; '.oCounterJK #3 'hread t3 pu$ ic Vatcher0'.oCounterJK #1 ; thi#.# 9 #3 t 9 ne. 'hread0ne. 'hreadStart0run113 t.Start013 < pu$ ic *oid run01 ; .hi e 0true1 ; for 0int i 9 03 i W #.Length3 iRR1 #JiK.#ynch'e#t013 'hread.S eep0P0013 < < pu$ ic *oid Stop01; t.)$ort013 < < //W/exa!p eZ y Gonitor.+xit0thi#13
#3&
Thinking in C
www.ThinkingIn.!et
:*ull n*tice that 2oth run( ) and synch+est( ) call .onitor6&nter() and &xit()6 -9 y*u u#e the .onitor *nly *n run(), the =atcher thread# calling synch+est() !ill happily read the #tate *9 the +woCounter even !hile the +woCounter thread ha# entered the critical #ecti*n and ha# placed the *34ect in an inc*n#i#tent #tate 3y incre+enting Counter7 3ut n*t yet changing Counter8) There# n*thing +agic a3*ut thread #ynchr*ni7ati*n P it# the +anipulati*n *9 the +woCounter in#tance# #ync 3l*ck via the .onitor that d*e# the !*rk) =ll #ynchr*ni7ati*n depend# *n pr*gra++er diligence1 every piece *9 c*de that can place an *34ect in an inc*n#i#tent #tate *r that relie# *n an *34ect 3eing in a c*n#i#tent #tate +u#t 3e !rapped in an appr*priate 3l*ck)
#3'
#4(
Thinking in C
www.ThinkingIn.!et
p.SiMe 9 ne. SiMe0E002 P013 #tart.C ic% R9 ne. +*entUand er0Start) .atch.C ic% R9 ne. +*entUand er0Start) Vatcher#13 aCount.'ext 9 &0&3 aCount.Location 9 ne. -oint0"02 "013 #tart.'ext 9 &Start thread#&3 #tart.Location 9 ne. -oint0""02 "013 .atch.'ext 9 &Begin .atching&3 .atch.Location 9 ne. -oint02"02 "013 p.Contro #.)dd0#tart13 p.Contro #.)dd0.atch13 p.Contro #.)dd0aCount13 # 9 ne. '.oCounterJnu!Counter#K3 for 0int i 9 03 i W #.Length3 iRR1 ; #JiK 9 ne. '.oCounter0ne. '.oCounter.5ncre!ent)cce##0incre!ent)cce##113 #JiK.Location 9 ne. -oint0"02 P0 R #JiK.Ueight = i13 Contro #.)dd0#JiK13 < thi#.C o#ed R9 ne. +*entUand er0Stop) Contro #.)dd0p13 < pu$ ic *oid Start) 'hread#0O$Dect #ender2 +*ent)rg# arg#1 ; for 0int i 9 03 i W #.Length3 iRR1 #JiK.Start013 < pu$ ic *oid Stop) 'hread#0O$Dect #ender2 +*ent)rg# arg#1; for0int i 9 03 i W #.Length3 iRR1; if0#JiK !9 nu 1; 'hread#13 'hread#13
#41
#JiK.Stop013 < < for0int i 9 03 i W ..Length3 iRR1; if0.JiK !9 nu 1; .JiK.Stop013 < < < pu$ ic *oid Start) Vatcher#0O$Dect #ender2 +*ent)rg# arg#1 ; . 9 ne. VatcherJnu!Vatcher#K3 for 0int i 9 03 i W nu!Vatcher#3 iRR1 .JiK 9 ne. Vatcher0#13 < pu$ ic #tatic *oid Gain0#tringJK arg#1 ; SharingT app 9 ne. SharingT013 if 0arg#.Length Z 01 ; app.nu!Counter# 9 SByte.-ar#e0arg#J0K13 if 0arg#.Length 99 21 ; app.nu!Vatcher# 9 SByte.-ar#e0arg#J"K13 < < )pp ication.Run0app13 < < c a## '.oCounter : -ane ; pri*ate $oo #tarted 9 fa #e3 pri*ate La$e t"3 pri*ate La$e t23 pri*ate La$e $ 3 pri*ate 'hread t3 c a## Counter ; pri*ate int c" 9 03 pri*ate int c2 9 03
#4)
Thinking in C
www.ThinkingIn.!et
pu$ ic *oid 5ncre!ent01 ; oc%0thi#1 ; RRc"3 RRc23 < < pu$ ic int Count" ; get; oc%0thi#1; return c"3< < < pu$ ic int Count2 ; get; oc%0thi#1; return c23 < < < < pri*ate Counter counter 9 ne. Counter013 pu$ ic de egate *oid 5ncre!ent)cce##013 5ncre!ent)cce## de 3 // )dd the di#p ay co!ponent# pu$ ic '.oCounter05ncre!ent)cce## de 1 ; thi#.de 9 de 3 thi#.SiMe 9 ne. SiMe0TP02 T013 thi#.BorderSty e 9 BorderSty e.HixedT:3 t" 9 ne. La$e 013 t".Location 9 ne. -oint0"02 "013 t2 9 ne. La$e 013 t2.Location 9 ne. -oint0""02 "013 $ 9 ne. La$e 013 $ .'ext 9 &Count" 99 Count2&3 $ .Location 9 ne. -oint02"02 "013 Contro #.)ddRange0ne. Contro JK;t"2 t22 $ <13 //5nitia iMe the 'hread t 9 ne. 'hread0ne. 'hreadStart0run113
#43
< pu$ ic *oid Start01 ; if 0!#tarted1 ; #tarted 9 true3 t.Start013 < < pu$ ic *oid Stop01; t.)$ort013 < pu$ ic *oid run01 ; .hi e 0true1 ; counter.5ncre!ent013 t".'ext 9 counter.Count".'oString013 t2.'ext 9 counter.Count2.'oString013 'hread.S eep0P0013 < < pu$ ic *oid #ynch'e#t01 ; de 013 if0counter.Count" !9 counter.Count21 ; $ .'ext 9 &On#ynched&3 < < < c a## Vatcher ; '.oCounterJK #3 'hread t3 pu$ ic Vatcher0'.oCounterJK #1 ; thi#.# 9 #3 t 9 ne. 'hread0ne. 'hreadStart0run113 t.Start013 < pu$ ic *oid run01 ; .hi e 0true1 ;
#44
Thinking in C
www.ThinkingIn.!et
for 0int i 9 03 i W #.Length3 iRR1 #JiK.#ynch'e#t013 'hread.S eep0P0013 < < pu$ ic *oid Stop01; t.)$ort013 < < //W/exa!p eZ
The Counter cla##, an inner cla## *9 +wo!anel i# n*! IthreadE#a9e,J 3y re+*ving any chance that an e;ternal *34ect can place it in an inc*n#i#tent #tate) -ncre+enting the c*unter integer# i# d*ne in#ide the Bncrement +eth*d, !ith a loc(ed critical #ecti*n, and acce## t* the integer# i# d*ne via the Count7 and Count8 pr*pertie#, !hich al#* #ynchr*ni7e again#t the A*nit*r t* en#ure that they cann*t 3e read until the Bncrement critical #ecti*n ha# e;ited Gand, unde#ira3ly, al#* en#ure that Count7 and Count8 cann*t 3e read #i+ultane*u#ly 3y t!* di99erent thread# P a #+all penalty typical *9 the de#ign deci#i*n# +ade !hen devel*ping +ultithreaded app#H) S*+eti+e#, l*cking this d*e#nt #ee+ like the right idea) ,hen an *34ect c*ntain# #*+e re#*urce, and e#pecially !hen that re#*urce i# a c*ntainer *9 #*+e #*rt, #uch a# a Collection *r a #tream *r an Bmage, it i# c*++*n t* !ant t* per9*r+ #*+e *perati*n acr*## #*+e #u3#et *9 that re#*urce !ith*ut !*rrying a3*ut !hether #*+e *ther thread !ill change the re#*urce hal9!ay thr*ugh y*ur *perati*n) -n a #ituati*n like thi#, it# c*++*n t* l*ck the re#*urce, n*t this6 -+ *9 t!* +ind# *n thi#1 *n the *ne hand, the principle *9 c*upling lead# t* the th*ught that i9 the *nly thing that# vulnera3le t* 3eing placed in an inc*n#i#tent #tate i# the re#*urce, then l*ck the re#*urce, a# l*cking this unnece##arily c*uple# this and the re#*urce) On the *ther hand, the principle *9 c*he#i*n lead# u# t* think that i9 *ne p*rti*n *9 the +eth*d# and re#*urce# in an in#tance are vulnera3le t* race c*nditi*n#, 3ut *ther +eth*d# and re#*urce# in the in#tance arent, then +ay3e !e *ught t* re9act*r) Thi# i#
#45
!hat !e did !ith *ur +wo!anel cla##, #plitting the initial cla## int* t!*, and - think #haring9 i# clearly a #uperi*r de#ign t* #haring86
Where to #onitor
=n *34ect# threadE#a9ety i# entirely a 9uncti*n *9 the *34ect# #tate) = cla## !ith*ut any #tatic *r in#tance varia3le#, c*n#i#ting #*lely *9 +eth*d#, i# inherently thread#a9e) =ny varia3le# *r re#*urce# that a99ect !hether y*ur *34ect i# in a c*n#i#tent #tate #h*uld 3e private *r protected and *nly availa3le t* *ut#ide *34ect# 3y !ay *9 pr*pertie# *r +eth*d#) -t# 4u#t 9**li#h t* ever all*! direct re9erence# t* the#e critical re#*urce# 9r*+ e;ternal *34ect#) -9 in#tead y*u create pr*pertie# and +eth*d# !hich c*n#i#tently u#e the .onitor cla## G*r the eDuivalent loc( 3l*ck#H, y*ull #ave y*ur#el9 c*n#idera3le headache# !hen it c*+e# t* l*cating and de3ugging threading pr*3le+#)
#46
Thinking in C
www.ThinkingIn.!et
'i!edVrite0!yLi#t13 < pu$ ic *oid 'i!edVrite0SortedLi#t !yLi#t1; Vriter'hread.+xceptionCount 9 03 Vriter'hreadJK .riter'hread# 9 ne. Vriter'hreadJi'hread#K3 :ate'i!e #tart 9 :ate'i!e.Co.3 for0int i 9 03 i W i'hread#3 iRR1; .riter'hread#JiK 9 ne. Vriter'hread0!yLi#t2 i13 .riter'hread#JiK.Start013 < VaitHor) 'hread#0.riter'hread#13 :ate'i!e #top 9 :ate'i!e.Co.3 'i!eSpan e ap#ed 9 #top 6 #tart3 Sy#te!.Con#o e.VriteLine0&SynchroniMed Li#t: & R !yLi#t.5#SynchroniMed13 Sy#te!.Con#o e.VriteLine0i'hread# R & = P000 9 & R !yLi#t.Count R &Y & R 0!yLi#t.Count 99 0i'hread# = P0001113 Sy#te!.Con#o e.VriteLine0&Cu!$er of exception# thro.n: & R Vriter'hread.+xceptionCount13 Sy#te!.Con#o e.VriteLine0&'i!e of ca cu ation 9 & R e ap#ed13 < pu$ ic *oid VaitHor) 'hread#0Vriter'hreadJK t#1; for0int i 9 03 i W t#.Length3 iRR1; .hi e0t#JiK.Hini#hed 99 fa #e1; 'hread.S eep0"00013 < < < < c a## Vriter'hread ; #tatic int i+xception#'hro.n 9 03 pu$ ic #tatic int +xceptionCount; get; return i+xception#'hro.n3 < #et; i+xception#'hro.n 9 *a ue3 <
#4#
< 'hread t3 SortedLi#t theLi#t3 pu$ ic Vriter'hread0SortedLi#t theLi#t2 int i1; t 9 ne. 'hread0ne. 'hreadStart0Vrite'hread113 t.5#Bac%ground 9 true3 t.Ca!e 9 &VriterJ& R i.'oString01 R &K&3 thi#.theLi#t 9 theLi#t3 < pu$ ic $oo Hini#hed; get; return i#Hini#hed3 < < $oo i#Hini#hed 9 fa #e3 pu$ ic *oid Vrite'hread01; for0int oop 9 03 oop W P0003 oopRR1; String e Ca!e 9 t.Ca!e R oop.'oString013 try; theLi#t.)dd0e Ca!e2 e Ca!e13 <catch0+xception 1; RRi+xception#'hro.n3 < < i#Hini#hed 9 true3 t.)$ort013 < pu$ ic *oid Start01; t.Start013 < < //W/exa!p eZ The .ain() create# a #yncCol7 cla## !ith a para+eter indicating h*! +any thread# t* #i+ultane*u#ly !rite t* a c*llecti*n) = #ortedList i# created and pa##ed t* the +imed=rite +eth*d) Thi# +eth*d #et# the #tatic varia3le &xceptionCount *9 the =riter+hread cla## t* $ and create# an array *9 =riter+hread#) The =riter+hread c*n#truct*r take# the li#t and a varia3le) Each =riter+hread create# a ne! thread, !h*#e pr*ce##ing i# delegated t* the =riter+hread6=rite+hread()
#4&
Thinking in C
www.ThinkingIn.!et
+eth*d) The Bac(ground pr*perty *9 the =riter+hread# thread i# #et t* true) = pr*gra+ !*nt e;it until all it# n*nE3ackgr*und thread# have ended) Being a3le t* create 3ackgr*und Idae+*nJ thread# i# very c*nvenient, e#pecially in a >U-, !here the u#er can reDue#t a pr*gra+ cl*#ure at any ti+e) =9ter the =riter+hread c*n#truct*r return#, the ne;t line *9 +imed=rite() call# the #tart() +eth*d, !hich in turn #tart# the inner thread, !hich in turn delegate# pr*ce##ing t* =rite+hread()6 =rite+hread() l**p# ',$$$ ti+e#, each ti+e creating a ne! na+e G#uch a# I,riterZ02\2/%JH and atte+pting t* add that t* theList) = #orted'rray i# 3acked 3y t!* #t*re# P *ne t* #t*re the value# and an*ther t* #t*re a #*rted li#t *9 key# Gthe key# +ay *r +ay n*t 3e the #a+e a# the value#H) The #*rted li#t i# #t*red in a data #tructure called a I3alanced treeJ G+*re #peci9ically, - 3elieve it i# 3acked 3y a IredE3lackJ treeH) IBalanced tree#J have the pr*perty that l**king up any ite+ happen# in a ti+e pr*p*rti*nal t* the l*garith+ *9 the t*tal nu+3er *9 ite+# #t*red) ,hen #peaking *9 alg*rith+ic e99iciency, it i# 3e#t t* ign*re the actual nu+3er *9 in#tructi*n# inv*lved and *nly c*ncentrate *n the *rder *9 the e;p*nential increa#e a##*ciated !ith #caling the alg*rith+) The actual nu+3er *9 #tep#, a9ter all, varie# 9r*+ pr*gra++ing language t* pr*gra++ing language and c*+puter #peed# increa#e c*n#tantly) S* !hat reall4 +atter# 3*il# d*!n t* !hat# called IBig OJ n*tati*n P a redE3lack tree d*e# a l**kup in OGl*g nH #tep#) =n un#*rted array, *n the *ther hand, reDuire# OGnH #tep# t* #earch G*n average, y*ull 9ind an ite+ in n<2 c*+pari#*n#, 3ut 9*r the purp*#e# *9 IBig OJ c*nver#ati*n#, y*u dr*p everything 3ut the e;p*nentH) But i9 y*u !ant really 9a#t retrieval, the "ashtable cla## d*e# a l**kup in OG0H #tep# P !hat# called Ic*n#tant ti+e)J O9 c*ur#e, a# Ta3le % #h*!#, 9*r every advantage, there# a di#advantage) C*llecti*n Cla## =rrayLi#t Bit=rray -n#ert OG0H ?elete L**kup
#4'
OG0H
OGl*g nH
The large +a4*rity *9 e99*rt that pr*gra++er# e;pend *n e99iciency and *pti+i7ati*n and per9*r+ance ign*re# Big O e99iciency and c*ncentrate# *n trivial a#pect# *9 re+*ving an inter+ediate a##ign+ent here, packing t!ice a# +uch data in a varia3le *ver there, and #* 9*rth) ?*nt 9all 9*r thi# +i#take P i9 it# n*t Big O e99iciency, it# al+*#t certainly n*t !*rth paying attenti*n t*) On !hat - pr*+i#e i# the la#t tangent 3e9*re getting 3ack t* thread#, the 3ig +agic in Duantu+ c*+puter# i# that they reduce the alg*rith+ic c*#t *9 r*tating an nEdi+en#i*nal hyper#phere 9r*+ OGn2H t* OG0H) -9 +y analy#i# i# c*rrect, thi# +ean# that any pr*3le+ y*u can #*lve 3y +anipulating a Ru3ik# cu3e !hile !earing a 3lind9*ld can 3e #*lved 3y a t!*EDu3it Duantu+ c*+puter in c*n#tant ti+e) Have at it, gang) Back t* =riter+hread6=rite+hread()) The call t* 'dd() an ele+ent t* the li#t i# !rapped in a catch 3l*ck) Since !e are ign*ring the detail# *9 the e;cepti*n and *nly rec*rding h*! +any e;cepti*n# !ere thr*!n, the catch #tate+ent d*e# n*t #peci9y a varia3le na+e 9*r the caught e;cepti*n) Once the l**p i# 9ini#hed, !e #et the :inished pr*perty *9 the =riter+hread, kill the Thread, and return) Back in the #yncCol7 cla##, the +ain applicati*n thread g*e# thr*ugh the array, checking t* #ee i9 it# 9ini#hed) -9 it# n*t, the +ain thread g*e# t* #leep 9*r 0,$$$ #ec*nd# 3e9*re checking again) ,hen all the =riter+hread# are :inished, the =rite+hread() !rite# #*+e data *n the e;peri+ent and return#) =9ter the initial call !ith a regular #ortedList, !e create a ne! #ortedList and pa## it t* the #tatic +eth*d #ortedList6#ynchroniTed()) =ll the C*llecti*n# have thi# #tatic +eth*d, !hich create# a ne!, threadE#a9e C*llecti*n) T* 3e clear, the pr*gra+ create# a t*tal *9 / #ortedList#1 the *ne 9*r the initial run thr*ugh =rite+hread(), a #ec*nd an*ny+*u# *ne, !hich i# u#ed a# the
#5(
Thinking in C
www.ThinkingIn.!et
para+eter t* #ortedList6#ynchroniTe(), !hich return# a third *ne) =9ter Chapter Ustream chapter U, y*u #h*uld rec*gni7e the ?ec*rat*r pattern in play) ,hen y*u run thi# pr*gra+, y*ull #ee that the 9ir#t run, !ith a plain #ortedList thr*!# a large nu+3er *9 e;cepti*n# Gi9 y*u have a #u99iciently #peedy c*+puter, y*u +ay get n* e;cepti*n#, 3ut i9 y*u increa#e the nu+3er *9 thread#, eventually y*ull run int* tr*u3leH, !hile the li#t pr*duced 3y #ynchroniTed() add# all the data 9la!le##ly) :*ull al#* #ee !hy C*llecti*n# arent #ynchr*ni7ed 3y de9ault1 the threadE#a9e li#t take# #*+ething like 'E( ti+e# the durati*n t* c*+plete) G-9 y*u #aid IBut it# the #a+e Big OKJ give y*ur#el9 a g*ld #tar) -9 y*u #aid, IBut ign*rant hack# !*uld c*n9u#e li3rary per9*r+ance !ith language per9*r+ance and c*+pare threadE#a9e c*llecti*n# t* n*nEthreadE#a9e c*llecti*n#, and *n the 3a#i# *9 #i+pli#tic 3ench+ark# !rite that C# ha# a per9*r+ance pr*3le+, 4u#t a# they did !ith "avaKJ give y*ur#el9 a platinu+ #tar)H :*u can 9ind *ut i9 a C*llecti*n i# #ynchr*ni7ed *r n*t 3y e;a+ining it# #ynchroniTed pr*perty, a# +imed=rite() d*e# during it# #tatu#E!riting line#) -9, in#tead *9 u#ing a li#t pr*duced 3y #ortedList6#ynchroniTed(), y*u put a loc((theList) 3l*ck ar*und the 'dd() call, y*ull get e;cepti*nE le## 3ehavi*r *n 3*th run# a# !ell) Curi*u#ly, i9 y*u d* thi#, the #ynchr*ni7ed li#t #ee+# t* al!ay# *utper9*r+ the un#ynchr*ni7ed li#t 3y a #+all +arginK -n general, th*ugh, the challenge *9 !*rking !ith c*llecti*n# and thread# i# n*t the threadE#a9ety *9 the underlying c*llecti*n, 3ut the inherent challenge *9 *34ect# 3eing added, deleted, *r changed 3y thread# !hile y*ur current thread trie# t* deal !ith the c*llecti*n a# a #ingle l*gical unit) 5*r in#tance, in an *34ect !ith an in#tance *34ect called myCollection, !hether the C*llecti*n i# #ynchroniTed *r n*t, the line# int i 9 !yCo ection.Count3 O$Dect o 9 !yCo ectionJiK3 are inherently threadEun#a9e 3ecau#e an*ther thread +ight have re+*ved ele+ent i 3e9*re the #ec*nd line i# e;ecuted) -9 the cla## *3ey# the rec*++endati*n that the *nly re9erence# t* a critical re#*urce like
#51
myCollection are internal, any +eth*d that acce##e# myCollection can #i+ply loc((this) and achieve threadE#a9ety) -t# n*t al!ay# p*##i3le t* de#ign cla##e# that d*nt e;p*#e internal in#tance *r #tatic c*llecti*n#, 3ut give it a hard try 3e9*re giving up *n the atte+pt) Can y*u Clone the c*llecti*nF U#e the Pr*;y pattern t* return, n*t the c*llecti*n it#el9, 3ut an inter9ace t* y*ur *!n thread#a9e +eth*d#F -9 n*t, 3e prepared 9*r #*+e l*ng de3ugging #e##i*n#, 3ecau#e it# a g**d 3et that any ti+e y*u *pen the d**r t* +ultithreading de9ect#, #*+e*ne !ill intr*duce the+)
#5)
Thinking in C
www.ThinkingIn.!et
1!, T@L
'che#as and 4ata'ets
#53
#55
#5#
#5'
C, C# Progra##ing Guidelines
Thi# appendi; c*ntain# #ugge#ti*n# t* help guide y*u in per9*r+ing l*!Elevel pr*gra+ de#ign, and in !riting c*de)
aturally, the#e are guideline# and n*t rule#) The idea i# t* u#e the+ a# in#pirati*n#, and t* re+e+3er that there are *cca#i*nal #ituati*n# !here y*u need t* 3end *r 3reak a rule)
4esign
1. &legance always pays off) -n the #h*rt ter+ it +ight #ee+ like it take# +uch l*nger t* c*+e up !ith a truly grace9ul #*luti*n t* a pr*3le+, 3ut !hen it !*rk# the 9ir#t ti+e and ea#ily adapt# t* ne! #ituati*n# in#tead *9 reDuiring h*ur#, day#, *r +*nth# *9 #truggle, y*ull #ee the re!ard# Geven i9 n* *ne can +ea#ure the+H) *t *nly
#61
d*e# it give y*u a pr*gra+ that# ea#ier t* 3uild and de3ug, 3ut it# al#* ea#ier t* under#tand and +aintain, and that# !here the 9inancial value lie#) Thi# p*int can take #*+e e;perience t* under#tand, 3ecau#e it can appear that y*ure n*t 3eing pr*ductive !hile y*ure +aking a piece *9 c*de elegant) Re#i#t the urge t* hurryQ it !ill *nly #l*! y*u d*!n) 0%) :irst ma(e it wor(, then ma(e it fast) Thi# i# true even i9 y*u are certain that a piece *9 c*de i# really i+p*rtant and that it !ill 3e a principal 3*ttleneck in y*ur #y#te+) ?*nt d* it) >et the #y#te+ g*ing 9ir#t !ith a# #i+ple a de#ign a# p*##i3le) Then i9 it i#nt g*ing 9a#t en*ugh, pr*9ile it) :*ull al+*#t al!ay# di#c*ver that Iy*urJ 3*ttleneck i#nt the pr*3le+) Save y*ur ti+e 9*r the really i+p*rtant #tu99) 0() *emember the adivide and con%uerb principle ) -9 the pr*3le+ y*ure l**king at i# t** c*n9u#ing, try t* i+agine !hat the 3a#ic *perati*n *9 the pr*gra+ !*uld 3e, given the e;i#tence *9 a +agic IpieceJ that handle# the hard part#) That IpieceJ i# an *34ectR!rite the c*de that u#e# the *34ect, then l**k at the *34ect and encap#ulate its hard part# int* *ther *34ect#, etc) 06) #eparate the class creator from the class user (client programmer)) The cla## u#er i# the Icu#t*+erJ and d*e#nt need *r !ant t* kn*! !hat# g*ing *n 3ehind the #cene# *9 the cla##) The cla## creat*r +u#t 3e the e;pert in cla## de#ign and !rite the cla## #* that it can 3e u#ed 3y the +*#t n*vice pr*gra++er p*##i3le, yet #till !*rk
#6)
r*3u#tly in the applicati*n) Li3rary u#e !ill 3e ea#y *nly i9 it# tran#parent) 2$) =hen you create a class, attempt to ma(e your names so clear that comments are unnecessary) :*ur g*al #h*uld 3e t* +ake the client pr*gra++er# inter9ace c*nceptually #i+ple) T* thi# end, u#e +eth*d *verl*ading !hen appr*priate t* create an intuitive, ea#yEt*Eu#e inter9ace) 20) @our analysis and design must produce, at minimum, the classes in your system, their public interfaces, and their relationships to other classes, especially base classes ) -9 y*ur de#ign +eth*d*l*gy pr*duce# +*re than that, a#k y*ur#el9 i9 all the piece# pr*duced 3y that +eth*d*l*gy have value *ver the li9eti+e *9 the pr*gra+) -9 they d* n*t, +aintaining the+ !ill c*#t y*u) Ae+3er# *9 devel*p+ent tea+# tend n*t t* +aintain anything that d*e# n*t c*ntri3ute t* their pr*ductivityQ thi# i# a 9act *9 li9e that +any de#ign +eth*d# d*nt acc*unt 9*r) 22) 'utomate everything) ,rite the te#t c*de 9ir#t G3e9*re y*u !rite the cla##H, and keep it !ith the cla##) =ut*+ate the running *9 y*ur te#t# thr*ugh a +ake9ile *r #i+ilar t**l) Thi# !ay, any change# can 3e aut*+atically veri9ied 3y running the te#t c*de, and y*ull i++ediately di#c*ver err*r#) Becau#e y*u kn*! that y*u have the #a9ety net *9 y*ur te#t 9ra+e!*rk, y*u !ill 3e 3*lder a3*ut +aking #!eeping change# !hen y*u di#c*ver the need) Re+e+3er that the greate#t i+pr*ve+ent# in language# c*+e 9r*+ the 3uiltEin te#ting pr*vided 3y type checking, e;cepti*n handling, etc), 3ut th*#e 9eature# take y*u *nly #* 9ar) :*u +u#t g* the re#t *9 the !ay in creating a r*3u#t #y#te+ 3y 9illing in the te#t# that veri9y 9eature# that are #peci9ic t* y*ur cla## *r pr*gra+) 2/) =rite the test code first (before you write the class) in order to verify that your class design is complete) -9 y*u cant !rite te#t c*de, y*u d*nt kn*! !hat y*ur cla## l**k# like) -n additi*n, the act *9 !riting the te#t c*de !ill *9ten 9lu#h *ut additi*nal 9eature# *r c*n#traint# that y*u need in the cla##Rthe#e 9eature# *r c*n#traint# d*nt al!ay# appear during analy#i# and de#ign) Te#t# al#* pr*vide e;a+ple c*de #h*!ing h*! y*ur cla## can 3e u#ed)
#63
2&) 'll software design problems can be simplified by introducing an extra level of conceptual indirection . Thi# 9unda+ental rule *9 #*9t!are engineering0 i# the 3a#i# *9 a3#tracti*n, the pri+ary 9eature *9 *34ectE*riented pr*gra++ing) 2') 'n indirection should have a meaning Gin c*ncert !ith guideline 6H) Thi# +eaning can 3e #*+ething a# #i+ple a# Iputting c*++*nly u#ed c*de in a #ingle +eth*d)J -9 y*u add level# *9 indirecti*n Ga3#tracti*n, encap#ulati*n, etc)H that d*nt have +eaning, it can 3e a# 3ad a# n*t having adeDuate indirecti*n) 2.) .a(e classes as atomic as possible) >ive each cla## a #ingle, clear purp*#e) -9 y*ur cla##e# *r y*ur #y#te+ de#ign gr*!# t** c*+plicated, 3reak c*+ple; cla##e# int* #i+pler *ne#) The +*#t *3vi*u# indicat*r *9 thi# i# #heer #i7e1 i9 a cla## i# 3ig, chance# are it# d*ing t** +uch and #h*uld 3e 3r*ken up) Clue# t* #ugge#t rede#ign *9 a cla## are1 0H = c*+plicated #!itch #tate+ent1 c*n#ider u#ing p*ly+*rphi#+) 2H = large nu+3er *9 +eth*d# that c*ver 3r*adly di99erent type# *9 *perati*n#1 c*n#ider u#ing #everal cla##e#) /H = large nu+3er *9 +e+3er varia3le# that c*ncern 3r*adly di99erent characteri#tic#1 c*n#ider u#ing #everal cla##e#) 2%) =atch for long argument lists) Aeth*d call# then 3ec*+e di99icult t* !rite, read, and +aintain) -n#tead, try t* +*ve the +eth*d t* a cla## !here it i# G+*reH appr*priate, and<*r pa## *34ect# in a# argu+ent#) 2() $on5t repeat yourself) -9 a piece *9 c*de i# recurring in +any +eth*d# in derived cla##e#, put that c*de int* a #ingle +eth*d in the 3a#e cla## and call it 9r*+ the derivedEcla## +eth*d#) *t *nly d* y*u #ave c*de #pace, y*u pr*vide 9*r ea#y pr*pagati*n *9 change#) S*+eti+e# the di#c*very *9 thi# c*++*n c*de !ill add valua3le 9uncti*nality t* y*ur inter9ace) 26) =atch for switch statements or chained i!'else clauses) Thi# i# typically an indicat*r *9 t4"e9check coding, !hich +ean# y*u are ch**#ing !hat c*de t* e;ecute 3a#ed *n #*+e kind *9 type
0 E;plained t* +e 3y =ndre! N*enig)
#64
Thinking in C
www.ThinkingIn.!et
in9*r+ati*n Gthe e;act type +ay n*t 3e *3vi*u# at 9ir#tH) :*u can u#ually replace thi# kind *9 c*de !ith inheritance and p*ly+*rphi#+Q a p*ly+*rphic +eth*d call !ill per9*r+ the type checking 9*r y*u, and all*! 9*r +*re relia3le and ea#ier e;ten#i3ility) /$) :rom a design standpoint, loo( for and separate things that change from things that stay the same) That i#, #earch 9*r the ele+ent# in a #y#te+ that y*u +ight !ant t* change !ith*ut 9*rcing a rede#ign, then encap#ulate th*#e ele+ent# in cla##e#) :*u can learn #igni9icantly +*re a3*ut thi# c*ncept in Thinking in /atterns with ,a-a, d*!nl*ada3le at www.BruceEckel.com) /0) $on5t extend fundamental functionality by subclassing) -9 an inter9ace ele+ent i# e##ential t* a cla## it #h*uld 3e in the 3a#e cla##, n*t added during derivati*n) -9 y*ure adding +eth*d# 3y inheriting, perhap# y*u #h*uld rethink the de#ign) /2) Less is more) Start !ith a +ini+al inter9ace t* a cla##, a# #+all and #i+ple a# y*u need t* #*lve the pr*3le+ at hand, 3ut d*nt try t* anticipate all the !ay# that y*ur cla## might 3e u#ed) =# the cla## i# u#ed, y*ull di#c*ver !ay# y*u +u#t e;pand the inter9ace) H*!ever, *nce a cla## i# in u#e y*u cann*t #hrink the inter9ace !ith*ut di#tur3ing client c*de) -9 y*u need t* add +*re +eth*d#, that# 9ineQ it !*nt di#tur3 c*de, *ther than 9*rcing rec*+pile#) But even i9 ne! +eth*d# replace the 9uncti*nality *9 *ld *ne#, leave the e;i#ting inter9ace al*ne Gy*u can c*+3ine the 9uncti*nality in the underlying i+ple+entati*n i9 y*u !antH) -9 y*u need t* e;pand the inter9ace *9 an e;i#ting +eth*d 3y adding +*re argu+ent#, create an *verl*aded +eth*d !ith the ne! argu+ent#Q thi# !ay y*u !*nt di#tur3 any e;i#ting call# t* the e;i#ting +eth*d) //) *ead your classes aloud to ma(e sure they5re logical ) Re9er t* the relati*n#hip 3et!een a 3a#e cla## and derived cla## a# Ii#EaJ and +e+3er *34ect# a# Iha#Ea)J /&) =hen deciding between inheritance and composition, as( if you need to upcast to the base type) -9 n*t, pre9er c*+p*#iti*n G+e+3er *34ect#H t* inheritance) Thi# can eli+inate the perceived need 9*r +ultiple 3a#e type#) -9 y*u inherit, u#er# !ill think they are #upp*#ed t* upca#t)
#65
/') Vse data members for variation in value and method overriding for variation in behavior) That i#, i9 y*u 9ind a cla## that u#e# #tate varia3le# al*ng !ith +eth*d# that #!itch 3ehavi*r 3a#ed *n th*#e varia3le#, y*u #h*uld pr*3a3ly rede#ign it t* e;pre## the di99erence# in 3ehavi*r !ithin #u3cla##e# and *verridden +eth*d#) /.) =atch for overloading) = +eth*d #h*uld n*t c*nditi*nally e;ecute c*de 3a#ed *n the value *9 an argu+ent) -n thi# ca#e, y*u #h*uld create t!* *r +*re *verl*aded +eth*d# in#tead) /%) Vse exception hierarchiesRpre9era3ly derived 9r*+ #peci9ic appr*priate cla##e# in the #tandard "ava e;cepti*n hierarchy) The per#*n catching the e;cepti*n# can then catch the #peci9ic type# *9 e;cepti*n#, 9*ll*!ed 3y the 3a#e type) -9 y*u add ne! derived e;cepti*n#, e;i#ting client c*de !ill #till catch the e;cepti*n thr*ugh the 3a#e type) /() #ometimes simple aggregation does the )ob) = Ipa##enger c*+9*rt #y#te+J *n an airline c*n#i#t# *9 di#c*nnected ele+ent#1 #eat, air c*nditi*ning, vide*, etc), and yet y*u need t* create +any *9 the#e in a plane) ?* y*u +ake private +e+3er# and 3uild a !h*le ne! inter9aceF *Rin thi# ca#e, the c*+p*nent# are al#* part *9 the pu3lic inter9ace, #* y*u #h*uld create pu3lic +e+3er *34ect#) Th*#e *34ect# have their *!n private i+ple+entati*n#, !hich are #till #a9e) Be a!are that #i+ple aggregati*n i# n*t a #*luti*n t* 3e u#ed *9ten, 3ut it d*e# happen) /6) Consider the perspective of the client programmer and the person maintaining the code) ?e#ign y*ur cla## t* 3e a# *3vi*u# a# p*##i3le t* u#e) =nticipate the kind *9 change# that !ill 3e +ade, and de#ign y*ur cla## #* that th*#e change# !ill 3e ea#y) &$) =atch out for agiant ob)ect syndrome6b Thi# i# *9ten an a99licti*n *9 pr*cedural pr*gra++er# !h* are ne! t* OOP and !h* end up !riting a pr*cedural pr*gra+ and #ticking it in#ide *ne *r t!* giant *34ect#) ,ith the e;cepti*n *9 applicati*n 9ra+e!*rk#, *34ect# repre#ent c*ncept# in y*ur applicati*n, n*t the applicati*n)
#66
Thinking in C
www.ThinkingIn.!et
&0) Bf you must do something ugly, at least localiTe the ugliness inside a class) &2) Bf you must do something nonportable, ma(e an abstraction for that service and localiTe it within a class) Thi# e;tra level *9 indirecti*n prevent# the n*np*rta3ility 9r*+ 3eing di#tri3uted thr*ugh*ut y*ur pr*gra+) GThi# idi*+ i# e+3*died in the Bridge PatternH) &/) ob)ects should not simply hold some data) They #h*uld al#* have !ellEde9ined 3ehavi*r#) GOcca#i*nally, Idata *34ect#J are appr*priate, 3ut *nly !hen u#ed e;pre##ly t* package and tran#p*rt a gr*up *9 ite+# !hen a generali7ed c*ntainer i# innappr*priate)H &&) Choose composition first when creating new classes from existing classes) :*u #h*uld *nly u#ed inheritance i9 it i# reDuired 3y y*ur de#ign) -9 y*u u#e inheritance !here c*+p*#iti*n !ill !*rk, y*ur de#ign# !ill 3ec*+e needle##ly c*+plicated) &') Vse inheritance and method overriding to express differences in behavior, and fields to express variations in state) =n e;tre+e e;a+ple *9 !hat n*t t* d* i# inheriting di99erent cla##e# t* repre#ent c*l*r# in#tead *9 u#ing a Ic*l*rJ 9ield) &.) =atch out for variance) T!* #e+antically di99erent *34ect# +ay have identical acti*n#, *r re#p*n#i3ilitie#, and there i# a natural te+ptati*n t* try t* +ake *ne a #u3cla## *9 the *ther 4u#t t* 3ene9it 9r*+ inheritance) Thi# i# called variance, 3ut there# n* real 4u#ti9icati*n t* 9*rce a #upercla##<#u3cla## relati*n#hip !here it d*e#nt e;i#t) = 3etter #*luti*n i# t* create a general 3a#e cla## that pr*duce# an inter9ace 9*r 3*th a# derived cla##e#Rit reDuire# a 3it +*re #pace, 3ut y*u #till 3ene9it 9r*+ inheritance, and !ill pr*3a3ly +ake an i+p*rtant di#c*very a3*ut the de#ign) &%) =atch out for limitation during inheritance) The cleare#t de#ign# add ne! capa3ilitie# t* inherited *ne#) = #u#pici*u# de#ign re+*ve# *ld capa3ilitie# during inheritance !ith*ut adding ne! *ne#) But rule# are +ade t* 3e 3r*ken, and i9 y*u are !*rking 9r*+ an *ld cla## li3rary, it +ay 3e +*re e99icient t* re#trict an e;i#ting cla## in it#
#6#
#u3cla## than it !*uld 3e t* re#tructure the hierarchy #* y*ur ne! cla## 9it# in !here it #h*uld, a3*ve the *ld cla##) &() Vse design patterns to eliminate ana(ed functionality6b That i#, i9 *nly *ne *34ect *9 y*ur cla## #h*uld 3e created, d*nt 3*lt ahead t* the applicati*n and !rite a c*++ent IAake *nly *ne *9 the#e)J ,rap it in a #inglet*n) -9 y*u have a l*t *9 +e##y c*de in y*ur +ain pr*gra+ that create# y*ur *34ect#, l**k 9*r a creati*nal pattern like a 9act*ry +eth*d in !hich y*u can encap#ulate that creati*n) Eli+inating Inaked 9uncti*nalityJ !ill n*t *nly +ake y*ur c*de +uch ea#ier t* under#tand and +aintain, it !ill al#* +ake it +*re 3ulletpr**9 again#t the !ellEintenti*ned +aintainer# that c*+e a9ter y*u) &6) =atch out for aanalysis paralysis6b Re+e+3er that y*u +u#t u#ually +*ve 9*r!ard in a pr*4ect 3e9*re y*u kn*! everything, and that *9ten the 3e#t and 9a#te#t !ay t* learn a3*ut #*+e *9 y*ur unkn*!n 9act*r# i# t* g* t* the ne;t #tep rather than trying t* 9igure it *ut in y*ur head) :*u cant kn*! the #*luti*n until y*u ha-e the #*luti*n) "ava ha# 3uiltEin 9ire!all#Q let the+ !*rk 9*r y*u) :*ur +i#take# in a cla## *r #et *9 cla##e# !*nt de#tr*y the integrity *9 the !h*le #y#te+) '$) =hen you thin( you5ve got a good analysis, design, or implementation, do a wal(through ) Bring #*+e*ne in 9r*+ *ut#ide y*ur gr*upRthi# d*e#nt have t* 3e a c*n#ultant, 3ut can 3e #*+e*ne 9r*+ an*ther gr*up !ithin y*ur c*+pany) Revie!ing y*ur !*rk !ith a 9re#h pair *9 eye# can reveal pr*3le+# at a #tage !hen it# +uch ea#ier t* 9i; the+, and +*re than pay# 9*r the ti+e and +*ney Il*#tJ t* the !alkthr*ugh pr*ce##)
I#$le#entation
'0) Bn general, follow the .icrosoft coding conventions ) The#e are availa3le at re$ Gthe c*de in thi# 3**k 9*ll*!# the#e c*nventi*n# a# +uch a# !a# a3leH) The#e are u#ed 9*r !hat c*n#titute# argua3ly the large#t 3*dy *9 c*de that the large#t nu+3er *9 C# pr*gra++er# !ill 3e e;p*#ed t*) -9 y*u d*ggedly #tick t* the c*ding #tyle y*uve al!ay#
#6&
Thinking in C
www.ThinkingIn.!et
u#ed, y*u !ill +ake it harder 9*r y*ur reader) ,hatever c*ding c*nventi*n# y*u decide *n, en#ure they are c*n#i#tent thr*ugh*ut the pr*4ect) '2) =hatever coding style you use, it really does ma(e a difference if your team (and even better, your company) standardiTes on it) Thi# +ean# t* the p*int that every*ne c*n#ider# it 9air ga+e t* 9i; #*+e*ne el#e# c*ding #tyle i9 it d*e#nt c*n9*r+) The value *9 #tandardi7ati*n i# that it take# le## 3rain cycle# t* par#e the c*de, #* that y*u can 9*cu# +*re *n !hat the c*de +ean#) '/) :ollow standard capitaliTation rules) Capitali7e the 9ir#t letter *9 cla## na+e# and n*nEprivate +eth*d# and pr*pertie#) The 9ir#t letter *9 private 9ield#, +eth*d#, and *34ect# Gre9erence#H #h*uld 3e l*!erca#e) =ll identi9ier# #h*uld run their !*rd# t*gether, and capitali7e the 9ir#t letter *9 all inter+ediate !*rd#) 5*r e;a+ple1 +hisBs'Class,ame thisBs'!rivate.ethod1r:ield,ame Capitali7e all the letter# *9 static final pri+itive identi9ier# that have c*n#tant initiali7er# in their de9initi*n#) Thi# indicate# they are c*+pileEti+e c*n#tant#) '&) $on5t create your own adecoratedb private data member names) Thi# i# u#ually #een in the 9*r+ *9 prepended under#c*re# and character#) Hungarian n*tati*n i# the !*r#t e;a+ple *9 thi#, !here y*u attach e;tra character# that indicate data type, u#e, l*cati*n, etc), a# i9 y*u !ere !riting a##e+3ly language and the c*+piler pr*vided n* e;tra a##i#tance at all) The#e n*tati*n# are c*n9u#ing, di99icult t* read, and unplea#ant t* en9*rce and +aintain) Let cla##e# and package# d* the na+e #c*ping 9*r y*u) '') :ollow a acanonical formb !hen creating a cla## 9*r generalE purp*#e u#e) -nclude de9initi*n# 9*r e%uals( ), hashCode( ), to#tring( ), clone( ) Gi+ple+ent CloneableH, and i+ple+ent Comparable and #erialiTable) '.) Vse the XavaBeans aget,b aset,b and aisb naming conventions 9*r +eth*d# that read and change private 9ield#, even i9 y*u d*nt think y*ure +aking a "avaBean at the ti+e) *t *nly d*e# it +ake it ea#y t* u#e y*ur cla## a# a Bean, 3ut it# a #tandard !ay t* na+e the#e
#6'
kind# *9 +eth*d# and #* !ill 3e +*re ea#ily under#t**d 3y the reader) '%) :or each class you create, consider including a static public test6 7 that contains code to test that class) :*u d*nt need t* re+*ve the te#t c*de t* u#e the cla## in a pr*4ect, and i9 y*u +ake any change# y*u can ea#ily rerun the te#t#) Thi# c*de al#* pr*vide# e;a+ple# *9 h*! t* u#e y*ur cla##) '() #ometimes you need to inherit in order to access protected members of the base class) Thi# can lead t* a perceived need 9*r +ultiple 3a#e type#) -9 y*u d*nt need t* upca#t, 9ir#t derive a ne! cla## t* per9*r+ the pr*tected acce##) Then +ake that ne! cla## a +e+3er *34ect in#ide any cla## that need# t* u#e it, rather than inheriting) '6) Bf two classes are associated with each other in some functional way (such as containers and iterators), try to ma(e one an inner class of the other) Thi# n*t *nly e+pha#i7e# the a##*ciati*n 3et!een the cla##e#, 3ut it all*!# the cla## na+e t* 3e reu#ed !ithin a #ingle package 3y ne#ting it !ithin an*ther cla##) .$) 'nytime you notice classes that appear to have high coupling with each other, consider the coding and maintenance improvements you might get by using inner classes) The u#e *9 inner cla##e# !ill n*t unc*uple the cla##e#, 3ut rather +ake the c*upling e;plicit and +*re c*nvenient) .0) $on5t fall prey to premature optimiTation) Thi# !ay lie# +adne##) -n particular, d*nt !*rry a3*ut !riting G*r av*idingH native +eth*d#, +aking #*+e +eth*d# final, *r t!eaking c*de t* 3e e99icient !hen y*u are 9ir#t c*n#tructing the #y#te+) :*ur pri+ary g*al #h*uld 3e t* pr*ve the de#ign, unle## the de#ign reDuire# a certain e99iciency) .2) Eeep scopes as small as possible so the visibility and lifetime of your ob)ects are as small as possible) Thi# reduce# the chance *9 u#ing an *34ect in the !r*ng c*nte;t and hiding a di99icultEt*E9ind 3ug) 5*r e;a+ple, #upp*#e y*u have a c*ntainer and a piece *9 c*de that iterate# thr*ugh it) -9 y*u c*py that c*de t* u#e !ith a ne!
##(
Thinking in C
www.ThinkingIn.!et
c*ntainer, y*u +ay accidentally end up u#ing the #i7e *9 the *ld c*ntainer a# the upper 3*und *9 the ne! *ne) -9, h*!ever, the *ld c*ntainer i# *ut *9 #c*pe, the err*r !ill 3e caught at c*+pileEti+e) ./) Vse the containers in the 6,&+ :ramewor( #$E) Bec*+e pr*9icient !ith their u#e and y*ull greatly increa#e y*ur pr*ductivity) .&) :or a program to be robust, each component must be robust) U#e all the t**l# pr*vided 3y C#1 acce## c*ntr*l, e;cepti*n#, type checking, and #* *n, in each cla## y*u create) That !ay y*u can #a9ely +*ve t* the ne;t level *9 a3#tracti*n !hen 3uilding y*ur #y#te+) .') !refer compile-time errors to run-time errors) Try t* handle an err*r a# cl*#e t* the p*int *9 it# *ccurrence a# p*##i3le) Pre9er dealing !ith the err*r at that p*int t* thr*!ing an e;cepti*n) Catch any e;cepti*n# in the neare#t handler that ha# en*ugh in9*r+ati*n t* deal !ith the+) ?* !hat y*u can !ith the e;cepti*n at the current levelQ i9 that d*e#nt #*lve the pr*3le+, rethr*! the e;cepti*n) ..) =atch for long method definitions) Aeth*d# #h*uld 3e 3rie9, 9uncti*nal unit# that de#cri3e and i+ple+ent a di#crete part *9 a cla## inter9ace) = +eth*d that i# l*ng and c*+plicated i# di99icult and e;pen#ive t* +aintain, and i# pr*3a3ly trying t* d* t** +uch all 3y it#el9) -9 y*u #ee #uch a +eth*d, it indicate# that, at the lea#t, it #h*uld 3e 3r*ken up int* +ultiple +eth*d#) -t +ay al#* #ugge#t the creati*n *9 a ne! cla##) S+all +eth*d# !ill al#* 9*#ter reu#e !ithin y*ur cla##) GS*+eti+e# +eth*d# +u#t 3e large, 3ut they #h*uld #till d* 4u#t *ne thing)H .%) Eeep things as aprivate as possible6b Once y*u pu3lici7e an a#pect *9 y*ur li3rary Ga +eth*d, a cla##, a 9ieldH, y*u can never take it *ut) -9 y*u d*, y*ull !reck #*+e3*dy# e;i#ting c*de, 9*rcing the+ t* re!rite and rede#ign) -9 y*u pu3lici7e *nly !hat y*u +u#t, y*u can change everything el#e !ith i+punity, and #ince de#ign# tend t* ev*lve thi# i# an i+p*rtant 9reed*+) -n thi# !ay, i+ple+entati*n change# !ill have +ini+al i+pact *n derived cla##e#) Privacy i# e#pecially i+p*rtant !hen dealing !ith +ultithreadingR*nly private 9ield# can 3e pr*tected again#t unEsynchroniTed u#e)
##1
.() Vse comments liberally, and use the commentdocumentation syntax to produce your program documentation) H*!ever, the c*++ent# #h*uld add geniune +eaning t* the c*deQ c*++ent# that *nly reiterate !hat the c*de i# clearly e;pre##ing are ann*ying) *te that the typical ver3*#e detail *9 "ava cla## and +eth*d na+e# reduce the need 9*r a# +any c*++ent#) .6) 'void using amagic numbersbR!hich are nu+3er# hardE!ired int* c*de) The#e are a night+are i9 y*u need t* change the+, #ince y*u never kn*! i9 I0$$J +ean# Ithe array #i7eJ *r I#*+ething el#e entirely)J -n#tead, create a c*n#tant !ith a de#criptive na+e and u#e the c*n#tant identi9ier thr*ugh*ut y*ur pr*gra+) Thi# +ake# the pr*gra+ ea#ier t* under#tand and +uch ea#ier t* +aintain) %$) =hen creating constructors, consider exceptions) -n the 3e#t ca#e, the c*n#truct*r !*nt d* anything that thr*!# an e;cepti*n) -n the ne;tE3e#t #cenari*, the cla## !ill 3e c*+p*#ed and inherited 9r*+ r*3u#t cla##e# *nly, #* they !ill need n* cleanup i9 an e;cepti*n i# thr*!n) Other!i#e, y*u +u#t clean up c*+p*#ed cla##e# in#ide a finally clau#e) -9 a c*n#truct*r +u#t 9ail, the appr*priate acti*n i# t* thr*! an e;cepti*n, #* the caller d*e#nt c*ntinue 3lindly, thinking that the *34ect !a# created c*rrectly) %0) Bf your class re%uires any cleanup when the client programmer is finished with the ob)ect, ma(e your class implement B$isposable tk) %2) =hen you are creating a fixed-siTe container of ob)ects, transfer them to an arrayRe#pecially i9 y*ure returning thi# c*ntainer 9r*+ a +eth*d) Thi# !ay y*u get the 3ene9it *9 the array# c*+pileEti+e type checking, and the recipient *9 the array +ight n*t need t* ca#t the *34ect# in the array in *rder t* u#e the+) %/) Choose inter!aces over abstract classes) -9 y*u kn*! #*+ething i# g*ing t* 3e a 3a#e cla##, y*ur 9ir#t ch*ice #h*uld 3e t* +ake it an interface, and *nly i9 y*ure 9*rced t* have +eth*d de9initi*n# *r +e+3er varia3le# #h*uld y*u change it t* an abstract cla##) =n interface talk# a3*ut !hat the client !ant# t* d*, !hile a cla## tend# t* 9*cu# *n G*r all*!H i+ple+entati*n detail#)
##)
Thinking in C
www.ThinkingIn.!et
%&) Bnside constructors, do only what is necessary to set the ob)ect into the proper state) =ctively av*id calling *ther +eth*d# Ge;cept 9*r final +eth*d#H #ince th*#e +eth*d# can 3e *verridden 3y #*+e*ne el#e t* pr*duce une;pected re#ult# during c*n#tructi*n) GSee Chapter % 9*r detail#)H S+aller, #i+pler c*n#truct*r# are le## likely t* thr*! e;cepti*n# *r cau#e pr*3le+#) %') =atch out for accidental overloading) -9 y*u atte+pt t* *verride a 3a#eEcla## +eth*d and y*u d*nt Duite get the #pelling right, y*ull end up adding a ne! +eth*d rather than *verriding an e;i#ting +eth*d) H*!ever, thi# i# per9ectly legal, #* y*u !*nt get any err*r +e##age 9r*+ the c*+piler *r runEti+e #y#te+Ry*ur c*de #i+ply !*nt !*rk c*rrectly) %.) =atch out for premature optimiTation) 5ir#t +ake it !*rk, then +ake it 9a#tR3ut *nly i9 y*u +u#t, and *nly i9 it# pr*ven that there i# a per9*r+ance 3*ttleneck in a particular #ecti*n *9 y*ur c*de) Unle## y*u have u#ed a pr*9iler t* di#c*ver a 3*ttleneck, y*u !ill pr*3a3ly 3e !a#ting y*ur ti+e) The hidden c*#t *9 per9*r+ance t!eak# i# that y*ur c*de 3ec*+e# le## under#tanda3le and +aintaina3le) %%) *emember that code is read much more than it is written) Clean de#ign# +ake 9*r ea#yEt*Eunder#tand pr*gra+#, 3ut c*++ent#, detailed e;planati*n#, and e;a+ple# are invalua3le) They !ill help 3*th y*u and every*ne !h* c*+e# a9ter y*u) -9 n*thing el#e, the 9ru#trati*n *9 trying t* 9erret *ut u#e9ul in9*r+ati*n 9r*+ the *nline "ava d*cu+entati*n #h*uld c*nvince y*u)
4, 6esources
'o0tware
tk
##3
3oo*s
C#
tk
)nal5sis I design
tk
@anage#ent I Process
tk
Inde&
Plea#e n*te that #*+e na+e# !ill 3e duplicated in capitali7ed 9*r+) 5*ll*!ing C# #tyle, the capitali7ed na+e# re9er t* C# cla##e#, !hile l*!erca#e na+e# re9er t* a general c*ncept)
A
+ultita#king f %0'
StartG H f %22 thread# and e99iciency f %20 !hen they can 3e #u#pended f %/2 U
u#er inter9ace f
P
pr*ce##, and threading f %0'
S
SleepG H f %2$, %/0
T
Thread f
##4
Thinking in C
www.ThinkingIn.!et
Chec( www."ruceEc(el.com 0or in;de$th details and the date and location o0 the ne&t ands)*n +ava Seminar
Ba#ed *n thi# 3**k Taught 3y Bruce Eckel Per#*nal attenti*n 9r*+ Bruce Eckel and hi# #e+inar a##i#tant# -nclude# inEcla## pr*gra++ing e;erci#e# -nter+ediate<=dvanced #e+inar# al#* *99ered Hundred# have already en4*yed thi# #e+inarR #ee the ,e3 #ite 9*r their te#ti+*nial#
##6
"ruce Ec(el,s ands)*n +ava Seminar @ulti#edia C4 Its li*e co#ing to the se#inarJ )vaila+le at www.BruceEckel.com
The >ands91n ,a-a @eminar captured *n a Aulti+edia C?K Overhead #lide# and #ynchr*ni7ed audi* v*ice narrati*n 9*r all the lecture#) "u#t play it t* #ee and hear the lecture#K Created and narrated 3y Bruce Eckel) Ba#ed *n the +aterial in thi# 3**k) ?e+* lecture availa3le at www.BruceEckel.com
%nd;>ser License )gree#ent 0or @icroso0t 'o0tware I@PO6-)(-;6%)4 C)6%7>LLB, -his @icroso0t %nd;>ser License )gree#ent 1=%>L)=2 is a legal agree#ent +etween 5ou 1either an individual or a single entit52 and @icroso0t Cor$oration 0or the @icroso0t so0tware $roduct included in this $ac*age. which includes co#$uter so0tware and #a5 include associated #edia. $rinted #aterials. and =online= or electronic docu#entation 1='O7-W)6% P6O4>C-=2. -he 'O7-W)6% P6O4>C- also includes an5 u$dates and su$$le#ents to the original 'O7-W)6% P6O4>C- $rovided to 5ou +5 @icroso0t. 35 installing. co$5ing. downloading. accessing or otherwise using the 'O7-W)6% P6O4>C-. 5ou agree to +e +ound +5 the ter#s o0 this %>L). I0 5ou do not agree to the ter#s o0 this %>L). do not install. co$5. or otherwise use the 'O7-W)6% P6O4>C-. 'O7-W)6% P6O4>C- LIC%('% -he 'O7-W)6% P6O4>C- is $rotected +5 co$5right laws and international co$5right treaties. as well as other intellectual $ro$ert5 laws and treaties. -he 'O7-W)6% P6O4>C- is licensed. not sold. 1. G6)(- O7 LIC%('%. -his %>L) grants 5ou the 0ollowing rights, 1.1 License Grant. @icroso0t grants to 5ou as an individual. a $ersonal none&clusive license to #a*e and use co$ies o0 the 'O7-W)6% P6O4>C- 0or the sole $ur$oses o0 evaluating and learning how to use the 'O7-W)6% P6O4>C-. as #a5 +e instructed in acco#$an5ing $u+lications or docu#entation. Bou #a5 install the so0tware on an unli#ited nu#+er o0 co#$uters $rovided that 5ou are the onl5 individual using the 'O7-W)6% P6O4>C-. 1.2 )cade#ic >se. Bou #ust +e a =Quali0ied %ducational >ser= to use the 'O7-W)6% P6O4>C- in the #anner descri+ed in this section. -o deter#ine whether 5ou are a Quali0ied %ducational >ser. $lease contact the @icroso0t 'ales In0or#ation Center?One @icroso0t Wa5?6ed#ond. W) EDF!2;"3EE or the @icroso0t su+sidiar5 serving 5our countr5. I0 5ou are a Quali0ied %ducational >ser. 5ou #a5 either, 1i2 e&ercise the rights granted in 'ection 1.1. O6 1ii2 i0 5ou intend to use the 'O7-W)6% P6O4>C- solel5 0or instructional $ur$oses in connection with a class or other educational $rogra#. this %>L) grants 5ou the 0ollowing alternative license #odels, 1)2 Per Co#$uter @odel. 7or ever5 valid license 5ou have acquired 0or the 'O7-W)6% P6O4>C-. 5ou #a5 install a single co$5 o0 the 'O7-W)6%
##&
P6O4>C- on a single co#$uter 0or access and use +5 an unli#ited nu#+er o0 student end users at 5our educational institution. $rovided that all such end users co#$l5 with all other ter#s o0 this %>L). O6 132 Per License @odel. I0 5ou have #ulti$le licenses 0or the 'O7-W)6% P6O4>C-. then at an5 ti#e 5ou #a5 have as #an5 co$ies o0 the 'O7-W)6% P6O4>C- in use as 5ou have licenses. $rovided that such use is li#ited to student or 0acult5 end users at 5our educational institution and $rovided that all such end users co#$l5 with all other ter#s o0 this %>L). 7or $ur$oses o0 this su+section. the 'O7-W)6% P6O4>C- is =in use= on a co#$uter when it is loaded into the te#$orar5 #e#or5 1i.e.. 6)@2 or installed into the $er#anent #e#or5 1e.g.. hard dis*. C4 6O@. or other storage device2 o0 that co#$uter. e&ce$t that a co$5 installed on a networ* server 0or the sole $ur$ose o0 distri+ution to other co#$uters is not =in use=. I0 the antici$ated nu#+er o0 users o0 the 'O7-W)6% P6O4>C- will e&ceed the nu#+er o0 a$$lica+le licenses. then 5ou #ust have a reasona+le #echanis# or $rocess in $lace to ensure that the nu#+er o0 $ersons using the 'O7-W)6% P6O4>Cconcurrentl5 does not e&ceed the nu#+er o0 licenses. 2. 4%'C6IP-IO( O7 O-9%6 6IG9-' )(4 LI@I-)-IO('. V Li#itations on 6everse %ngineering. 4eco#$ilation. and 4isasse#+l5. Bou #a5 not reverse engineer. deco#$ile. or disasse#+le the 'O7-W)6% P6O4>C-. e&ce$t and onl5 to the e&tent that such activit5 is e&$ressl5 $er#itted +5 a$$lica+le law notwithstanding this li#itation. V 'e$aration o0 Co#$onents. -he 'O7-W)6% P6O4>C- is licensed as a single $roduct. Its co#$onent $arts #a5 not +e se$arated 0or use on #ore than one co#$uter. V 6ental. Bou #a5 not rent. lease or lend the 'O7-W)6% P6O4>C-. V -rade#ar*s. -his %>L) does not grant 5ou an5 rights in connection with an5 trade#ar*s or service #ar*s o0 @icroso0t. V 'o0tware -rans0er. -he initial user o0 the 'O7-W)6% P6O4>C- #a5 #a*e a one;ti#e $er#anent trans0er o0 this %>L) and 'O7-W)6% P6O4>C- onl5 directl5 to an end user. -his trans0er #ust include all o0 the 'O7-W)6% P6O4>C- 1including all co#$onent $arts. the #edia and $rinted #aterials. an5 u$grades. this %>L). and. i0 a$$lica+le. the Certi0icate o0 )uthenticit52. 'uch trans0er #a5 not +e +5 wa5 o0 consign#ent or an5 other indirect trans0er. -he trans0eree o0 such one;ti#e trans0er #ust agree to co#$l5 with the ter#s o0 this %>L). including the o+ligation not to 0urther trans0er this %>L) and 'O7-W)6% P6O4>C-. V (o 'u$$ort. @icroso0t shall have no o+ligation to $rovide an5 $roduct su$$ort 0or the 'O7-W)6% P6O4>C-. V -er#ination. Without $re/udice to an5 other rights. @icroso0t #a5 ter#inate this %>L) i0 5ou 0ail to co#$l5 with the ter#s and conditions o0 this %>L). In
##'
such event. 5ou #ust destro5 all co$ies o0 the 'O7-W)6% P6O4>C- and all o0 its co#$onent $arts. 3. COPB6IG9-. )ll title and intellectual $ro$ert5 rights in and to the 'O7-W)6% P6O4>C- 1including +ut not li#ited to an5 i#ages. $hotogra$hs. ani#ations. video. audio. #usic. te&t. and =a$$lets= incor$orated into the 'O7-W)6% P6O4>C-2. the acco#$an5ing $rinted #aterials. and an5 co$ies o0 the 'O7-W)6% P6O4>C- are owned +5 @icroso0t or its su$$liers. )ll title and intellectual $ro$ert5 rights in and to the content which #a5 +e accessed through use o0 the 'O7-W)6% P6O4>C- is the $ro$ert5 o0 the res$ective content owner and #a5 +e $rotected +5 a$$lica+le co$5right or other intellectual $ro$ert5 laws and treaties. -his %>L) grants 5ou no rights to use such content. )ll rights not e&$ressl5 granted are reserved +5 @icroso0t. . 3)CR>P COPB. )0ter installation o0 one co$5 o0 the 'O7-W)6% P6O4>C$ursuant to this %>L). 5ou #a5 *ee$ the original #edia on which the 'O7-W)6% P6O4>C- was $rovided +5 @icroso0t solel5 0or +ac*u$ or archival $ur$oses. I0 the original #edia is required to use the 'O7-W)6% P6O4>C- on the CO@P>-%6. 5ou #a5 #a*e one co$5 o0 the 'O7-W)6% P6O4>C- solel5 0or +ac*u$ or archival $ur$oses. %&ce$t as e&$ressl5 $rovided in this %>L). 5ou #a5 not otherwise #a*e co$ies o0 the 'O7-W)6% P6O4>C- or the $rinted #aterials acco#$an5ing the 'O7-W)6% P6O4>C-. !. >.'. GO8%6(@%(- 6%'-6IC-%4 6IG9-'. -he 'O7-W)6% P6O4>C- and docu#entation are $rovided with 6%'-6IC-%4 6IG9-'. >se. du$lication. or disclosure +5 the Govern#ent is su+/ect to restrictions as set 0orth in su+$aragra$h 1c21121ii2 o0 the 6ights in -echnical 4ata and Co#$uter 'o0tware clause at 47)6' 2!2.22C;CF13 or su+$aragra$hs 1c2112 and 122 o0 the Co##ercial Co#$uter 'o0tware;6estricted 6ights at D C76 !2.22C;1E. as a$$lica+le. @anu0acturer is @icroso0t Cor$oration?One @icroso0t Wa5?6ed#ond. W) EDF!2;"3EE. ". %TPO6- 6%'-6IC-IO('. Bou agree that 5ou will not e&$ort or re;e&$ort the 'O7-W)6% P6O4>C-. an5 $art thereo0. or an5 $rocess or service that is the direct $roduct o0 the 'O7-W)6% P6O4>C- 1the 0oregoing collectivel5 re0erred to as the =6estricted Co#$onents=2. to an5 countr5. $erson. entit5 or end user su+/ect to >.'. e&$ort restrictions. Bou s$eci0icall5 agree not to e&$ort or re; e&$ort an5 o0 the 6estricted Co#$onents 1i2 to an5 countr5 to which the >.'. has e#+argoed or restricted the e&$ort o0 goods or services. which currentl5 include. +ut are not necessaril5 li#ited to Cu+a. Iran. Iraq. Li+5a. (orth Rorea. 'udan and '5ria. or to an5 national o0 an5 such countr5. wherever located. who intends to trans#it or trans$ort the 6estricted Co#$onents +ac* to such countr5L 1ii2 to an5 end;user who 5ou *now or have reason to *now will utili:e the 6estricted Co#$onents in the design. develo$#ent or $roduction o0 nuclear. che#ical or +iological wea$onsL or 1iii2 to an5 end;user who has +een
#&(
$rohi+ited 0ro# $artici$ating in >.'. e&$ort transactions +5 an5 0ederal agenc5 o0 the >.'. govern#ent. Bou warrant and re$resent that neither the 3T) nor an5 other >.'. 0ederal agenc5 has sus$ended. revo*ed. or denied 5our e&$ort $rivileges. C. (O-% O( A)8) '>PPO6-. -9% 'O7-W)6% P6O4>C- @)B CO(-)I( '>PPO6- 7O6 P6OG6)@' W6I--%( I( A)8). A)8) -%C9(OLOGB I' (O7)>L- -OL%6)(- )(4 I' (O- 4%'IG(%4. @)(>7)C->6%4. O6 I(-%(4%4 7O6 >'% O6 6%')L% )' O(;LI(% CO(-6OL %Q>IP@%(- I( 9)W)64O>' %(8I6O(@%(-' 6%Q>I6I(G 7)IL;')7% P%67O6@)(C%. '>C9 )' I( -9% OP%6)-IO( O7 (>CL%)6 7)CILI-I%'. )I6C6)7- ()8IG)-IO( O6 CO@@>(IC)-IO( 'B'-%@'. )I6 -6)77IC CO(-6OL. 4I6%C- LI7% '>PPO6@)C9I(%'. O6 W%)PO(' 'B'-%@'. I( W9IC9 -9% 7)IL>6% O7 A)8) -%C9(OLOGB CO>L4 L%)4 4I6%C-LB -O 4%)-9. P%6'O()L I(A>6B. O6 '%8%6% P9B'IC)L O6 %(8I6O(@%(-)L 4)@)G%. @I'C%LL)(%O>' I0 5ou acquired this $roduct in the >nited 'tates. this %>L) is governed +5 the laws o0 the 'tate o0 Washington. I0 5ou acquired this $roduct in Canada. this %>L) is governed +5 the laws o0 the Province o0 Ontario. Canada. %ach o0 the $arties hereto irrevoca+l5 attorns to the /urisdiction o0 the courts o0 the Province o0 Ontario and 0urther agrees to co##ence an5 litigation which #a5 arise hereunder in the courts located in the Audicial 4istrict o0 Bor*. Province o0 Ontario. I0 this $roduct was acquired outside the >nited 'tates. then local law #a5 a$$l5. 'hould 5ou have an5 questions concerning this %>L). or i0 5ou desire to contact @icroso0t 0or an5 reason. $lease contact @icroso0t. or write, @icroso0t 'ales In0or#ation Center?One @icroso0t Wa5?6ed#ond. W) EDF!2;"3EE. LI@I-%4 W)66)(-B LI@I-%4 W)66)(-B. @icroso0t warrants that 1a2 the 'O7-W)6% P6O4>C- will $er0or# su+stantiall5 in accordance with the acco#$an5ing written #aterials 0or a $eriod o0 ninet5 1EF2 da5s 0ro# the date o0 recei$t. and 1+2 an5 'u$$ort 'ervices $rovided +5 @icroso0t shall +e su+stantiall5 as descri+ed in a$$lica+le written #aterials $rovided to 5ou +5 @icroso0t. and @icroso0t su$$ort engineers will #a*e co##erciall5 reasona+le e00orts to solve an5 $ro+le#. -o the e&tent allowed +5 a$$lica+le law. i#$lied warranties on the 'O7-W)6% P6O4>C-. i0 an5. are li#ited to ninet5 1EF2 da5s. 'o#e states?/urisdictions do
#&1
not allow li#itations on duration o0 an i#$lied warrant5. so the a+ove li#itation #a5 not a$$l5 to 5ou. C>'-O@%6 6%@%4I%'. @icroso0tXs and its su$$liersX entire lia+ilit5 and 5our e&clusive re#ed5 shall +e. at @icroso0tXs o$tion. either 1a2 return o0 the $rice $aid. i0 an5. or 1+2 re$air or re$lace#ent o0 the 'O7-W)6% P6O4>C- that does not #eet @icroso0tXs Li#ited Warrant5 and that is returned to @icroso0t with a co$5 o0 5our recei$t. -his Li#ited Warrant5 is void i0 0ailure o0 the 'O7-W)6% P6O4>C- has resulted 0ro# accident. a+use. or #isa$$lication. )n5 re$lace#ent 'O7-W)6% P6O4>C- will +e warranted 0or the re#ainder o0 the original warrant5 $eriod or thirt5 13F2 da5s. whichever is longer. Outside the >nited 'tates. neither these re#edies nor an5 $roduct su$$ort services o00ered +5 @icroso0t are availa+le without $roo0 o0 $urchase 0ro# an authori:ed international source. (O O-9%6 W)66)(-I%'. -O -9% @)TI@>@ %T-%(- P%6@I--%4 3B )PPLIC)3L% L)W. @IC6O'O7- )(4 I-' '>PPLI%6' 4I'CL)I@ )LL O-9%6 W)66)(-I%' )(4 CO(4I-IO('. %I-9%6 %TP6%'' O6 I@PLI%4. I(CL>4I(G. 3>- (O- LI@I-%4 -O. I@PLI%4 W)66)(-I%' O6 CO(4I-IO(' O7 @%6C9)(-)3ILI-B. 7I-(%'' 7O6 ) P)6-IC>L)6 P>6PO'%. -I-L% )(4 (O(; I(76I(G%@%(-. WI-9 6%G)64 -O -9% 'O7-W)6% P6O4>C-. )(4 -9% P6O8I'IO( O7 O6 7)IL>6% -O P6O8I4% '>PPO6- '%68IC%'. -9I' LI@I-%4 W)66)(-B GI8%' BO> 'P%CI7IC L%G)L 6IG9-'. BO> @)B 9)8% O-9%6'. W9IC9 8)6B 76O@ '-)-%?A>6I'4IC-IO( -O '-)-%?A>6I'4IC-IO(. LI@I-)-IO( O7 LI)3ILI-B. -O -9% @)TI@>@ %T-%(- P%6@I--%4 3B )PPLIC)3L% L)W. I( (O %8%(- '9)LL @IC6O'O7- O6 I-' '>PPLI%6' 3% LI)3L% 7O6 )(B 'P%CI)L. I(CI4%(-)L. I(4I6%C-. O6 CO('%Q>%(-I)L 4)@)G%' W9)-'O%8%6 1I(CL>4I(G. WI-9O>- LI@I-)-IO(. 4)@)G%' 7O6 LO'' O7 3>'I(%'' P6O7I-'. 3>'I(%'' I(-%66>P-IO(. LO'' O7 3>'I(%'' I(7O6@)-IO(. O6 )(B O-9%6 P%C>(I)6B LO''2 )6I'I(G O>- O7 -9% >'% O7 O6 I()3ILI-B -O >'% -9% 'O7-W)6% P6O4>C- O6 -9% 7)IL>6% -O P6O8I4% '>PPO6- '%68IC%'. %8%( I7 @IC6O'O7- 9)' 3%%( )48I'%4 O7 -9% PO''I3ILI-B O7 '>C9 4)@)G%'. I( )(B C)'%. @IC6O'O7-X' %(-I6% LI)3ILI-B >(4%6 )(B P6O8I'IO( O7 -9I' %>L) '9)LL 3% LI@I-%4 -O -9% G6%)-%6 O7 -9% )@O>(- )C->)LLB P)I4 3B BO> 7O6 -9% 'O7-W)6% P6O4>C- O6 >.'.Y!.FFL P6O8I4%4. 9OW%8%6. I7 BO> 9)8% %(-%6%4 I(-O ) @IC6O'O7- '>PPO6- '%68IC%' )G6%%@%(-. @IC6O'O7-X' %(-I6% LI)3ILI-B 6%G)64I(G '>PPO6- '%68IC%' '9)LL 3% GO8%6(%4 3B -9% -%6@' O7 -9)- )G6%%@%(-. 3%C)>'% 'O@% '-)-%'?A>6I'4IC-IO(' 4O (O- )LLOW -9% %TCL>'IO( O6 LI@I-)-IO( O7 LI)3ILI-B. -9% )3O8% LI@I-)-IO( @)B (O- )PPLB -O BO>. F E! Part (o. " 3!D
#&)
LIC%('% )G6%%@%(- 7O6 @ind8iew. Inc.Xs -hin*ing in C, 7oundations 0or Aava I CUU C4 6O@ +5 Chuc* )llison -his C4 is $rovided together with the +oo* =-hin*ing in Aava. 2 nd edition.= 6%)4 -9I' )G6%%@%(- 3%7O6% >'I(G -9I' =-hin*ing in C, 7oundations 0or CUU I Aava= 19erea0ter called =C4=2. 3B >'I(G -9% C4 BO> )G6%% -O 3% 3O>(4 3B -9% -%6@' )(4 CO(4I-IO(' O7 -9I' )G6%%@%(-. I7 BO> 4O (O- )G6%% -O -9% -%6@' )(4 CO(4I-IO(' O7 -9I' )G6%%@%(-. I@@%4I)-%LB 6%->6( -9% >(>'%4 C4 7O6 ) 7>LL 6%7>(4 O7 @O(I%' P)I4. I7 )(B. Z2FFF @ind8iew. Inc. )ll rights reserved. Printed in the >.'. 'O7-W)6% 6%Q>I6%@%(-' -he $ur$ose o0 this C4 is to $rovide the Content. not the associated so0tware necessar5 to view the Content. -he Content o0 this C4 is in 9-@L 0or viewing with @icroso0t Internet %&$lorer or newer. and uses @icroso0t 'ound Codecs availa+le in @icroso0tXs Windows @edia Pla5er 0or Windows. It is 5our res$onsi+ilit5 to correctl5 install the a$$ro$riate @icroso0t so0tware 0or 5our s5ste#. -he te&t. i#ages. and other #edia included on this C4 1=Content=2 and their co#$ilation are licensed to 5ou su+/ect to the ter#s and conditions o0 this )gree#ent +5 @ind8iew. Inc.. having a $lace o0 +usiness at !3 3 8alle 8ista. La @esa. C) E1E 1. Bour rights to use other $rogra#s and #aterials included on the C4 are also governed +5 se$arate agree#ents distri+uted with those $rogra#s and #aterials on the C4 1the =Other )gree#ents=2. In the event o0 an5 inconsistenc5 +etween this )gree#ent and the Other )gree#ents. this )gree#ent shall govern. 35 using this C4. 5ou agree to +e +ound +5 the ter#s and conditions o0 this )gree#ent. @ind8iew. Inc. owns title to the Content and to all intellectual $ro$ert5 rights therein. e&ce$t inso0ar as it contains #aterials that are $ro$rietar5 to third;$art5 su$$liers. )ll rights in the Content e&ce$t those e&$ressl5 granted to 5ou in this )gree#ent are reserved to @ind8iew. Inc. and such su$$liers as their res$ective interests #a5 a$$ear. 1. LI@I-%4 LIC%('% @ind8iew. Inc. grants 5ou a li#ited. none&clusive. nontrans0era+le license to use the Content on a single dedicated co#$uter 1e&cluding networ* servers2. -his )gree#ent and 5our rights hereunder shall auto#aticall5 ter#inate i0 5ou
0ail to co#$l5 with an5 $rovisions o0 this )gree#ent or an5 o0 the Other )gree#ents. >$on such ter#ination. 5ou agree to destro5 the C4 and all co$ies o0 the C4. whether law0ul or not. that are in 5our $ossession or under 5our control. 2. )44I-IO()L 6%'-6IC-IO(' a. Bou shall not 1and shall not $er#it other $ersons or entities to2 directl5 or indirectl5. +5 electronic or other #eans. re$roduce 1e&ce$t 0or archival $ur$oses as $er#itted +5 law2. $u+lish. distri+ute. rent. lease. sell. su+license. assign. or otherwise trans0er the Content or an5 $art thereo0. +. Bou shall not 1and shall not $er#it other $ersons or entities to2 use the Content or an5 $art thereo0 0or an5 co##ercial $ur$ose or #erge. #odi05. create derivative wor*s o0. or translate the Content. c. Bou shall not 1and shall not $er#it other $ersons or entities to2 o+scure @ind8iewXs or its su$$liers co$5right. trade#ar*. or other $ro$rietar5 notices or legends 0ro# an5 $ortion o0 the Content or an5 related #aterials. 3. P%6@I''IO(' a. %&ce$t as noted in the Contents o0 the C4. 5ou #ust treat this so0tware /ust li*e a +oo*. 9owever. 5ou #a5 co$5 it onto a co#$uter to +e used and 5ou #a5 #a*e archival co$ies o0 the so0tware 0or the sole $ur$ose o0 +ac*ing u$ the so0tware and $rotecting 5our invest#ent 0ro# loss. 35 sa5ing. =/ust li*e a +oo*.= @ind8iew. Inc. #eans. 0or e&a#$le. that this so0tware #a5 +e used +5 an5 nu#+er o0 $eo$le and #a5 +e 0reel5 #oved 0ro# one co#$uter location to another. so long as there is no $ossi+ilit5 o0 its +eing used at one location or on one co#$uter while it is +eing used at another. Aust as a +oo* cannot +e read +5 two di00erent $eo$le in two di00erent $laces at the sa#e ti#e. neither can the so0tware +e used +5 two di00erent $eo$le in two di00erent $laces at the sa#e ti#e. +. Bou #a5 show or de#onstrate the un;#odi0ied Content in a live $resentation. live se#inar. or live $er0or#ance as long as 5ou attri+ute all #aterial o0 the Content to @ind8iew. Inc. c. Other $er#issions and grants o0 rights 0or use o0 the C4 #ust +e o+tained directl5 0ro# @ind8iew. Inc. at htt$,??www.@ind8iew.net. 13ul* co$ies o0 the C4 #a5 also +e $urchased at this site.2 4I'CL)I@%6 O7 W)66)(-B -he Content and C4 are $rovided =)' I'= without warrant5 o0 an5 *ind. either
e&$ress or i#$lied. including. without li#itation. an5 warrant5 o0 #erchanta+ilit5 and 0itness 0or a $articular $ur$ose. -he entire ris* as to the results and $er0or#ance o0 the C4 and Content is assu#ed +5 5ou. @ind8iew. Inc. and its su$$liers assu#e no res$onsi+ilit5 0or de0ects in the C4. the accurac5 o0 the Content. or o#issions in the C4 or the Content. @ind8iew. Inc. and its su$$liers do not warrant. guarantee. or #a*e an5 re$resentations regarding the use. or the results o0 the use. o0 the $roduct in ter#s o0 correctness. accurac5. relia+ilit5. currentness. or otherwise. or that the Content will #eet 5our needs. or that o$eration o0 the C4 will +e uninterru$ted or error;0ree. or that an5 de0ects in the C4 or Content will +e corrected. @ind8iew. Inc. and its su$$liers shall not +e lia+le 0or an5 loss. da#ages. or costs arising 0ro# the use o0 the C4 or the inter$retation o0 the Content. 'o#e states do not allow e&clusion or li#itation o0 i#$lied warranties or li#itation o0 lia+ilit5 0or incidental or consequential da#ages. so all o0 the a+ove li#itations or e&clusions #a5 not a$$l5 to 5ou. In no event shall @ind8iew. Inc. or its su$$liersX total lia+ilit5 to 5ou 0or all da#ages. losses. and causes o0 action 1whether in contract. tort. or otherwise2 e&ceed the a#ount $aid +5 5ou 0or the C4. @ind8iew. Inc.. and Prentice;9all. Inc. s$eci0icall5 disclai# the i#$lied warrantees o0 #erchanta+ilit5 and 0itness 0or a $articular $ur$ose. (o oral or written in0or#ation or advice given +5 @ind8iew. Inc.. Prentice;9all. Inc.. their dealers. distri+utors. agents or e#$lo5ees shall create a warrantee. Bou #a5 have other rights. which var5 0ro# state to state. (either @ind8iew. Inc.. 3ruce %c*el. Chuc* )llison. Prentice;9all. nor an5one else who has +een involved in the creation. $roduction or deliver5 o0 the $roduct shall +e lia+le 0or an5 direct. indirect. consequential. or incidental da#ages 1including da#ages 0or loss o0 +usiness $ro0its. +usiness interru$tion. loss o0 +usiness in0or#ation. and the li*e2 arising out o0 the use o0 or ina+ilit5 to use the $roduct even i0 @ind8iew. Inc.. has +een advised o0 the $ossi+ilit5 o0 such da#ages. 3ecause so#e states do not allow the e&clusion or li#itation o0 lia+ilit5 0or consequential or incidental da#ages. the a+ove li#itation #a5 not a$$l5 to 5ou. -his C4 is $rovided as a su$$le#ent to the +oo* =-hin*ing in Aava 2nd edition.= -he sole res$onsi+ilit5 o0 Prentice;9all will +e to $rovide a re$lace#ent C4 in the event that the one that ca#e with the +oo* is de0ective. -his re$lace#ent warrantee shall +e in e00ect 0or a $eriod o0 si&t5 da5s 0ro# the $urchase date. @ind8iew. Inc. does not +ear an5 additional res$onsi+ilit5 0or the C4. (O -%C9(IC)L '>PPO6- I' P6O8I4%4 WI-9 -9I' C4 6O@
#&5
-he 0ollowing are trade#ar*s o0 their res$ective co#$anies in the >.'. and #a5 +e $rotected as trade#ar*s in other countries, 'un and the 'un Logo. 'un @icros5ste#s. Aava. all Aava;+ased na#es and logos and the Aava Co00ee Cu$ are trade#ar*s o0 'un @icros5ste#sL Internet %&$lorer. the Windows @edia Pla5er. 4O'. Windows E!. and Windows (- are trade#ar*s o0 @icroso0t.
The C? ROA packaged !ith thi# 3**k i# a +ulti+edia #e+inar c*n#i#ting *9 #ynchr*ni7ed #lide# and audi* lecture#) The g*al *9 thi# #e+inar i# t* intr*duce y*u t* the a#pect# *9 C that are nece##ary 9*r y*u t* +*ve *n t* C@@ *r "ava, leaving *ut the unplea#ant part# that C pr*gra++er# +u#t deal !ith *n a dayEt*Eday 3a#i# 3ut that the C@@ and "ava language# #teer y*u a!ay 9r*+) The C? al#* c*ntain# thi# 3**k in HTAL 9*r+ al*ng !ith the #*urce c*de 9*r the 3**k) Thi# C? ROA !ill !*rk !ith ,ind*!# G!ith a #*und #y#te+H) H*!ever, y*u +u#t1
0) -n#tall the +*#t recent ver#i*n *9 Aicr*#*9t# -nternet E;pl*rer) Becau#e *9 the 9eature# pr*vided *n the C?, it !ill OT !*rk !ith et#cape avigat*r) +he Bnternet &xplorer software for =indows R?/,+ is included on the C$6 2) -n#tall Aicr*#*9t# Gindows .edia /la4er) +he .edia !layer software for =indows R?/,+ is included on the C$6 :*u can al#* g* t* httpD//www6microsoft6com/windows/mediaplayer and 9*ll*! the in#tructi*n# *r link# there t* d*!nl*ad and in#tall the Aedia Player 9*r y*ur particular plat9*r+) /) =t thi# p*int y*u #h*uld 3e a3le t* play the lecture# *n the C?) U#ing the -nternet E;pl*rer ,e3 3r*!#er, *pen the 9ile Bnstall6html that y*ull 9ind *n the C?) Thi# !ill intr*duce y*u t* the C? and pr*vide 9urther in#tructi*n# a3*ut the u#e *9 the C?)
#&#