Académique Documents
Professionnel Documents
Culture Documents
Tartalomjegyzk
A C#-rl rviden........................................................................................................................7
A C# trtnete...................................................................................................................................7 Szerkeszt hasznlata......................................................................................................................7 Forrsfjlok elnevezse....................................................................................................................8 A C# program vgrehajtsrl........................................................................................................8 A C# forrskd fordtsa kztes nyelvre........................................................................................9
C# objektumkzpont nyelv....................................................................................................10
Els C# programunk......................................................................................................................10 A C# programok tpusai................................................................................................................11 A C#, mint objektum orientlt programozsi nyelv....................................................................11
Egysgbe zrs...............................................................................................................................................11 Tbbalaksg.................................................................................................................................................12 rkls...........................................................................................................................................................12 jrahasznosthatsg.....................................................................................................................................12 Objektumok s osztlyok...............................................................................................................................13 A C# modulris..............................................................................................................................................13
.NET madrtvlatbl.....................................................................................................................13
A C# programok.......................................................................................................................14
A C# alkalmazsok felptse........................................................................................................14
A megjegyzsekrl........................................................................................................................................15
A C# alkalmazsok alapelemei......................................................................................................17
Formzs trkzkkel....................................................................................................................................17 Kulcsszavak a C# nyelv alapkvei.............................................................................................................18 Literlok.........................................................................................................................................................18 Azonostk.....................................................................................................................................................18
A C# alkalmazsok szerkezete.......................................................................................................19
Utastsok s kifejezsek a C#-ban................................................................................................................19 Az res utasts..............................................................................................................................................19
Adattrols vltozkkal.................................................................................................................19
A vltozk hasznlata....................................................................................................................................20 rtkads a vltozknak................................................................................................................................20 Vltozk kezdrtk nlkl...........................................................................................................................21
A C# adattpusai.............................................................................................................................21
Lebegpontos rtkek....................................................................................................................................22 Logikai rtkek..............................................................................................................................................22 Adattpusok a .NET krnyezetben.................................................................................................................22 Literlok vagy vltozk?...............................................................................................................................23 Egsz literlok...............................................................................................................................................23 Lebegpontos literlok..................................................................................................................................24 Logikai literlok.............................................................................................................................................24 Karakterlnc literlok....................................................................................................................................24 llandk ltrehozsa.....................................................................................................................................24 Hivatkozsi tpusok.......................................................................................................................................25
Felhasznlt irodalom.............................................................................................................216
A C#-rl rviden
A C# trtnete
A C# bta vltozathoz elszr 2000 jniusban juthatott hozz a nagykznsg, a hivatalos kiads pedig 2002 tavaszn ltott napvilgot, gy a nyelv valban nincs tl rgen jelen a kztudatban. A C# (c kereszt vagy C sharp) szlatyja a Microsoft, szabvnyostsrl pedig az ECMA gondoskodott. Kszti kztt vezetkent feltnik az az Andres Hejlsberg is, aki a korbbiakban mr ms programozsi nyelek ksztsnl Borland C++, Borland Delphi megmutatta oroszlnkrmeit. A C# fejlesztsnl a Microsoft programozi csoportja megprblta tvenni a mr ltez programnyelvek j tulajdonsgait, itt-ott tovbbi javtsokat, fejlesztseket eszkzlve. Jllehet a C# a Microsoft fejlesztsnek eredmnye, hasznlata mgsem korltozhat Microsoft rendszerekre. Lteznek C# fordtk a FreeBSD, a Linux s a Macintosh rendszereken, tovbb szmos Microsoft felleten. A C# igen hatkony s rugalmas programozsi nyelv, mellyel szmos nyelvekhez hasonlan alkalmazsok szles krt kszthetjk el. Maga a nyelv nem korltozza a programozt tevkenysgben, gy fantzink hatrtalanul szrnyalhat. Mindezt mi sem mutatja jobban, mint az, hogy a C#-ot hasznltk mr dinamikus webhelyek, fejleszteszkzk, st fordtprogramok ksztshez is.
Szerkeszt hasznlata
A Microsoft a C# lehetsgeit elrhetv tette a Microsoft Visual Studio .NET-ben, amely gy tartalmazza a Microsoft Visual Studio C# .NET-et is. Ezzel a legismertebb szerkeszt a C# programozshoz mindazonltal ahhoz, hogy C# programokat ksztsnk, nincs felttlenl szksgnk a Visual Studio .NET-re vagy a Visual C# .NET-re. Lteznek ugyanis ms szerkesztk is, melyek nmelyike a Visual Studio .NET-hez hasonlan lehetv teszi, hogy a szerkeszt elhagysa nlkl vgezzk el a fejleszts folyamatnak sszes lpst. Tbbsgk emellett ms szolgltatsokat is nyjt, gy pldul a bert szvegek sznkdolst ezzel, sokkal knnyebben rbukkanhatunk az esetleges hibkra. Szmos szerkeszt mg abban is segt, mit rjunk be egy adott helyen, tovbb sokoldal sgval kedveskedik szmunkra. Azonban C# programot lehet kszteni akr a Microsoft Windows rendszereken tallhat Jegyzettmb vagy a WordPad nev alkalmazs, Linux s Unix rendszereken pedig a jl hasznlhat az ed, az ex, az edit, az emacs, vagy a vi.
C# Amit a C# tudni rdemes! Ha ms szerkesztt szeretnnk hasznlni, arra is van lehetsg. Ilyen szerkesztk akr ingyen is beszerezhetk: SharpDevelop A SharpDevelop egy ingyenes szerkeszt, melyet a C# s a VB.NET projektekhez hasznlhatunk a Microsoft .NET felleten. Mivel a szerkeszt nylt forrs (GPL), a www.icsharpcode.net cmrl a futtathat fjlok mellett a forrskdot is letlthetjk. CodeWright A CodeWright olyan szerkeszt, amely kln tmogatst biztost az ASP, az XML, a HTML, a C#, a Perl, a Python s ms formtumokhoz. A 30 napos prbavltozatt letlthetjk a www.premia.com cmrl. A CodeWright jelenleg a Borlandhoz tartozik. JEdit A JEdit egy nylt forrs Java szerkeszt, amely azonban egyttal hasznlhat C# programok szerkesztsre is, a kd sznezsnek lehetsgvel. A programot a http://jedit.sourceforge.net cmen tallhatjuk meg.
Forrsfjlok elnevezse
Ha elkszlt a forrsfjl, termszetesen nevet kell adnunk neki ennek a nvnek pedig le kell rnia, mit is tesz a program. Forrsfjljaink kiterjesztst szabadon megvlaszthatjuk, de jobban jrunk, ha megmaradunk az ltalnosan elismert, szabvnyos .cs-nl. A nvnek le kell rnia a program mkdst. Sokan vlik gy, hogy ez a nv j, ha megegyezik az adott C# osztly nevvel.
A C# program vgrehajtsrl
Fontos, hogy nmikpp tisztban legynk azzal, miknt trtnik a C# programok vgrehajtsa ezek a programok ugyanis e tren eltrnek a szoksos programnyelveken rt trsaiktl. A C# programokat a .NET Common Language Runtime (CLR) krnyezetben futtathatjuk. Ez azt jelenti, hogy ha elksztnk egy futtathat C# programot, s megksreljk elindtani egy olyan gpen, melyen nincs jelen a CLR, vagy ms, vele sszeegyeztethet futsidej krnyezet, a futs nem sikerl. A futsidej krnyezet hasznlatnak elnye a hordozhatsg. Ha korbban olyan programot szerettnk volna kszteni valamely rgebbi programnyelven mondjuk C-ben vagy C++-ban -, ami kpes klnbz opercis rendszereken s felleteken futni, mindegyikk esetben kln futtathat programot kellett ksztennk a fordtval. Ha pldul, ksztnk egy C alkalmazst, s egy Linux s egy Windows gpen is futtatni akartuk, kt futtathat programot kellett ksztennk egyet a Linuxhoz, egyet a Windowshoz. A C# esetben csak egyre van szksgnk, s ez mkdik mindkt rendszeren. Ha programunkat a lehet leggyorsabban szeretnnk futtatni, valdi futtathat fjlt kell belle ksztennk. Ehhez a forrskdot gpi kdra kell fordtanunk egy fordtprogrammal. A fordtprogram teht fogja a forrsfjlunkat, s utastsait gpi kd utastsokk alaktja t. Ksztette: Zstr Csaba III. ves informatikus hallgat 8
C# Amit a C# tudni rdemes! A C, C++ s hasonl programnyelveken kszlt programok esetben a fordtprogram olyan fjlt ad, amely minden tovbbi erfeszts nlkl egyszeren futtathat. A C# esetben fordtprogramunk nem kzvetlenl gpi kdra fordt, hanem egy kztes nyelvre (Intermediate Language - IL). Az gy kapott IL fjlt ezutn tmsolhatjuk brmely .NET CLR krnyezettel rendelkez gpre. Mivel ez az IL fjl kzvetlenl nem futtathat, tovbbi fordtsra van szksg a mkdshez ezt teszi meg a CLR, vagy ms C# futsidej krnyezet. A CLR, ha IL fjlt lt, els dolga, hogy lefordtsa. Ilyenkor a hordozhat IL kdot talaktja gpi kdd, amit a szmtgp mr kpes rtelmezni s futtatni. A dolog persze ennl egy kicsit sszetettebb, a CLR ugyanis valjban csak a program ppen hasznlatban lv rszt fordtja le, hogy idt takartson meg. Ezt a vgs fordtst nevezik Just In Time (JIT) fordtsnak. Mivel teht az IL fjlokat futs idben kell fordtani, a program kezdetben lassabban fut, mintha egy teljes fordts nyelven, pldul C++-ban rtk volna. Ha azonban egy adott rszt mr futtattunk, a klnbsg eltnik, ugyanis innentl kezdve a rendszer a teljes lefordtott kdot hasznlja. Az esetek tbbsgben ez a kezdeti idkiess elhanyagolhat, st lehetsgnk van arra is, hogy C# programunkat rgtn lefordtsuk a JIT-tel, mihelyt teleptjk egy rendszerbe.
C# Amit a C# tudni rdemes! a CLR-nak szksge van a futtatshoz. A .NET szhasznlata szerint az e fjlban tallhat kd neve kezelt kd (managed code). Miutn programunkat IL fjll fordtottuk, futtathatjuk gy, hogy berjuk a nevt a parancssorba, vagy brhogy, ahogyan ms programot szoktunk. Azt viszont nem szabad elfelejtennk, hogy a programnak a futshoz szksge van a .NET CLR-re ha nem teleptjk ezt a krnyezetet, futtatskor csak egy hibazenetet kapunk. Ha ellenben teleptjk a Microsoft .NET krnyezett, a futs pontosan gy zajlik, mint brmely ms program esetben.
C# objektumkzpont nyelv
Els C# programunk
Pldnkban egy Hello.cs nev programot hasznlunk, mely mindssze a Hello, World! feliratot rja ki a kpernyre: 2.1 kdszveg Hello.cs
Gpeljk be a fenti kdszveget a szerkesztnkbe s mentsk Hello.cs nven. gyeljnk arra, hogy a C#-nl a Main() nagybetvel rdik, mg ms programnyelveken ilyen a C, vagy a C++ - kisbetvel. Ha nem nagy M-et hasznlunk fordtsi hibt kapunk. Ha ezen kis programocskt futtatni szeretnnk, nincs ms dolgunk, mint a lefordtani a Hello.cs fjl. Ehhez rjuk be a kvetkezt a parancssorba: csc Hello.cs Ha egyestett fejleszti krnyezetet hasznlunk (IDE), vlasszuk a megfelel gombot (ikont), gyorsbillentyt vagy menpontot. Ha minden jl vgeztnk, egy zenetet kell kapjunk arrl, hogy nincs figyelmeztets, vagy fordtsi hiba. Ha lefordtottuk, akkor a fordts helyl szolgl knyvtrban, illetve mappban tallunk egy Hello.exe nev fjlt. Futtatshoz egyszeren rjuk be a Hello szt a parancssorba; ekkor kpernynkn megjelenik a Hello, World! felrat. Ksztette: Zstr Csaba III. ves informatikus hallgat 10
A C# programok tpusai
Mieltt tovbb folytatnnk utunkat a C# rejtelmei kzt, fontos dolog, hogy megismerkedjnk, hogy pontosan milyen programokat kszthetnk a C#-al: Konzolalkalmazsok A konzolalkalmazsokat a parancssorbl indthatk. Ablakos alkalmazsok Kszthetnk olyan Windows-alkalmazsokat is, melyek kihasznljk a rendszer nyjtotta grafikus felhasznli felletet (GUI). Webszolgltatsok Ezek olyan eljrsok, melyeket a Vilghln keresztl lehet meghvni. Webes formok / ASP.NET alkalmazsok Az ASP.NET alkalmazsokat webkiszolglkon futtathatjuk, segtsgkkel dinamikus weblapokat kszthetnk. Az albbi tpus programok ksztse mellett a C# nyelvet szmos ms feladatra is hasznlhatjuk, gy kszthetnk a segtsgvel knyvtrakat, vezrlket s ms egyebeket.
Egysgbe zrs
Az egysgbe zrs gyakorlatilag annyit jelent, hogy csomagokat ksztnk, melyekbe mindent beletesznk, ami az adott feladathoz szksges. Az objektumkzpont programozs Ksztette: Zstr Csaba III. ves informatikus hallgat 11
C# Amit a C# tudni rdemes! esetben objektumokat (csomagokat) ksztnk, pldul egy krt, amely maga kpes elvgezni mindent, amit egy krrel megtehetnk. Ebbe beletartozik a kr adatainak sugr s kzppont nyilvntartsa, de ki kell tudnia szmtani pldul ms adatokbl a sugarat, vagy ppen kirajzolni a krt. A kr egysgbe zrsval teht elrhet, hogy a felhasznlnak ne kelljen ismernie a kr mkdst, elg legyen tudnia, miknt bnjon vele. gy elrejthetjk elle a bels mveleteket.
Tbbalaksg
A tbbalaksg az objektumkzpont programozs kt (ha nem tbb) klnbz terletn is alkalmazhat. Elszr is, segtsgvel egy objektumot vagy eljrst tbbfle mdon meghvhatunk, mgis azonos eredmnyt kapunk. A kr pldjnl maradva, ez azt jelenti, hogy he meg szeretnnk hatrozni a kr terlett, megadhatjuk hrom pontjt, vagy a kzppontjt s a sugart. Termszetesen minkt esetben ugyanazt az eredmnyt kapjuk. Eljrs alap nyelvekben, mint a C, kt, eltr nev eljrsra van szksg a terlet e kt mdon trtn kiszmtshoz C# is kettre van szksg, de ezek neve megegyezhet. Ha ezutn egy program a terletet szeretn kiszmolni, akkor csak meghvja ezt az eljrst, tadva a paramtereket, s program automatikusan eldnti, hogy melyik mdszerrel szmtsa ki az eredmnyt. A felhasznlnak gy nem kell foglalkoznia azzal, hogy melyik eljrst hvja meg az a program feladata. A tbbalaksg msik s taln fontosabb felhasznlsa az alkalmazkodst teszi lehetv, olyan adatok kezelst, melyekrl esetleg elzleg semmit sem tudunk. Tegyk fel, hogy klnbz alakzataink vannak hromszgek, ngyzetek s krk. Programunk a tbbalaksg segtsgvel kpes lehet ltalban az alakzatokkal dolgozni. Mivel hromszgek, ngyzetek s krk alakzatok, programunk kpes mindegyikk hasznlathoz alkalmazkodni. Az itt hasznlt programozsi mdszerek bonyolultabbak a szoksosnl, de hasznlatuk hihetetlen lehetsgeket adhat.
rkls
Az rkls az objektumkzpont programozs legsszetettebb fogalma. Krkkel mr dolgoztunk mi legyen, ha gmbkkel kell foglalkoznunk? Nos, a gmb bizonyos rtelemben a kr tovbbfejlesztse, hiszen rendelkezik a kr jellemzivel, csak eggyel tbb dimenzija van. Azt is mondhatnnk, hogy a gmb egy klnleges krflesg, egy jabb dimenzival kiegsztve. Ha teht a kr segtsgvel ksztjk el a gmbnket, a gmb rklheti a kr tulajdonsgait. Az itt lertakat nevezzk ltalnossgban rklsnek.
jrahasznosthatsg
Az objektumkzpont programozs hasznlatnak egyik legfontosabb clja az jrahasznosthatsg biztostsa. Ha ksztnk egy osztlyt, jrafelhasznlva ltrehozhatunk belle tbb objektumot is. Az rkls s ms korbban bemutatott lehetsgek hasznlatval eljrsokat kszthetnk, melyeket ksbb ms programokban, klnflekppen hasznlhatunk fel. Az egyes szolgltatsok egysgbe zrsval olyan eljrsokat hozhatunk ltre, melyek helyessgt j elre ellenrizhetjk, gy a ksbbiekben nem kell trdnnk a Ksztette: Zstr Csaba III. ves informatikus hallgat 12
C# Amit a C# tudni rdemes! mkds rszleteivel csak a helyes hasznlatra kell gyelni. gy ezen eljrsok jrafelhasznlsa egyszer s gyors lesz.
Objektumok s osztlyok
Az osztly valjban egy ksbb ksztend elem meghatrozsa, szban forg elem pedig az objektum. Gyakran hasznlt prhuzam a stemnyforma. Ez a forma meghatrozza a sti alakjt, de nmaga nem stemny mg csak nem is ehet. A stemnyforma csak egy eszkz, mellyel stemnyeket kszthetnk. Hasznlatnl biztosak lehetnk abban, hogy a stik egyformk lesznek, s abban hogy nem fog elkopni akrmennyi stemnyt is ksztsnk. A stemnyformhoz hasonlan az osztlybl is tbb objektumot kszthetnk. gy, ha van pldul egy kr osztlyunk, ezzel szmos krt ltrehozhatunk. Amennyiben egy rajzprogramot ksztnk, elg, ha csak egyetlen kr osztllyal rendelkeznk a kr objektumok sokasga ennek segtsgvel ltrehozhat.
A C# modulris
A modulris azt jelenti, hogy a C# kdot, osztlyoknak nevezett kdrszletekbl kell sszelltanunk, melyek eljrsokat, gynevezett tagfggvnyeket (metdusokat) tartalmaznak. Ezeket az osztlyokat s tagfggvnyeket tbb helytt is felhasznlhatjuk, gy elkerlhetjk a felesleges, tbbszri kdolst. Egy msik, a C#-hoz kapcsold kifejezs a komponens. A C# segtsgvel ugyanis kszthetnk komponenseket (jrahasznosthat programelemeket) is, melyek ms alkalmazsokba gyazhat programok. A komponensek melyek nem felttlenl C# kdbl llnak sszetett programok ptelemeiknt szerepelhetnek.
.NET madrtvlatbl
A C# nyelv tervezsekor a .NET krnyezettel val egyttmkdst tartottk szem eltt. Ez a krnyezet tbb rszbl ll, kztk egy futsidej krnyezetbl, nhny elre meghatrozott eljrsbl, valamint az adatok trolsnak meghatrozott mdjaibl. A C# programok kpesek kihasznlni mindezek elnyeit. A futsidej krnyezetrl (CLR) mr volt sz a korbbiakban rviden rla csak annyit, hogy feladata a lefordtott C# program s az adott opercis rendszer sszektse. Az adatok szabvnyostott trolsrt a Common Type System (CTS), kzs tpusrendszer felel. Ez valjban trolsi tpusok egy csaldja, melyeket brmely hasznlhat. Pontosabban szlva, mindent, a .NET krnyezettel egyttmkd programnyelv ezeket a kzs tpusokat hasznlja. A kzs tpusok alkalmazsa lehetv teszi, hogy klnbz programok megosszk adataikat.
13
C# Amit a C# tudni rdemes! A .NET krnyezet msik lnyeges eleme az elre meghatrozott eljrsok csaldja. Ezeket a .NET alaposztly-knyvtr (BCL) rszeiknt rhetjk el. Itt eljrsok ezrei segtenek C# programozsi feladataink megvalstsban gy tettek Hello, World! programunkban is, ahol agy ilyen eljrs vgezte a kiratst a konzolablakra, de az ablakok s vezrlk ksztsnl is ezek kapnak szerepet. Tovbbi eljrsok llnak rendelkezsre a fjlkezels feladataihoz, az XML kezelshez, a tbbfeladatossghoz s ms egyb feladatokhoz. A CTS, a BCL eljrsai, valamint a .NET krnyezet ms elemei ugyangy elrhetk ms .NET programozsi nyelvekben, mint a C#-ban. gy pldul a BCL eljrsai ugyanazok, mint a Microsoft VisualBasic.NET, a Microsoft J#.NET, vagy a JScript.NET ltal hasznltak.
A C# programok
A C# alkalmazsok felptse
3.1. kdszveg App.cs
// App.cs Bemutat C# alkalmazs // Nem baj, ha mg nem rtnk mindent, // ksbb vlaszt kapunk krdseinkre //----------------------------------------------using System; class App { public static void Main() { int radius = 4; const double PI = 3.14159; double area; area = PI * radius * radius; Console.WriteLine("Radius = {0}, PI = {1}", radius, PI ); Console.WriteLine("The area is {0}", area); } }
Kimenet: Radius = 4, PI = 3.14159 The area is 50.26544 Ismerkedjnk meg a 3.1.-es kdszveg rszleteivel:
14
A megjegyzsekrl
A 3.1. kdszveg els ngy sora megjegyzs, vagyis olyan tjkoztat szveg, melyet a fordt figyelmen kvl hagy. Haszna a megjegyzsnek, hogy ezltal dokumentlni tudjuk a programunkat, ezltal knnyebb lesz majd a ksbbi fejleszts, hibajavts, s bvts, illetve msok szmra megjegyzseket tehetnk, hogy eligazodjanak a programunkban. A C#-ban hromfle megjegyzs van: Egysoros megjegyzs Ilyeneket tallunk a 3.1. kdszveg 1-4., valamint 12., 18. s 22. sorban. Alakjuk a kvetkez: // megjegyzs A kt perjel adja a megjegyzs kezdett innen a sor vgig a fordt mindent megjegyzsknt kezel. Az egysoros megjegyzseknek nem kell a sor elejn kezddnik, st llhat elttk C# kd is. A kt perjel utn azonban minden megjegyzsnek szmt. Tbbsoros megjegyzs A fenti pldban nem tallhat ilyen, de hasznlatra szksg lehet, ha azt szeretnnk, hogy egy megjegyzs tbb sorra terjedjen ki. Ilyenkor persze megtehetjk, hogy minden sor elejre kitesszk a kt perjelet, de hasznlhatunk valdi tbbsoros megjegyzseket is. A tbbsoros megjegyzseknek egy nyit s egy zr jelz hatrolja. Megjegyzs kezdetn egy perjelet, majd egy csillagot kell bernunk: /* Minden, amit ezutn kvetkezik, a megjegyzshez tartozik, egszen a vg jelzjig ez pedig egy csillag s egy perjel egymsutnja: */ Megjegyzs pldul a kvetkez: /* Ez egy megjegyzs */ vagy /* Ez szintn egy megjegyzs csak tbb sorban */ A tbbsoros megjegyzsek nem gyazhatk egymsba. Ez azt jelenti, hogy egy tbbsoros megjegyzs nem helyezhet el egy msik belsejben. Dokumentcis megjegyzs A C# rendelkezik egy klnleges megjegyzstpussal, ami lehetv teszi az automatikus kls dokumentlst. Ksztette: Zstr Csaba III. ves informatikus hallgat 15
C# Amit a C# tudni rdemes! Ezeket a megjegyzseket hrom perjellel vezeti be, s bennk hasznlhatjuk az XML stlus kdokat. Az XML egy adatok jellsre szolgl szabvny. Jllehet brmely XML kdot hasznlhatjuk, a C#-ban jellemzen a kvetkezk fordulnak el: <c>,<code>,<example>,<exception>,<list>,<para>,<param>,< paramref>,<permission>,<remarks>,<returns>,<see>,<seeals o>,<summary> s <value>. Ezeket megjegyzseket a 3.2 kdszveghez hasonlan helyezhetjk el kdunkban: 3.2 kdszveg Az XML megjegyzsek hasznlata Xmlapp.cs__________________________
// Xmlapp.cs Bemutat C# alkalmazs // XML dokumentcival //----------------------------------------------/// <summary> /// sszefoglal lers az osztlyrl.</summary> /// <remarks> /// Ez egy hosszabb megjegyzs melyben /// rszletesebben lerhatjuk az osztlyt. </remarks> class Xmlapp { /// <summary> /// Az alkalmazs kezdpontja. /// </summary> /// <param name="args"> paracssori paramterek felsorolsa</param> public static void Main(string[] args) { System.Console.WriteLine("An XML Documented Program"); } } ____________________________________________________________________
Ha lefordtjuk s futtatjuk ezt a kdot, az albbi eredmnyt kapjuk: An XML Documented Program Ha hozz akarunk jutni az XML dokumentcihoz, a fordtst a korbbiaktl eltren kell elvgezni. A korbbi parancssorban el kell helyezni a /doc kapcsolt. Teht a kvetkezt kell begpelni: csc /doc:xmlfile Xmlapp.cs A fordts utn az elzvel megegyez kimenetet kapunk, de emellett hozzjutunk egy xmlfile nev fjlhoz, amely XML dokumentcit tartalmaz. A 3.2 kdszveg esetn a kapott file tartalma a kvetkez:
<?xml version="1.0"?> <doc> <assembly> <name>Xmlapp</name> </assembly> <members> <member name="T:Xmlapp"> <summary>
16
A C# alkalmazsok alapelemei
A programnyelvek alapja egy csokrnyi kulcssz, melyek klnleges jelentssel brnak. A szmtgpprogramok e kulcsszavak rendezett halmazbl llnak, kiegsztve nhny tovbbi szval s jellel. A C# nyelv kulcsfontossg rszei a kvetkezk: Trkzk C# kulcsszavak Literlok Azonostk
Formzs trkzkkel
A 3.1 kdszveget gy formztuk, hogy a kd sorai igazodjanak egymshoz, megknnytve az olvasst. A formzshoz beillesztett res helyeket hvjuk trkzknek. Ezek lehetnek szkzk, tabultorok, jsor karakterek s kocsivisszk. A fordt szinte minden esetben figyelmen kvl hagyja a trkzket, gy akrmennyi szkzt, tabultort, vagy jsor karaktert beilleszthetnk a kdba. Nzzk pldul a 3.1 kdszveg 14. sort: int radius = 4; Ez egy jl formzott sor az elemek kztt egy-egy szkzzel. Ezeket a szkzket azonban tovbbiakkal is megtoldhatjuk: int Radius = 4 ;
17
C# Amit a C# tudni rdemes! Nos ez nem valami olvashat, de mkdik. A trkzket egyetlen esetben kell figyelembe vennnk az idzjelek kztt ll szvegekben. Ilyenkor ugyanis pontosan az jelenik meg a kpernyn, amit bertunk.
Vannak ezen kvl a C# programokban nhny sz get, set s a value -, melyek nem kulcsszavak, csak foglaltak. Kezeljk ket kulcsszavakknt. A C# jvbeni vltozataiban vrhat, hogy a partial, a yield s a where is kulcsszavakk vlnak. Mivel mindegyiknek jelentse van a nyelv szempontjbl, termszetesen foglaltak, vagyis nem hasznlhatjuk ket sajt cljainkra.
Literlok
A literlok egyszer, rgztett rtkek. Jelentsk pontosan az, amit lerva ltunk bellk. gy a 4 s a 3.14159 egyarnt literlok, de literl az idzjelek kztt elhelyezett szveg is.
Azonostk
A C# kulcsszavai s a literlok mellett vannak ms szavak is, melyeket hasznlhatunk C# programjainkban. E szavakat a fordt azonostknak tekinti. A 3.1. kdszveg szmos ilyet tartalmaz. Plda erre a 6. sorban a System, a 8. sorban a sample, a 14. sorban a radius, a 15. sorban a PI, a 16. sorban az area.
18
A C# alkalmazsok szerkezete
A szavakbl s kifejezsekbl mondatokat lltunk ssze, a mondatokbl pedig bekezdseket szerkesztnk. A trkzk, kulcsszavak, literlok s azonostk ugyangy az utastsok s kifejezsek alapjul szolglnak. Ezekbl pedig sszell maga a program.
Az res utasts
Van egy utasts, amelyet kln kell emltennk: ez az res utasts. Amint korbbam mondtuk, az utastsok pontosvesszvel vgzdnek megtehetjk azonban azt is, hogy egy sorba egyetlen, nmagban ll pontosvesszt tesznk. A kapott utasts nem csinl semmit hiszen nincs benne semmilyen vgrehajthat kifejezs.
Adattrols vltozkkal
A vltozk voltakppen szmtgpnk memrijnak nvvel elltott rszei, gy ha programunk egy vltozra hivatkozik, voltakppen e trterlet tartalmt hasznljuk fel. Ha vltozkat akarunk hasznlni, tudnunk kell, miknt nevezzk el ket. A nvadskor az albbi szablyokat kell figyelembe venni: A nv betket, szmjegyeket s alhzs karaktereket ( _ ) tartalmazhat. A vltoznv els karaktere csak bet vagy alhzs karakter lehet, br az utbbi nem ajnlott, mivel gyakran hasznljk klnleges utastsoknl, s az olvashatsgot is rontja. A kis- s nagybetk klnbznek szmtanak, vagyis a Szamlalo s a szamlalo kt klnbz vltozt jell. A C# kulcsszavai nem hasznlhatk vltoznvknt, hiszen a C# nyelv rszei Nhny helyes s helytelen plda vltoznevekre: Vltoznv Szazalek y2x5_w7h3 eves_koltseg _2010_ado szamlalo#ell Helyessge helyes helyes helyes helyes, de nem ajnlott helytelen a # nem hasznlhat karakter 19
C# Amit a C# tudni rdemes! double 9byte helytelen, hiszen C# kulcssz helytelen, ugyanis az els karakter szmjegy
A vltozk hasznlata
Mieltt egy vltozt hasznlatba vehetnnk, be kell vezetnnk. Ezzel elruljuk a fordtnak a vltoz nevt, valamint az ltala trolt adatok tpust. Ha olyan vltozt prblunk meg programunkban hasznlni, amit eltte nem vezettnk be, fordtsi hibt kapunk. A vltoz bevezetsvel a rendszer memrit foglal le szmra, a trolt adatok tpusnak azonostsa pedig lehetv teszi, hogy a rendszer a lehet legjobb teljestmnyt rje el, s ne pocskolja a memrit. A vltozkat a kvetkez alakban vezetjk be: tpusnv vltoznv; A tpusnv az alkalmazott adattpus nevt adja meg, a vltoznv jelentse pedig az ltalunk adott nevet jelenti, amivel hivatkozunk a vltozra. Pldul: int my_number; Tbb azonos tpus vltozt egy sorban is bevezethetnk, csak soroljuk fel ket a tpusnv utn vesszvel elvlasztva. Ezzel tmrebb tehetjk a kdot: int count, number, start;
rtkads a vltozknak
A vltozk bevezetse utn vgre kvetkezhet a lnyeg: az rtkek trolsa. rtkads alakja a kvetkez: vltoznv = rtk; A vltoznv az ltalunk ltrehozott vltoz neve, az rtk pedig a benne trolni kvnt rtk. Ha pldul az 5-t szeretnnk trolni egy tarolt_szam nev vltozban a kvetkezt kell bernunk: int tarolt_szam = 5; Termszetesen az rtkads trtnhetett volna kt sorban is: int tarolt_szam; tarolt_szam = 5; A vltozk rtkt termszetesen meg is vltoztathatjuk csak rendeljnk hozz j rtket. Ksztette: Zstr Csaba III. ves informatikus hallgat 20
A C# adattpusai
Korbban lttuk, hogy egy vltoz bevezetsekor egyttal a tpust is meg kell adnunk. A C#ban a kvetkez tpus vltozkat vezethetjk be:
Sbyte Byte Short Ushort Int Uint Long
8 bit eljeles 8 bit eljel nlkli 16 bit eljeles 16 bit eljel nlkli 32 bit eljeles 32 bit eljel nlkli 64 bit eljeles 64 bit eljel nlkli
-128 127 0 255 -32768 32767 0 65535 -2147483648 2147483647 0 4294967295 - 92233720368547758 92233720368547758 07 08 0 18446744073709551 615
Ulong
Lthatjuk, hogy a klnbz tpusoknak, klnbz memria igny van, illetve a rajtuk vgezhet matematikai mveletek vgrehajtsa is klnbz nehzsg lehet. A megfelel vltoztpust hasznlva biztosthatjuk, hogy programunk a lehet leghatkonyabban mkdjn. A kvetkezkben a szmszer adatokat ngy kategrira osztjuk: Egszek Lebegpontos szmok Tizedestrtek Logikai rtkek
21
Lebegpontos rtkek
Nem minden szm egsz, gy ha olyan szmokat szeretnnk trolni, melyekben tizedesjegyek szerepelnek, akkor itt is vlaszthatjuk a szm nagysgtl fgg tpust. Ezek a tpusok a kvetkezk:
Float 7 1.5x10-45 Double 15 5x10-324
3.4x1038 1.7x10308
C#-ban ltezik egy tovbbi adattpus, melyben tizedes szmokat trolhatunk ez a decimal, melynek feladata a nagyobb pontossg biztostsa. Ha float vagy double rtkben troljuk a szmrtkeket, kerektsi hibkat kapunk, gy pldul, ha 10,00-bl kivonunk -,90et double vltozkat hasznlva az eredmny 0,99999999999999645 lehet a vrt 0,10 helyett. Ha a mveletet decimal rtkekkel vgezzk el, a kapott szm valban 0,10 lesz. A decimal tpus 16 bjton trolja a szmokat. rdekessge, hogy nem rendelkezik eljel nlkli alakkal, trolsi korltai pedig nagyjbl 1,0 x 10-28 s 7,9 x 10-28, emellett pontossga 28 jegyig terjed. A vltoz trolsra hasznlt memriamennyisg a tpustl fgg. A szmszer adatok mellett vannak a karakterek, melynek tpusa char. char karakter = a;
Logikai rtkek
Logikai vagy Boole-rtkek. Sokszor tudnunk kell valamirl, hogy igaz-e vagy hamis a logikai rtkekkel ezt a tudst trolhatjuk a 0 vagy az 1 rtk formjban. A C# logikai adattpusnak neve bool, mely a memribl egy bjtot hast ki. rtke true (igaz) vagy false (hamis) lehet, ezek egyttal C# kulcsszavak is.
C# Amit a C# tudni rdemes! ushort int uint long ulong char float double bool decimal System.UInt16 System.Int32 System.UInt32 System.Int64 System.UInt64 System.Char System.Single System.Double System.Boolean System.Decimal
Ha egy egsz tpus vltozt .NET megfelelsvel szeretnnk bevezetni jllehet semmi okunk r -, a kvetkezkppen tehetjk meg: System.Int32 szam = 5; Megjegyzs: A CTS olyan szablyok csoportja, melyeknek a CLR adattpusai meg kell feleljenek. A C# egyszer adattpusai s a .NET tpusok kielgtik ezt a kvetelmnyt. Ha egy programnyelv kveti a CTS szablyait adattpusai elksztsben, a bennk trolt adatok sszeegyeztethetk lesznek ms, a CTS szablyainak megfelel nyelvekkel.
Egsz literlok
Ha egsz rtket hasznlunk, ez nagysg szerint int, uint, long vagy ulong tpusok valamelyikbe kerl, attl fggen, hogy melyik adattpusba fr bele. Ksztette: Zstr Csaba III. ves informatikus hallgat 23
C# Amit a C# tudni rdemes! Ha magunk szeretnnk megadni a literl adattpust, megtehetjk csak biggyessznk hozz egy uttagot. Ha pldul a 10-et long tpusknt szeretnnk hasznlni, a kvetkezt rhatjuk: 10L. Az eljelnlklisget egy u uttag jelzi, ami a tpusra ural uttaggal kombinlhat.
Lebegpontos literlok
Amint a korbbiakban emltettk, a tizedespontot tartalmaz literlok alaprtelmezs szerint double tpusak ha float tpusakk szeretnnk tenni valamelyiket, csak rjuk utna az f vagy az F bett: my_float = 4.4f; Ha decimal tpust szeretnnk hasznlni, a megfelel uttag az m, illetve az M. Ezt az albbiak szerint hasznlhatjuk: my_decimal = 1.32m;
Logikai literlok
A logikai (Boole) literlokrl mr ejtettnk szt a korbbiakban csak kt ilyen ltezik a true s a false, melyek egyttal kulcsszavak is a C#-ban.
Karakterlnc literlok
A karakterek csoportjaibl szavakat, kifejezseket, majd mondatokat llthatunk ssze. A karakterek csoportjait karakterlncoknak nevezzk, megadsuk idzjelek kztt trtnhet.. Pldnak okrt a Console.WriteLine eljrs karakterlncokat fogad. A karakterlnc literl brmilyen, idzjelek kz helyezett karaktercsoport lehet: Hell vilg! 123456789
llandk ltrehozsa
A literlok mellet sokszor szksg van olyan vltozkra is, melyek rtkt befagyasztjuk. gy ha pldul bevezetnk egy PI nev vltozt, s elhelyezzk benne a 3.14159 rtket, kvnhatjuk tle, hogy ettl kezdve ne vltozzon, hiszen semmi nem indokolja a mdostst st, ez krt is okozna a programunk mkdsben. Ha azt szeretnnk, hogy vltoznk rtke lland (konstans) maradjon, vezessk be a const kulcsszval.: const float PI = 3.14159;
24
Hivatkozsi tpusok
A C# az adatok trolsnak alapveten ktfle mdjt ismeri: az rtk s a hivatkozs szerinti trolst. Az eddigiekben megismert alapvet adattpusok rtk szerinti trolsak. Ha egy vltoz rtk szerint trolja az adatokat, akkor valban kzvetlenl az adatokat tartalmazza. A hivatkozs szerinti trols ennl bonyolultabb ilyenkor ugyanis nem kzvetlenl az adatokat, hanem azok cmt troljuk a vltozban, vagyis egy hivatkozst rjuk. A C#-ban a kvetkez adattpusok hasznlnak hivatkozs szerinti trolst: Osztlyok Karakterlncok Felletek Tmbk Kpviselk
Mveletek a C#-ban
Alapvet adatok megjelentse
Kt szban forg eljrst kell megismernnk, melyet mr eddig is hasznlunk a pldk sorn, melyekkel brmit a kpernyre rhattunk. Ez a kt eljrs a kvetkez: System.Console.WriteLine() System.Console.Write()
Mindkett adatokat r a kpernyre, egy apr klnbsggel. A WriteLine() az adatok kirsa utn j sort kezd, mg a Write() nem. Hasznlata: System.Console.WriteLine(Hell vilg!!); Az idzjelek kz helyezett szvegek kirsa mellett msfajta rtkeket is megjelenthetnk. int nbr = 456; System.Console.WriteLine(me egy szm: {0},nbr); Ez eredmny a kvetkez lesz a kpernyn: me egy szm: 456 Lthatjuk, hogy a {0} helyt az idzjelbe tett szveget kvet rtk vette t. De nem csak egy rtk helyettesthet be egyms utn sorszmokkal behelyettesthetjk a tovbbi megadott rtkeket is: System.Console.WriteLine(Az 1.rtk {0}, a 2.pedig {1},123, Csaba);
25
C# Amit a C# tudni rdemes! A kpernyn a kvetkez jelenik meg: Az 1.rtk 123, a 2.pedig Csaba A szmozs mindig nullval kezddik!
Emellett meg kell ismerkednnk a mveleti jelek hasznlatval is eszerint hromfle mvelet ismeretes a C# nyelvben: Egyvltozs mvelet (unris mvelet) Ktvltozs mvelet (binris mvelet) Hromvltozs mvelet (ternris mvelet)
Egyvltozs mveletek
Az egyvltozs mveletek a nevkbl kvetkezen egyetlen vltozra hatnak. ltalnos alakja: [mveleti jel] [vltoz] vagy [vltoz][mveleti jel] Plda: -x;
Ktvltozs mveletek
Nem meglep mdon a ktvltozs mveletek mkdshez kt vltozra van szksg ilyen pldul az sszeads mvelete. Hasznlatul ltalnos alakja a kvetkez: [vltoz1][mveleti jel][vltoz2] Plda:
26
Hromvltozs mveletek
Az ide tartoz mveletek a hrom kategria kzl a legsszetettebbek. A C# egyetlen egy ilyet tartalmaz a feltteles mvelet. Alakja a kvetkez: Felttel ? utasts_ha_igaz : utasts_ha_hamis;
Ezek az sszetett mveletek lehetv teszik, hogy egyszerre vgezznk el egy aritmetikai mvelet s egy rtkadst.
27
Meg kell jegyezni, hogy a ++x nem ugyanaz, mint a x++. Ugyanis a ++x-nl elzetes , mg az x++-nl utlagos nvelst vgeztnk. Ez azt jelenti, hogy az els esetben megnveljk az x rtkt eggyel s gy vehetjk hasznlatba, mg a msodiknl elbb hasznlatba veszzk, majd utna nveljk meg eggyel az rtket. Termszetesen ez vonatkozik a cskkent mveletre is. (--)
Viszonyt mveletek Mveleti jel > < == != >= <= Jelents Nagyobb, mint Kisebb, mint Egyenl Nem egyenl Nagyobb vagy egyenl Kisebb vagy egyenl
Amikor sszehasonltst vgznk relcis opertorokkal, ktfle eredmnyt kaphatunk: igazat (true) vagy hamisat (false). Pldul: 5 < 10 5 > 10 5 = = 10 5 != 10 5 kisebb, mint a 10, teht igaz 5 nem nagyobb, mint a 10, teht hamis 5 nem egyenl 10, teht hamis 5 nem egyenl 10, teht igaz
Az if utasts
A viszonyt mveletek valdi rtke az, hogy segtsgkkel dntseket hozhatunk, melyek befolysolhatjk a program futsnak menett. Mindebben az if kulcssz siet segtsgnkre. Az if kulcsszval kt rtket hasonltunk ssze; hasznlati alakja a kvetkez: if (val1 [mveleti jel] val2) utasts(ok); Ha a val1 s a val2 kzti sszehasonlts eredmnye true, a program vgrehajtja a megadott utasts, ellenkez esetben tugorja azt. Ksztette: Zstr Csaba III. ves informatikus hallgat 28
C# Amit a C# tudni rdemes! Megeshet, hogy egyszerre tbb felttel teljeslst kell ellenriznnk. Erre a feladatra szolgl az AND (&&) s az OR (||). Nzznk erre egy egyszer pldt: if(sex = = female && age >=21) { //Az adott szemly legalbb 21 ves s n(female). } vagy if(sex = = female || age >=21) { //Az adott szemly n, vagy legalbb 21 ves }
____________________________________________________________________________
29
C# Amit a C# tudni rdemes! A kirtkelsi sorrendet megvltoztathatjuk a zrjelek segtsgvel ( ). Mivel a zrjelek magasabb szinten vannak, mint a mveletek, bennk tallhat kifejezsek kirtkelse elbb trtnik meg, mint a rajtuk kvl lvk.
Adattpusok talaktsa
Ha ttrnk egy adattpusrl egy msikra, t kell alaktani az adatainkat, st, erre az talaktsra akkor is szksg lehet, ha egy mveletben kt klnbz tpus adat is rszt vesz. Az talaktsnak kt tpusa ismeretes: az automatikus (rejtett, belertett, implicit) s a knyszertett (kifejezett, meghatrozott, explicit) talakts. Az automatikus talaktsok nmkden, hiba nlkl vgbemennek. A knyszertett talaktsok esetben az talaktst a programoz knyszerti ki. Ennek alakja a kvetkez: ClVltoz (adattpus) KiindulsiVltoz; Plda erre: int intszam = 0; long longszam = 1234; intszam = (int)longszam; A tpusknyszerts hasznlatnl a programoz felelssge annak ellenrzse, hogy a vltoz valban kpes befogadni az talaktott rtket. Ha nem kpes, az adatok csonkolst, vagy ms mdostst szenvednek. Knyszertett talaktsra szmos esetben lehet szksgnk: Ahol knyszertett talaktsra van szksg Kiindulsi tpus sbyte byte short ushort int uint long ulong char float double decimal Cltpus byte, ushort, uint, ulong, char sbyte, char sbyte, byte, ushort, uint, ulong, char sbyte, byte, short, char sbyte, byte, short, ushort, uint, ulong, char sbyte, byte, short, ushort, int, char sbyte, byte, short, ushort, int, uint, ulong, char sbyte, byte, short, ushort, int, uint, long, char sbyte, byte, short sbyte, byte, short, ushort, int, uint, long, ulong, char, decimal sbyte, byte, short, ushort, int, uint, long, ulong, char, float, decimal sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double
30
Tpuslptets
Az automatikus talaktsok szerepet kapnak a mveletek mkdse sorn is hasznlatukra a tpuslptetsnl (operator promotion) kerl sor. Erre akkor van szksg, amikor kt vltozn valamilyen matematikai alapmveletet vgznk, s tpusuk nem azonos. Pldul, ha egy byte tpus vltozt egy int tpushoz szeretnnk adni, a program elbb int tpusv alaktja. Minden int-nl kisebb szmvltoz int tpusv vlik, az int-nl bvebb tpusok pedig az albbi sorrendet veszik t egyms szerept: int uint long ulong float double decimal
Kivlaszt utastsok
A kivlaszt utastsok lehetv teszik, hogy egy felttel eredmnytl fggen vlasszunk bizonyos kdrszletek vgrehajtsa kztt. Ide tartozik a korbban mr megismert if, de a ksbbiekben trgyalt switch is ilyen utasts.
Ismt az if
Eleventsk fel, hogy hogyan is mkdik az if utasts: if(gender == m || gender == f) { System.Console.WriteLine(The gender is valid); } if(gender != m && gender != f) { System.Console.WriteLine(The gender value, {0} valid,gender); Ksztette: Zstr Csaba III. ves informatikus hallgat 31
is
not
C# Amit a C# tudni rdemes! } Ezen kd hatkonysgnak nvelse rdekben a C# hasznlatba veszi az if-else utasts szerkezet, melynek hasznlata a kvetkez: if(felttel) { //utasits(ok); } else { //ha az if felttele hamis a program vgrehajtja az itt ll kdot } Lthat, hogy az else lehetsget ad arra, hogy megadjuk egy kdrszletet, melyet a program akkor hajt vgre, ha az if felttele nem teljesl, vagyis hamis eredmnyt szolgltat.
Az if utastsok begyazsa
A begyazs egyszeren azt jelenti, hogy egy utastst egy msikon bell helyeznk el. A C#ban szinte minden vezrl utasts begyazhat trsaiba. Ha if utastst szeretnnk egy msikba gyazni, egyszeren helyezzk el a msik kdblokkjban. Pldul: if(gender == m) { //frfirl van sz } else { if(gender == m) { //nrl van sz } else { //se nem n, se nem frfi } } A begyazs sokszor leegyszersti a programozst, de lehetsgnk van arra is, hogy az if utastsokat felhalmozzuk.
32
Az if utastsok felhalmozsa
Az if utastsok halmozsnl az else utastst jabb if-fel egyestjk. Nzznk erre egy pldt: 3.3 Az if-else utastsok felhalmozsa
class Stacked { static void Main() { char gender = 'x'; if( gender == 'm' ) { System.Console.WriteLine("The gender is male"); } else if ( gender == 'f' ) { System.Console.WriteLine("The gender is female"); } else { System.Console.WriteLine("The gender value, {0}, is not valid", gender); } System.Console.WriteLine("The if statement is now over!"); } } ___________________________________________________________________________________________
A switch utasts
A C# lehetsget ad arra is, hogy egy vltoz rtke alapjn dntseket hozzunk rendelkezsnkre bocstja a switch utastst. Hasznlatnak alakja a kvetkez: switch(rtk) { case eredmny_1: //az eredmny_1-hez tartoz kd break; case eredmny_2: //az eredmny_2-hez tartoz kd break; ... case eredmny_n: //az eredmny_n-hez tartoz kd break; default: //az alaprtelmezsben vgrehajtott kd break; }
33
C# Amit a C# tudni rdemes! Lthatjuk, hogy ebben az utastsban nincsenek felttelek egy rtk szerepel helyettk. Ez az rtk lehet egy kifejezs eredmnye, vagy akr egy vltoz is. Ezt hasonltja ssze a program a case utastsoknl megadott rtkekkel, mg egyezst nem tall. Ha nincs egyezs, vgrehajtja a default utastsban megadott kdot vagy ha ilyen nincs, tovbblp a switch utni els kdsorra. Ha a program, egyezst tallt, vgrehajtja az ott megadott kdot, ha pedig egy jabb case utastshoz r, a switch utastsnak vge szakad. gy legfeljebb egy case tartalma hajthat vgre, ezutn a vezrls a switch utni els utastshoz kerl. Nzznk erre is egy pldt: 3.4 Kockadobs a switch utastssal
class roll { public static void Main() { int roll = 0; // A kvetkez kt sorban a dobas (roll) rtkt egy 1 s 6 kzti //vletlen szmmal azonostjuk System.Random rnd = new System.Random(); roll = (int) rnd.Next(1,7); System.Console.WriteLine("Starting the switch... "); switch (roll) { case 1: System.Console.WriteLine("Roll is 1"); break; case 2: case 3: case 4: case 5: case 6: default: System.Console.WriteLine("Roll is 2"); break; System.Console.WriteLine("Roll is 3"); break; System.Console.WriteLine("Roll is 4"); break; System.Console.WriteLine("Roll is 5"); break; System.Console.WriteLine("Roll is 6"); break; System.Console.WriteLine("Roll is not 1 through 6"); break; } System.Console.WriteLine("The switch statement is now over!"); } }
34
dobs
nincs
35
Bejr utastsok
A kivlaszt utastsok mellett a program menetr gy is mdosthatjuk, ha egyes rszleteket megismtlnk. E clra a C# szmos bejr utastst bocst rendelkezsnkre, amelyek egy adott kdrszletet tbbszr kpesek vgrehajtani. Ezt nevezzk bejrknak (iterci). A C# bejr utastsai a kvetkezk: while do for foreach
A while utasts
A while segtsgvel egy kdrszletet mindaddig ismtelhetnk, mg egy megadott felttel igaz. Hasznlati alakja a kvetkez: while (felttel) { utasts(ok); }
36
} }
} System.Console.WriteLine("Done!");
A do utasts
Ha a while utasts felttele az els ellenrzskor hamis, az utastshoz tartoz kdblokk vgrehajtsra soha nem kerl sor. Gyakran szksg van azonban arra, hogy ezek az utastsok egyszer lefussanak ilyenkor segt a do utasts. A do hasznlatnak alakja a kvetkez: do { Ksztette: Zstr Csaba III. ves informatikus hallgat 37
C# Amit a C# tudni rdemes! utasts(ok); }while(felttel); A do elszr vgrehajtja a belsejben foglalt utastsokat, s ezutn vizsglja a while felttelt. Ez a while pontosan gy mkdik, mint az elzekben trgyaltaknl. Ha a felttel igaz, akkor a program jra vgrehajtja az utastsokat, ha pedig hamis, akkor a dowhile utni els utasts kapja meg a vezrlst.
A for utasts
Jllehet, a while s a dowhile utastsok gyakorlatilag mindenfle kdismtlst lehetv tesznek, nem k az egyedli szereplk ezen a sznpadon. Ez pedig nem, mint a for utasts. Hasznlati alakja a kvetkez: for (bellts; felttel; nvels | cskkents) { utasts(ok); } A bellts (inicializls) kdja a for utasts kezdetn lp mkdsbe. Csak ilyenkor mkdik, ksbb nem tr vissza r a program. A bellts utn a program kirtkeli a felttelt. Ha az rtk igaz, kvetkezhet az utastsok vgrehajtsa. Az utasts vagy kdblokk vgrehajtsa utn kvetkezik a nvels vagy a cskkents. A nv flrevezet, mert itt valjban brmilyen C# utasts llhat ltalban azonban egy szmll nvelse vagy cskkentse szerepel e helyen. A for utasts fejlcben tallhat hrom utasts bellts, felttel, nvels valjban tbbre kpes, mint els ltsra gondolnnk. Mindhrom terleten tetszleges kifejezsek elhelyezhetk, st, egy helyen akr tbb is. Ha tbb kifejezst szeretnnk hasznlni egy rszben, valahogyan el kell vlasztanunk azokat egymstl erre szolgl a vessz. for(x=1,y=2;x+Y<100;x++,y++) //utastsok vagy for(x=0;++x<=10;System.Console.WriteLine({0},x) );
A foreach utasts
A foreach utasts hasonl bejrst valst meg, mint a for, de klnleges clokra hasznlatos; kpes vgighaladni gyjtemnyeken, pldul tmbkn. A foreach hasznlata segthet leegyszersteni a tmbkkel vgzett munkt, klnsen akkor, ha egy teljes tmbn Ksztette: Zstr Csaba III. ves informatikus hallgat 38
C# Amit a C# tudni rdemes! vgig szeretnnk haladni. Radsul itt a tmbkre egyszeren tartalmuk alapjn hivatkozhatunk, nincs szksg szgletes zrjelekre s indexelsre. A foreach utasts htultje, hogy hasznlatval a tmbket csak olvashatjuk, elemeit mdostani nincs lehetsgnk. Az utasts forma a kvetkez: foreach(adattpus vltoznv in tmbnv) { Utastsok; } Nzznk erre egy rvid programrszletet: 3.6 A foreach hasznlata
using System; public class ForEach1 { public static void Main() { char[] name = new char[] {'B','r','a','d','l','e','y'}; Console.WriteLine("Display content of name array..."); foreach( char x in name ) { Console.Write("{0}", x); } Console.WriteLine("\n...Done."); } }
Az tkos goto
A goto utasts hasznlatt minden programnyelvben folyamatos vita ksri. Mivel felttel nlkl kpes megvltoztatni a program menett, igen nagy ert kpvisel ehhez azonban nagy felelssg is tartozik. Sok fejleszt egyltaln nem hasznlja ezt az utastst, mert gy vlik tlthatatlann teszi a kdot. A goto hromfle alakban hasznlhat a C#-ban. Kettt goto case s goto default a switch utastsnl mr megismerhettnk, mg a harmadik alakja a kvetkez: goto cmke; Ezzel az alakkal a vezrlst egy cmkeutastsnak adjuk t.
39
Utastsok cmkzse
A cmkeutasts egy olyan parancs, ami egyszeren megjell egy helyet a programban. Hasznlati alakja igen egyszer: cmke_neve: Nzznk erre egy pldt: 3.7 A goto hasznlata cmkkkel
class score { public static void Main() { int score = 0; int ctr = 0; System.Random rnd = new System.Random(); Start: ctr++; if (ctr > 10) goto EndThis; else score = (int) rnd.Next(60, 101); System.Console.WriteLine("{0} - You received a score of {1}", ctr, score); goto Start; EndThis: System.Console.WriteLine("Done with scores!"); } }
40
C# Amit a C# tudni rdemes! A .NET krnyezet rengeteg beptett osztllyal rendelkezik ezek egyikt mr a kezdetektl fogva hasznljuk: ez a Console. Ez az osztly szmos adattagot s eljrst tartalmaz utbbiak kzl tbben ismersek lehetnek, gy a Write s a WriteLine is. Az osztly neve a fenti smban azonost ez esetben a Console, trzse pedig tartalmazza a Write s a WriteLine kdjt.
Osztlyok bevezetse
Ha elksztnk egy osztlyt,a tovbbiakban hasznlhatjuk objektumok ltrehozsra. Az osztly valjban mindssze egy minta objektumok ksztsre nmagban nem kpes sem adatok trolsra, sem eljrsok vgrehajtsra. Ezeket a feladatokat az objektumok ltjk el. Az objektumok bevezetst (deklarcijt) pldnyostsnak is hvjk, magukat az objektumokat pedig az osztlyok pldnyainak nevezik. Az objektumok bevezetse a kvetkez alakban trtnik: osztly_neve objektumazonost = new osztly_neve(); Plda: Van egy Pont nev osztlyunk, s abbl akarunk kszteni egy objektumok, a kvetkezt kell tennnk: Pont kezd_pont = new Pont(); Az osztly neve Pont, mg az objektum neve kezd_pont Mivel a kezd_pont egy objektum, az osztly meghatrozsnak megfelelen tartalmazhat adatokat s eljrsokat. Ha a bevezets sort tzetesebben megvizsgljuk, feltnhet nhny rdekes elem. Ezek kzl a legfontosabb a new kulcssz. Amint neve is sugallja, segtsgvel j objektumokat hozhatunk ltre pldnk esetben egy j Pont objektumot. A new kulcssz jelentse mindig j pldny ltrehozsra utal. Ne feledjk, az osztly csak egyszer meghatrozs, nem trol semmit. Az objektumnak ugyanakkor szksge van helyre a trolshoz ezt a helyet foglalja le a new kulcssz. Az objektum bevezetsnl ez rtkads jobb oldaln az osztly neve mellett ki kell tennnk egy zrjelprt. Ez teszi lehetv, hogy az osztly szerkezete megjelenjen az objektumban.
Az osztly tagjai
Megnztk teht, hogy hogyan ksztsnk objektumokat az osztly felptse alapjn ideje, hogy megtanuljuk, mit is rejt az osztlyok szerkezete. Az osztly trzsben alapveten ktfle elemet tallunk: adattagokat s fggvnytagokat (tagfggvnyeket).
41
C# Amit a C# tudni rdemes! Az adattagok kztt vltozkat s llandkat lthatunk. Szerepelhet itt brmely a korbbiakban megismert egyszer vltoztpus, de szerepelhet itt sszetettebb adattpusok is. Az adattagok szrmazhatnak akr osztlyokbl is. Az osztlytrzs sszetevinek msik tpusba tartoznak a tagfggvnyek, melyek meghatrozott feladatok elvgzsre alkalmas eljrsok. E feladatok lehetnek egyszerek, mint rtk adsa egy vltoznak, de sszetettek is, mint pldul egy sornyi szveg kirsa elre meg nem hatrozott szm rtk alapjn ezt teszi a Write s a WriteLine. Ez utbbi fggvnyek a Console tagfggvnyei.
Az adattagok elrse
Miutn bevezettk az adattagokat, termszetesen szeretnnk azokat elrni. Amint a korbbiakban lthattuk, a public kulcssz lehetv teszi, hogy kvlrl elrhessk ket, de nem hivatkozhatunk egyszeren a nevkre. Hivatkoznunk az objektum nevnek s az adattag nevnek egyttes megadsval kell. Pldul a fenti pldbl kiindulva: Pont kezdpont = new Pont(); kezdpont.x s kezdpont.y 3.8 Osztlybevezets adattagokkal
class Point {
42
Az osztlyok adattagjai olyanok, mint a hagyomnyos vltozk. Hasznlhatjuk ket mveletekben, vezrl utastsokban, vagy brhol, ahol egy hagyomnyos vltozt elrhetnk. Meg kell emlteni, hogy az osztlyokat is egymsba gyazhatjuk, hiszen az osztly is csak adattpus. gy egy osztly tpusval ami voltakppen csak egy fejlettebb vltoztpus bevezetett objektumok ugyanott hasznlhatunk, ahol ms vltozkat. Pldul:
class Pont { public int x; public int y; } class Vonal { public Pont kezdo = new Pont(); public pont veg = new Pont(); public double hossz; }
Lehetsgnk van arra is, hogy a tpusokat ms osztlyokba gyazzuk be. gy, ha a Pont osztlyt csak a Vonal osztlyban hasznlnnk, meghatrozst is beletehetnnk ebbe az osztlyba. Ekkor a Pont tpus objektum a Vonal osztly szmra volnnak elrhetk. A begyazs kdja a kvetkezkppen fest:
class Vonal { public class Pont {
43
Van itt azonban mg egy kis aprcska vltozs: a Pont osztlyt nyilvnoss kell tennnk a public kulcsszval. Ha ezt nem tesszk meg, hibt kapunk. Persze, ha jobban belegondolunk, ez logikus is: hogyan lehetnnek a Pontobjektum rszei nyilvnosak, ha maga az osztly nem az.
44
Ha egy statikus adattagot egy objektum nevvel prblunk elrni, hibt kapunk. Ilyenkor az osztly nevt kell hasznlnunk az elrshez.
Line.origin.x = 1;
Mivel az origin objektumot statikusknt vezettk be, rtke kzs minden Line tpus objektumban. Ezrt a line1 s line2 sem birtokolhatja ezt az rtket, segtsgkkel nem is lehet belltani az osztly nevt kell hasznlnunk.
Az alkalmazs osztly
A szemflesebbek felfigyelhettek r, hogy azt az osztlyt, melyre minden alkalmazsunk pl, mg nem trgyaltuk. Az elz pldban ez a class StartLine volt. St, hasonl sort eddigi sszes programunkban tallhatunk. Ebbl is ltszik, hogy a C# objektumkzpont programnyelv minden eleme objektum, belertve magukat a programokat is. Ahhoz, hogy objektumot ksztsnk, szksgnk van egy osztlyra. Futtatskor a rendszer pldnyostja ezt az osztlyt az alkalmazs osztlyt -,s egy objektumot kszt ez lesz a programunk.
Tulajdonsgok ltrehozsa
A korbbiakban emltettk, hogy az objektumkzpont programok elnye, hogy szablyozzk az adatok bels megjelenst s elrst. Eddigi pldinkban azonban csak public vltozkat hasznltunk, melyeket brmely kdrszlet szabadon elrhetett. Ksztette: Zstr Csaba III. ves informatikus hallgat 45
C# Amit a C# tudni rdemes! Az objektumkzpont programokban ltalban ennl nagyobb mrtkben szeretnnk beavatkozni az adatok elrsbe. Ha ugyanis mindenkinek megengedjk, hogy kzvetlenl elrje az adattagokat, a ksbbiekben a tpusuk mdostsa nehzsgekbe tkzhet. E gondok thidalsra alkalmazza a C# a tulajdonsgokat, melyek az objektumkzpont programozsnak megfelel adattagokat nyjtanak. A tulajdonsgok a get s a set foglelt kifejezsek teszik lehetv rtkk kiolvasst s mdostst. Nzznk erre egy pldt:
class Point { int my_X; int my_Y;
public int x { get { return } set { my_X = } } public int y { get { return } set { my_Y = } }
my_X;
value;
my_Y;
value;
A nvterekrl
Ha mr megismerkedtnk az osztlyok alapvet jellemzivel, j tudnunk azt is, hogy szmos elre elksztett osztly (beptett osztly) ll rendelkezsnkre feladatok szles krnek elvgzsre. A .NET krnyezet alaposztlyai mellett a programozkat ms gyrtk is elhalmozzk hasznosabbnl hasznosabb osztlyokkal. Mr a korbbiakban is tallkoztunk alaposztlyokkal ilyen volt pldul a Console. Azt is megtanultuk, hogy a Console rendelkezik legalbb kt tagfggvnnyel ezek a Write s a WriteLine. A kvetkez sor pldul e jegyzet alkotjnak nevt rja a kpernyre: System.Console.WriteLine(Zstr Csaba);
46
C# Amit a C# tudni rdemes! Tudjuk, hogy a Zstr Csaba egy literl, a WriteLine pedig egy eljrs, ami a Console osztlyba tartozik. Azt is tudjuk, hogy a Console egy osztly objektuma. Nos, mindez nagyszer, de felmerl egy krds, hogy mi az a System? Mivel rengeteg klnbz osztly ltezik, fontos, hogy megfelel mdon rendszerbe szervezzk ket. Az osztlyokat nvterek szerint csoportosthatjuk, vagyis a nvterek osztlyok csoportjai. A Console osztly a System nvtrhez tartozik. A System.Console.WriteLine egy teljes nv, mellyel pontosan utalunk a megvalst kd helyre. Mindazonltal, hogy ne kelljen ennyit rnunk, a C# lehetv teszi, hogy rvidebben is hozzfrjnk az osztlyokhoz s eljrsaikhoz erre hasznlhatjuk a using kulcsszt. Ez a kulcssz lehetv teszi, hogy megjelljk a hasznlni kvnt nvteret. Ezutn a programunk tudni fogja, hol keresse a kvnt osztlyokat s eljrsokat, ha nvtr nlkl adjuk meg azokat. A using kulcssz hasznlatnak alakja a kvetkez: using nvtr_neve; A System nvtr esetben gy nz ki a fenti plda: Using System; Amennyiben azt a sort bertuk, a tovbbiakban nem lesz szksgnk System feltntetsre, he e nvteren belli osztlyokra vagy eljrsokra hivatkozunk.
Begyazott nvterek
Tbb nvteret is csoportba foglalhatunk, s ezt a csoportot egy jabb nvtrknt trolhatjuk. Ilyenkor a teljes nv kiegszl a tartalmaz nvtr nevvel, illetve ez a nv is megjelenik a using kulcssznl. A System nvtr is szmos ms nvteret tartalmaz, mint a Drawing, a Data s a Windows.Forms. Ha e nvterek osztlyait hasznljuk, meg kell adnunk a teljes nevket, vagy hasznlatba kell vennnk a megfelel nvteret a using utastssal. Ha a System-en belli Data nvteret szeretnnk programunkban hasznlatba venni a using utastssal, a kvetkezt kell a kd elejre rnunk: using System.Data;
47
C# Amit a C# tudni rdemes! Tagfggvny alatt egy nvvel elltott kdrszletet rtnk, melyet jrahasznosthat formban trolunk. A tagfggvnyek a program tbbi rsztl fggetlenl mkdnek, s amennyiben krltekinten jrunk el a nevk ltal jelzett feladatot hajtjk vgre. Fontos hangslyozni mg egyszer, hogy a tagfggvnyek valjban klnll nvvel elltott kdrszletek, melyeket a programbl meghvhatunk. A tagfggvny hvsakor a vezrls belp a tagfggvnybe, vgrehajtja az ott tallhat kdot, majd visszatr a hv eljrshoz.
A tagfggvny felptse
Fontos hogy tisztban legynk a tagfggvnyek szerkesztsvel. Ehhez a kvetkez minta ad pldt: Tagfggvny-fejlc { Tagfggvnytrzs } A fajlc a tagfggvnyek kulcsfontossg rsze, amint szmos alapvet jellemzt meghatroz: a programok elrsi lehetsgeit, a visszatrsi adattpust, a tagfggvnynek tadott rtkeket, a tagfggvny nevt. Pldul: public double terulet() A tagfggvny nyilvnos (public), vagyis az osztlyon kvli programokbl is elrhet. Lthatjuk azt is, hogy a tagfggvny visszatrsi rtknek tpusa double, neve pedig terulet. Vgl mivel a zrjel res, nem adunk t rtkeket a tagfggvnynek. Jelen esetben csak az osztly adattagjait hasznljuk.
48
A tagfggvnyek meghvsa
Ahhoz hogy egy tagfggvnyt hasznlatba vegynk, meg kell hvnunk. Ezt ugyangy tehetjk meg, mint az adattagokkal: rjuk be az objektum nevt, majd ezt kveten egy pontot s a tagfggvny nevt. A kt hvs kztt azonban klnbsg van, a tagfggvnyek esetben ugyanis ki kell rnunk egy zrjelprt, valamint kzjk az esetleges tadott paramtereket is. Vltozkhoz hasonlan, ha a tagfggvny rendelkezik visszatrsi tpussal, a kapott rtk a hvs helyre kerl. Nzznk most mindezekre egy pldt: 3.10 Osztly tagfggvnyekkel
class Circle { public int x; public int y; public double radius; public double getArea() // A getArea tagfggvny s a kdsor hozz { double theArea; theArea = 3.14159 * radius * radius; return theArea; } public double circumference() { double theCirc; theCirc = 2 * 3.14159 * radius; return theCirc; // A circumference tagfggvny s //kdsora
} }
class CircleApp { public static void Main() { Circle first = new Circle();
49
double area; double circ; first.x = 10; // Az x adattag elrse a first objektumban first.y = 14; // Az y adattag elrse a first objektumban first.radius = 3; // A radius adattag elrse a first objektumban second.x = 10; // Az x adattag elrse a secound objektumban second.y = 11; // Az x adattag elrse a secound objektumban second.radius = 4;// A radius adattag elrse a secound objektumban System.Console.WriteLine("Circle 1: Center = ({0},{1})", first.x, first.y); System.Console.WriteLine(" Radius = {0}", first.radius); // A first objektum getArea() tagfggvnynek meghvs s visszaadott // rtknek kiratsa a kpernyre System.Console.WriteLine(" Area = {0}", first.getArea()); // A first objektum circimference() tagfggvnynek meghvsa s // visszaadott rtknek kiratsa System.Console.WriteLine(" Circum = {0}", first.circumference()); // A secound objektum getArea() tagfggvnynek meghvs s // visszaadott rtknek trolsa az area vltozban area = second.getArea(); // A secound objektum circumference() tagfggvnynek meghvs s // visszaadott rtknek trolsa a circ vltozban circ = second.circumference(); System.Console.WriteLine("\nCircle 2: Center = ({0},{1})", second.x, second.y); System.Console.WriteLine(" Radius = {0}", second.radius); System.Console.WriteLine(" Area = {0}", area); System.Console.WriteLine(" Circum = {0}", circ); } }
50
} }
Fontos megjegyezni, hogy a tagfggvnyeknek tadott rtkek szma meg kell egyezzen a meghatrozsnl megadott paramterek szmval.
51
Statikus tagfggvnyek
A korbbiakban lttuk, hogy a static mdost hasznlata esetn a megfelel adattagot a program nem az objektumhoz, hanem az osztlyhoz tartoznak tekinti. A tagfggvnyeknl is minden hasonlan mkdik, mint az adattagoknl. Ez azt jelenti, hogy az objektum helyett az osztly nevvel hivatkozhatunk a tagfggvnyre.
52
C# Amit a C# tudni rdemes! A paramterek meghatrozsukkor jellemzknt alaprtelmezsben az adattpus eredeti jellemzjt kapjk. Az egyszer adattpusok esetben ez rtk szerinti tads jelent. Ha egy ilyen rtket mgis hivatkozs szerint kvnunk tadni, rjuk a paramterek sorba az adattpus el a ref kulcsszt. Mr megemltettk, hogy az egyszer adattpusok alaprtelmezsben rtk szerintiek, vagyis ksztskkor a program egy helyet jell ki szmukra a memriban. Ms adattpusok, gy az osztlyok, alaprtelmezsben hivatkozs szerintiek. Ez azt jelenti, hogy az osztly neve azt a cmet tartalmazza, melyen az osztly adatai tallhatk, nem pedig magukat az adatokat. Nzznk egy pldt erre: 3.12 Hivatkozs s rtk szerinti paramtertads
using System; class nbr { public double squareByVal( double x ) { x = x * x; return x; } public double squareByRef( ref double x ) { x = x * x; return x; }
} class RefVars { public static void Main() { nbr doit = new nbr(); double nbr1 = 3; double retVal = 0;
Console.WriteLine("Before square -> nbr1 = {0}, retVal = {1}", nbr1, retVal); retVal = doit.squareByVal( nbr1 ); Console.WriteLine("After square -> nbr1 = {0}, retVal = {1}", nbr1, retVal); Console.WriteLine("\n---------\n"); retVal = 0; // reset return value to zero
Console.WriteLine("Before square -> nbr1 = {0}, retVal = {1}", nbr1, retVal); retVal = doit.squareByRef( ref nbr1 ); Console.WriteLine("After square -> nbr1 = {0}, retVal = {1}", nbr1, retVal);
53
} }
Az out paramterekben tadott vltozknak nem kell kezdrtket adnunk a tagfggvny hvst megelzen.
54
Az osztly-tagfggvnyek tpusai
A tagfggvnyek hasznlati alapjait mr megtanultuk, de nem szabad figyelmen kvl hagyni nhny klnleges tagfggvny tpust sem: Tulajdonsgelrsi tagfggvnyek Konstruktorok Destruktorok
Tulajdonsgelrsi tagfggvnyek
E tagfggvnyekkel nevk get s set mr dolgoztunk. Feladatuk, hogy lehetv tegyk privt adatok hasznlatt.
Konstruktorok
Az objektumok ltrehozsnl gyakran van szksgnk bizonyos kezdeti belltsokra. E feladat elvgzsre az objektumokban egy klnleges tagfggvny ll rendelkezsnkre a konstruktor (ltrehoz fggvny). E tagfggvnynek kt tpusa ltezik: Pldnykonstruktor ami az egyes objektumpldnyok ksztsnl hasznlatos Statikus konstruktor amelyet a program mg azeltt meghv, hogy akr egyetlen objektumot is ltrehozott volna az osztlybl.
Pldnykonstruktor
A pldnykonstruktor olyan tagfggvny, amelyet a program egy adott osztly minden pldnynak elksztsekor meghv. Brmilyen kdot elhelyezhetnk benne, amit ms tagfggvnyekben, de a konstruktor ltalban az objektumok kezdeti belltsra hasznljk, gy tbbnyire vltozknak adunk rtket bennk. A konstruktor felptse a kvetkez: Mdostk osztlynv() { //a konstruktor trzse } Lthatjuk teht, hogy a konstruktor az osztly nevvel hatrozhatjuk meg. A mdostk az eddig megismertek kzl kerlhetnek ki; itt ltalban a public kulcsszt hasznljuk. Visszatrsi tpust nem tntetnk fel. Fontos tudnunk, hogy minden osztly rendelkezik alaprtelmezett konstruktorral, melyet az objektum meghv, akkor is, ha magunk nem ksztettnk ilyet a szmra. A konstruktor megrsval tbbletlehetsget kapunk a kezdeti belltsok meghatrozsra. Az objektum ltrehozsakor a program automatikusan elindtja a konstruktort. Nzznk erre pldt: 3.14 Konstruktor hasznlata Ksztette: Zstr Csaba III. ves informatikus hallgat 55
Statikus konstruktorok
Az adattagokhoz s tagfggvnyekhez hasonlan statikus konstruktorokat is kszthetnk. A static mdostval elltott konstruktort a program az osztly els objektumnak ltrehozsa eltt hvja meg, s tbb nem is hasznlja. Egy plda erre: 3.15 Statikus konstruktor hasznlata
using System; namespace StatikusKonstruktor { class Konstruktor { static public int szamlalo;
56
Destruktorok
Lehetsgnk van arra is, hogy mveleteket vgezznk az objektum megsemmistsekor erre szolglnak a destruktorok (megsemmist fggvnyek). A destruktor valamikor azutn indul el, hogy a program vgleg befejezte az objektum hasznlatt. Mi az hogy valamikor? Nos, az objektum megsemmistse trtnhet rgtn az objektum hasznlatnak befejezsekor, de eltoldhat egszen a program vgig is. St, mg az is elfordulhat, hogy a program anlkl fejezdik be, hogy meghvta volna a destruktort. Ez azt jelenti, hogy nem igazn rendelkeznk befolyssal a destruktorok hasznlatnak idpontjra, gy alkalmazsuk korltozott hasznossggal br. Egyes nyelvekben ilyen a C++ is magunk is meghvhatjuk a destruktort, gy a programoz befolysolhatja a vgrehajtsnak idejt. A C#-ban erre nincs lehetsgnk. Ha technikai oldalrl kzeltjk meg a dolgokat, azt mondhatjuk, hogy a C# futsidej krnyezete ltalban akkor hvja meg a destruktort, amikor az objektum nincs tbb hasznlatban. Ez a hvs tbbnyire akkor kvetkezik be, amikor a krnyezet szabad vagy felszabadthat memria utn nz (ez a szemtgyjts). Ha a C# futsidej krnyezetnek nincs szksge jabb memriafoglalsra az objektum hasznlatnak befejezse s a program vge kztt, a destruktort egyltaln nem hvja meg. Van r lehetsg, hogy erltessk a szemtgyjtst, de jobban tesszk, ha inkbb a destruktor hasznlatt korltozzuk.
57
A destruktor hasznlata
A C#-ban a destruktorok neve egy hullmos vonalbl (tilde, ~), az osztly nevbl, valamint egy res zrjelprbl ll: ~osztlynv() { //A destruktor trzse } Itt nem hasznlhatunk semmifle mdostt vagy egyb kulcsszt. Nzzk az elz pldt destruktorral kiegsztve: 3.16 Destruktor hasznlata
using System; namespace Destruktor { class Destruktor { static public int szamlalo; public int szam; static Destruktor() { szamlalo = 100; } public Destruktor() { Console.WriteLine("In Constructor..."); szamlalo++; Console.WriteLine("In Constructor szamlalo = {0} ",szamlalo); szam = 0; } ~Destruktor() { Console.WriteLine("In Destructor..."); } } class Class1 { static void Main(string[] args) { Console.WriteLine("Star of Main method..."); Destruktor obj1 = new Destruktor(); Destruktor obj2 = new Destruktor(); Destruktor obj3 = new Destruktor(); Console.WriteLine("End of Main method..."); } } }
58
C# Amit a C# tudni rdemes! Fontos megjegyezni, hogy a destruktor hvsban soha nem lehetnk biztosak. Az is elfordulhat, hogy nem futnak le.
A struktrk tagjai
A struktrk tagjait ugyan gy vezethetjk be, mint az osztlyokit: struct Pont { public int x; public int y; } 3.17 A Pont struktra hasznlata
struct Pont { public int x; public int y; } class PontApp { public static void Main() { Pont starting = new Pont(); Pont ending = new Pont(); starting.x starting.y ending.x = ending.y = = 1; = 4; 10; 11;
System.Console.WriteLine("Pont 1: ({0},{1})",
59
} }
A struktrk tagfggvnyei
Az osztlyokhoz hasonlan a struktrk is rendelkeznek tagfggvnyekkel s tulajdonsgokkal, melyek pontosan gy adhatunk meg, mint az osztlyok esetben. Ez egyttal azt is jelenti, hogy ugyanazokat a mdostkat s jellemzket is hasznlhatjuk. E tagfggvnyek osztlybeli trsaikhoz hasonlan tlterhelhetk, s ugyangy adhatunk, illetve fogadhatunk rtkeket tlk.
A struktrk konstruktorai
A hagyomnyos tagfggvnyek mellett a struktrk rendelkeznek konstruktorokkal is. Ha azonban konstruktor hasznlata mellett dntnk, nem hagyhatjuk resen a paramterlistjt:
struct Point { public int x; public int y; public Point(int x, int y) { this.x = x; this.y = y; }
A struktrk konstruktoraira vonatkozan ltezik mg egy fontos megkts: kezdrtket kell adjanak a struktra sszes adattagjnak. Ha a struktra alaprtelmezett (paramter nlkli) konstruktort hasznljuk, az automatikusan alaprtelmezett rtkeket ad az adattagoknak ez ltalban 0-kat jelent. Ha azonban sajt konstruktorunkat hasznljuk, gyelnnk kell arra, hogy minden adattaggal magunk foglalkozzunk. Ksztette: Zstr Csaba III. ves informatikus hallgat 60
C# Amit a C# tudni rdemes! A new hasznlatt mellzhetjk, ha az alaprtelmezett konstruktort hasznljuk, de ha pldnyostskor sajtunkat szeretnnk alkalmazni, ezt nem kerlhetjk meg.
A struktrk destruktorai
A cm kiss csalka, ugyanis az osztlyokkal ellenttben a struktrk nem rendelkezhetnek destruktorral. Emiatt ne aggdjunk, hiszen a destruktorok bizonytalan vgrehajtsuk miatt amgy sem vesszk sok hasznukat. Ha egy struktrban destruktort prblunk meg alkalmazni, a fordt hibt jelez.
Felsorolsok
A C#-ban lehetsgnk van felsorol tpusok hasznlatra is. Segtsgkkel olyan vltozkat hozhatunk ltre, melyek rtke vges halmazbl szrmazik. Vegyk pldaknt a ht napjait. Ahelyett, hogy sorszmukkal 1,2,3,4,5,6,7 hivatkoznnk rjuk, sokkal knnyebben kezelhetv vlnak, ha nevkn szlthatnnk ket. A felsorolsokkal lehetv vlik ilyen rtkek hasznlata. Bevezetsk az enum kulcsszval trtnhet, a kvetkez alakban: mdostk enum felsorols_neve { felsorols_tag1, felsorols_tag2, ... Felsorols_tagN } A mdost helyn a new kulcssz, illetve az elrsi mdostk llhatnak. A felsorols_neve brmilyen rvnyes azonost lehet, mg a felsorols_tag1 felsorols_tagN a felsorolt rtkeket tartalmazzk. Ha a felsorolst a gyakorlatban is hasznlni akarjuk, akkor egy felsorols_neve tpus objektumot kell ksztennk. Nzznk erre egy pldt: 3.18 Az enum kulcssz hasznlata
using System; class Colors { enum Color { red, white, blue } public static void Main() {
61
62
} }
Tmbk
A korbbiakban megtanultuk, hogy a klnbz tpus adatokat egyttesen osztlyokban vagy struktrkban trolhatjuk. Sokszor addik azonban, hogy trolt adatok tpusa azonos, s akkor nyjt segtsget a tmb tpus.
63
C# Amit a C# tudni rdemes! A tmb teht olyan vltoz, amely azonos tpus adatokat tartalmaz. Ezek az rtkek egyms utn llnak a szmtgp memrijban, gy mdostsuk s elkeressk egyszer. Az, hogy egy vltozt egy msik utn vezetnk be a kdszvegben, mg nem jelenti azt, hogy rtkeik a memriban egyms mell kerlnek. pp ellenkezleg: e vltozk a memria egszen klnbz rszeire eshetnek, mg ha egytt adtuk is meg ket. A tmb azonban egyetlen vltoz, csak tbb elemmel. Ez az oka annak, hogy az elemek egyms utn llnak a memriban. Ha tmbt szeretnnk bevezetni, az adattpus utn egy szgletes zrjelprt kell kitennnk: Adattpus[] tmb_nv; Nzzk meg a tmb mkdst egy konkrt pldn keresztl: decimal[] tomb; Ezzel ltrehoztunk egy vltozt, amely kpes decimal rtkek trolsra, de memrit nem foglaltunk le szmukra. Ennek elvgzsre hasonlan a korbbiakban ltottakhoz a new kulcsszt kell hasznlnunk. Ha tmbnket pldnyostjuk, meg kell hatroznunk, hny rtket fog trolni. Ez gy megtehetjk meg, ha a kezdeti rtkadsnl szgletes zrjelben feltntetjk a tmbelemek szmt: tomb = new decimal[12]; vagy decimal[] tomb = new decimal[12]; Miutn bevezettnk egy tmbt hasznlni is szeretnnk. A tmb elemekbl ll, melyeket sorszmuk (indexk) segtsgvel rhetnk el. A tmbk els elemnek indexe 0, a msodik 1, az utols elem sorszma pedig eggyel kisebb, mint a tmb hossza. A tmb adott elemnek elrshez a tmb neve utn fel kell tntetnnk az elem sorszmt szgletes zrjelek kztt. Pldul: tomb[5] = 1235.25m; Nzznk egy pldt a tmbk hasznlatra: 3.20 Tmbk hasznlata
using System; public class Balances { public static void Main() { decimal[] balances = new decimal[12]; decimal ttl = 0m; System.Random rnd = new System.Random(); for (int indx = 0; indx < 12; indx++ )
64
} }
Tbbdimenzis tmbk
A tbbdimenzis tmb valjban tmbk tmbje st, lehet tmbk tmbjnek tmbje is! A szintek szaporodsval gondjaink is srsdnek, s kdunk kezd tlthatatlann vlni, ezrt hrom szintnl (hrom dimenzinl) tbbet nem rdemes hasznlnunk. Az egyszer tmbk tmbjt ktdimenzis tmbknt is szoks emlegetni, ugyanis termszetes mdon brzolhat kt dimenziban. A ktdimenzis tmbk bevezetsnl, az egyszer tmbknl (egydimenzis) tanultakbl indulunk ki: byte[,] tomb = new byte[15,30]; A klnbsg annyi, hogy a deklarci els felben megjelent egy vessz, a msodik felben pedig kt, vesszvel elvlasztott szm szerepel. Ha csak egy egyszer tbbdimenzis tmbt szeretnnk kszteni, ami nhny karaktert tartalmaz, a kvetkezt kell rnunk: Ksztette: Zstr Csaba III. ves informatikus hallgat 65
C# Amit a C# tudni rdemes! char[,] betuk = new char[2,3]; Ez egy ktdimenzis tmb, mely kt, hromelem karaktertmbt tartalmaz. Kezdrtkkel a bevezets pillanatban is ellthatjuk: char[,] betuk = new char[2,3] {{a,b,c}, {X,Y,Z}}; vagy betuk[0,0] betuk[0,1] betuk[0,2] betuk[1,0] betuk[1,1] betuk[1,2] = = = = = = a; b; c; X; Y; Z;
A myname egy tmbkbl ll tmb, amely kett, klnbz mret karaktertmbt tartalmaz. Mivel a tmbk klnbz hosszsgak, nem bnhatunk velk gy, mint korbbi szablyos trsaikkal. Itt nem hasznlhatunk egy kzs szgletes zrjelprba zrt, vesszvel elvlasztott indexprt kln szgletes zrjelek kz kell helyeznnk ket. Kezdeti rtkads nlkl a kvetkezkppen kell eljrnunk: char myname = new char[2][]; myname[0] = new char[6]; myname[1] = new char[5];
C# Amit a C# tudni rdemes! A C# nyelvben a tlterhels nyjtotta lehetsgeket a legltvnyosabban a tagfggvnyekkel kapcsolatban lehet megmutatni. Ltrehozhatunk olyan osztlyt, amely szmos klnbz tpus adattal kpes dolgozni, de az eredmny mindig ugyanaz lesz. A tagfggvnyek tlterhelse azt jelenti, hogy tbb klnbz tagfggvnyt hozunk ltre azonos nvvel. Ugyanakkor ezeknek a tagfggvnyeknek mgis egyedieknek kell lennik valamilyen mdon, msknt a fordtprogram nem tud klnbsget tenni kzttk. Nzznk egy pldt a tagfggvnyek tlterhelsre: 3.22
using System; public class Circle { public int x; public int y; public double radius; private const float PI = 3.14159F; public double Area() { return Area(radius); } public double Area( double rad ) { double theArea; theArea = PI * rad * rad; Console.WriteLine(" The area for radius ({0}) is {1}", rad, theArea); return theArea; } public double Area(int x1, int y1, double rad) { return Area(rad); } public double Area( int x1, int y1, int x2, int y2 ) { int x_diff; int y_diff; double rad; x_diff = x2 - x1; y_diff = y2 - y1; rad = (double) Math.Sqrt((x_diff * x_diff) + (y_diff * y_diff)); return Area(rad); } public Circle()
Tagfggvnyek
tlterhelse
68
class CircleApp { public static void Main() { Circle myCircle = new Circle(); Console.WriteLine("Passing nothing..."); myCircle.Area(); Console.WriteLine("\nPassing a radius of 3..."); myCircle.Area( 3 ); Console.WriteLine("\nPassing a center of (2, 4) and a radius of 3..."); myCircle.Area( 2, 4, 3 ); Console.WriteLine("\nPassing center of (2, 3) and a point of (5, 6)..."); myCircle.Area( 2, 3, 4, 5 ); }
Egy kicsit hossz a kd, de ha alaposan ttanulmnyozzuk, akkor vilgoss vlik, hogy mit jelent a tagfggvnyek tlterhelse. A kdsor rvid magyarzata: A program a kr terlett szmtja ki hrom klnbz mdon a sugr segtsgvel, a sugr s a kzppont koordintjnak segtsgvel, valamint a kzppont koordintjnak s a kr egy kerleti pontjnak koordintinak segtsgvel. Erre hrom klnbz paramterlistj, de azonos nev tagfggvny ll rendelkezsnkre. A program a paramterlista alapjn vlasztja ki, hogy melyik tagfggvnyt hasznlja a kr terletnek kiszmtsra.
Konstruktor tlterhelse
A kznsges tagfggvnyek tlterhelse mellett lehetsgnk van a konstruktorok tlterhelsre is. Egy tlterhel konstruktor lehetsget ad arra, hogy egy objektumnak bizonyos rtkeket adjuk t, kzvetlenl a ltrehozs pillanatban. Nzznk erre is egy pldt: 3.23 Konstruktor tlterhelse
using System; { public class Circle public int x; public int y; public int radius; private const float PI = 3.14159F;
69
= = = =
class CircleApp { public static void Main() { Circle first = new Circle(); Circle second = new Circle(4); Circle third = new Circle(3,4); Circle fourth = new Circle(1, 2, 5);
70
Lthat, hogy valamennyi konstruktort ugyanolyan nvvel s azonos mdon hoztuk ltre. Az egyetlen eltrs itt a bemen paramterek szmban van. Ezt nevezzk alrsnak.
A tagfggvnyek alrsa
A tagfggvnyeket azrt lehet tlterhelni, mert valamennyinek egyedi alrsa (szignatra, signature) van. Amint azt az elbb lttuk, a tlterhelt tagfggvnyeket a rendszer a bemen paramterek szma alapjn kpes megklnbztetni. Valjban e klnbsgttelnek ms mdszerei is lteznek. A tagfggvnyek gynevezett alrst egyttesen alkotjk azok a tulajdonsgok, amelyek a klnbsgttel alapjul szolglnak. Egy tagfggvny alrsa teht alapveten bemen paramtereinek szmbl s tpusbl tevdik ssze. Nzzk az elbbi kdsor konstruktorait: Circle() Circle( int ) Circle( int, int ) Circle( int, int, int ) A 3.22 kdsorban bemutatott Area tagfggvnynek szintn ngy klnbz alrsa volt, hiszen ngy vltozatban ltezett: double double double double Area() Area( double ) Area( int, int, double ) Area( int, int, int, int )
A kvetkez kd tovbbi ngy olyan tagfggvny-vltozatot mutat, amelynek szintn elfordulhatnak egytt ugyanazon osztlyon bell: MyFunc( MyFunc( MyFunc( MyFunc( int ) float ) ref int ) val int )
71
C# Amit a C# tudni rdemes! Ugyanakkor vannak bizonyos dolgok, amelyek br elvileg szolglhatnnak a klnbsgttel alapjul, nem szerepelnek a tagfggvnyek alrsban. Ilyen pldul a visszatrsi rtk tpusa. Nem szmt klnbznek kt alrs akkor sem, ha az egyik tagfggvnyben ugyanolyan tpus tmb szerepel bemen paramternek, mint amilyen skalr adattpus az adott helyen a msik pldnyban elfordul. A kvetkez tlterhelsi ksrletre teht fordtsi hibazenetet fogunk kapni: int myMethod( int ) int myMethod( int[] ) Az alrsok megklnbztetsre a params kulcsszt sem hasznlhatjuk. Ha teht egy programban egytt fordul el a kvetkez kt tagfggvny, megint csak fordtsi hibazenetet kapunk: void Method( string, float ) void Methos( string, params float[]) A C# ugyanakkor nem korltozza a tlterhelt pldnyok szmt. Amg brmely kt alrs klnbzik egymstl, tetszlegesen sok vltozatt adhatjuk meg ugyanannak a tagfggvnynek.
72
class MyApp { public static void Main() { long Total = 0; Total = AddEm.Add( 1 ); Console.WriteLine("Total of (1) = {0}", Total); Total = AddEm.Add( 1, 2 ); Console.WriteLine("Total of (1, 2) = {0}", Total); Total = AddEm.Add( 1, 2, 3 ); Console.WriteLine("Total of (1, 2, 3) = {0}", Total); Total = AddEm.Add( 1, 2, 3, 4 ); Console.WriteLine("Total of (1, 2, 3, 4) = {0}", Total);
} }
Ha a deklarcibl kihagyjuk a params kulcsszt, akkor a 30., 33. s 36. sorokban lthat kddal nem sokra megynk. Ahelyett, hogy egyszeren tadnnk a tagfggvnyeknek a paramtereket, elbb el kellene azokat helyeznnk egy egszeket tartalmaz tmbben, majd a tmbt kellene tadnunk. A params kulcssz legfbb haszna ppen az, hogy ezt az egszet a fordtprogramra bzza. Lthat, hogy az elbb nem hoztunk ltre AddEm tpus objektumot. Mivel az Add tagfggvny statikus (static) egyszeren az osztly nevvel (AddEm) hvtuk meg. Mindez teht ezt jelenti, hogy a fggvnyt akkor is hasznlhatjuk, ha egyetlen objektumot sem hozunk ltre.
73
} }
class MyApp { public static void Main() { long ALong = 1234567890987654321L; decimal ADec = 1234.56M; byte Abyte = 42; string AString = "Cole McCrary"; Console.WriteLine("First call..."); Garbage.Print( 1 ); Console.WriteLine("\nSecond call..."); Garbage.Print( ); Console.WriteLine("\nThird call..."); Garbage.Print( ALong, ADec, Abyte, AString ); Console.WriteLine("\nFourth call..."); Garbage.Print( AString, "is cool", '!' );
} }
75
Az els kimenet azt mutatja, hogy mi trtnik, ha parancssori paramterek nlkl hvjuk meg a programot. C:\gyak\CommandLine>CommanLine
No Command Line arguments were provided
A msik kimenet azt mutatja, miknt reagl a programunk klnbz szm s tpus parancssori paramterek megadsra. C:\gyak\CommandLine>CommanLine xxx 123 456 789.012 Argumentum 1 is xxx Argumentum 2 is 123 Argumentum 3 is 456 Argumentum 4 is 789.012
Hatkrk
A vltozk nem tartanak rkk. Ezrt tisztban kell lennnk, hogy egy vltoz meddig ltezik, s mikor trli a futsidej rendszer. A vltoz lettartamt s a hozzfrhetsgt egyttesen hatkrnek (scope, rvnyessgi kr) nevezzk. A hatkrnek tbb szintje ltezik, melyek kzl a kt leggyakrabban hasznlt vagy emltett a globlis (ltalnos, programszint) s a helyi (loklis) rvnyessg. A globlis vltozk a kd brmely pontjrl lthatk s hozzfrhetk. Ugyanakkor megadhatk olyan vltozk is, amelyek a kdnak csak egy kisebb-nagyobb terletrl kezelhetk. Ezeket az adott terletre nzve helyi vltozknak nevezzk.
76
C# Amit a C# tudni rdemes! Ha ezt a kdsort megprbljuk futtatni, akkor egy hibt fogunk kapni, ugyanis a Console.WriteLine("Out of For Loop. x is {0}", x)-ban lv x ezen a ponton nem ltezik, nincs bevezetve. Az x vltozt a for cikluson bell hoztuk ltre, ami azt jeleni, hogy amikor a for ciklus mkdse befejezdik, akkor az x vltoz is megsznik ltezni, megsznik az rvnyessge. Ha pedig egy vltozt sajt hatkrn kvl prblunk meg hasznlni, az hibt eredmnyez.
77
C# Amit a C# tudni rdemes! De hogyan is hasznlhatunk egy osztlyt annak elemeit kpz objektum nlkl? Amint azt mr megtanultuk, a static tpus tagfggvnyek logikailag maghoz az osztlyhoz tartoznak, s nem az osztly objektumaihoz. Ez egyben azt is jelenti, hogy ha egy osztly valamennyi adattagja s tagfggvnye statikus, akkor semmi rtelme az osztlyba tartoz objektumokat ltrehozni. Nzznk erre egy egyszer pldt: 3.28 Statikus tagfggvnyek
using System; public class MyMath { public static long Add( params int[] args ) { int ctr = 0; long Answer = 0; for( ctr = 0; ctr < args.Length; ctr++) { Answer += args[ctr]; } return Answer; } public static long Subtract( int arg1, int arg2 ) { long Answer = 0; Answer = arg1 - arg2; return Answer; } } class MyMathApp { public static void Main() { long Result = 0; Result = MyMath.Add( 1, 2, 3 ); Console.WriteLine("Add result is {0}", Result); Result = MyMath.Subtract( 5, 2 ); Console.WriteLine("Subtract result is {0}", Result);
} }
class MyMathApp2 { public static void Main() { long Result = 0; // MyMath var = new MyMath(); Result = MyMath.Add( 1, 2, 3 ); Console.WriteLine("Add result is {0}", Result); Result = MyMath.Subtract( 5, 2 ); Console.WriteLine("Subtract result is {0}", Result); } }
A nvtr elnevezse
Egy nvtr brmilyen nevet tartalmazhat, amely egybknt is hasznlhat a megfelel tpusokkal kapcsolatban. Ez gyakorlatilag azt jelenti, hogy a nevek szabvnyos karakterekbl llhatnak, s az alhzs karaktert is tartalmazhatjk. Maguknak a nvtereknek a nevei ezen kvl pontot is tartalmazhatnak. Ezeken kvl egyb megkts a nvterekkel kapcsolatban nincs, de mint mshol, itt is clszer trekedni a kifejez nevek hasznlatra.
A nvtr bevezetse
A nvterek megadshoz a namespace kulcsszt kell hasznlnunk, amelyet a ltrehozni kvnt nvtr neve kvet. A nvtrbe tartoz neveket kapcsos zrjelek kztt soroljuk fel. Pldul: 3.30 Nvtr megadsa
using System; namespace Consts { public class PI { public static double value = 3.14159; private PI() {} // private constructor } public class three { public static int value = 3; private three() {} // private constructor } } namespace MyMath { public class Routine { public static long Add( params int[] args ) { int ctr = 0; long Answer = 0; for( ctr = 0; ctr < args.Length; ctr++) { Answer += args[ctr]; } return Answer; } public static long Subtract( int arg1, int arg2 ) { long Answer = 0; Answer = arg1 - arg2; return Answer; } }
80
} }
Minden forrskdot tartalmaz fjl egy-egy nll nvteret kpvisel mg akkor is, ha ezt kifejezetten nem adjuk meg. Ugyanakkor valamennyi fjl egy-egy globlis nvteret tartalmaz, ami azt jelenti, hogy a krdses fjlban nevestett nvterekbl a fjl minden egyb eleme hozzfrhet.
81
C# Amit a C# tudni rdemes! mkdse szempontjbl kritikusnak szmtanak, s melyek azok, amelyeket figyelmen kvl hagyhatunk.
Mi okozhat kivtelt?
Ha magnak a programnak a logikja nem gtolja meg a hiba fellptt, akkor kivtel keletkezik. A kivtel teht nem ms, mint egy kezeletlen programozsi hiba. Nem tartoznak ebbe a kategriba azok a logikai hibk, amelyek egy mvelet eredmnye, s nem a program szerkezete miatt keletkeznek. Ha a program futsa kzben kezeletlen hiba lp fel, a futsidej vgrehajtsi rendszer megll, s kivtel lp fel. A kvetkez kdszveg egy olyan kdot mutat be, amely futs kzben kivtelt vlt ki: 3.32 Kivtel keletkezse
using System; class Error { public static void Main() { int [] myArray = new int[5]; for ( int ctr = 0; ctr < 10; ctr++ ) { myArray[ctr] = ctr; } } }
Ha lefuttatjuk ezt a kis programot, ami nem csinl semmi hasznosat, de arra j plda, hogy mikor keletkezik kivtel. Lthat, hogy egy tmbn haladunk vgig egy for ciklus segtsgvel, azonban a tmb csak t elembl ll. Mi trtnik, amikor megprblunk a Ksztette: Zstr Csaba III. ves informatikus hallgat 83
C# Amit a C# tudni rdemes! hatodik elemre hivatkozni? Nos, ekkor keletkezik a kivtel. Ha futtatjuk, akkor a rendszer jelzi, hogy kivtel trtnt, s a kvetkezhz hasonl zenet is megjelenik:
Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
Ezt a szveget a programban hasznlt egyik objektum lltotta el, mgpedig maga a tmb. sszessgben teht a futsnak nem az lett az eredmnye, amit a felhasznlval lttatni szerettnk volna. Ha valban felhasznl bart programot akarunk rni, az effle hibkat sokkal kifinomultabb mdon kell kezelnnk. Ez a program radsul hirtelen megllt, amikor a hiba bekvetkezett, ez pedig nem mindig engedhet meg. A val letben gyakoriak az olyan helyzetek, amikor a program feletti uralmat akkor is meg kell tudnunk tartani, ha az trtnetesen valamilyen hibs mveletet hajtott vgre. A futsidej rendszer ltal megjelentett hibazenet:
Kivtelkezels
A kivtelkezels a futsidej hibk kezelst jelenti. Lnyege, hogy programunkban megadhatunk olyan kdrszleteket, amelyek kpesek elfogni s bartsgosabb mdon kezelni a futs kzben keletkez kivteles esemnyeket. Az ilyen kivtelkezel eljrsok lnyege teht ppen az, hogy ltaluk elkerlhessk az elbb bemutatott zenetablakok hirtelen felbukkanst, a programok vratlan lellst, vagy az rtelmezhetetlen hibazenetek kirst. A kivtelkezelssel kapcsolatos kt legfontosabb nyelvi elem a try s a catch.
84
85
C# Amit a C# tudni rdemes! catch(Exception e) {} Az Exception tpus e vltoz a keletkezett kivtel lersval kapcsolatos informcikat hordoz. Hasznlata lehet a kvetkez:
catch( Exception e) { Console.WriteLine("The following exception was caught:\n{0}", e); }
} }
C# Amit a C# tudni rdemes! htul kvetkezzenek. De a prba kedvrt cserljk meg az elz pldban szerepl kt catch blokkot:
catch (Exception e) { Console.WriteLine("Exception caught: {0}", e); } catch (IndexOutOfRangeException e) { Console.WriteLine("You were very goofy trying to use a bad array index!!", e); }
Ha jrafordtjuk a programot, hibazenetet kapunk. Mivel az ltalnos catch(Exception e) parancs az sszes kivtelt elfogja, egyetlen ms catch blokk sem fog soha lefutni.
class ListFile { public static void Main(string[] args) { try { int ctr=0; if (args.Length <= 0 ) { Console.WriteLine("Format: ListFile filename"); return; } else { FileStream fstr = new FileStream(args[0], FileMode.Open); try { StreamReader sReader = new StreamReader(fstr); string line; while ((line = sReader.ReadLine()) != null) { ctr++; Console.WriteLine("{0}: {1}", ctr, line); } } catch( Exception e )
87
} }
catch (System.IO.FileNotFoundException) { Console.WriteLine ("ListFile could not find the file {0}", args[0]); } catch (Exception e) { Console.WriteLine("Exception: {0}\n\n", e); } } }
Format: ListFile filename Ha futtatjuk a programot, akkor a megadott kdszveget kapjuk a kimeneten. Ez egy tjkoztat szveg, ami azt mondja, hogy a program neve utn parancssorban meg kell adnunk egy fjl nevt is. Ha paramterknt magnak a programnak a kdjt tartalmaz fjlt adjuk meg, akkor a forrskdot ratjuk ki a kpernyre, melynek sorait a program beszmozza. Termszetesen fogadhatunk ms fjlneveket is, s az eredmnymindig hasonl lesz, ha az adott nev fjl ltezik. Ha viszont egy olyan nevet adunk meg, amely egyetlen ltez fjlhoz sem tartozik, a kvetkez zenetet fogjuk kapni (xxx a fjl nevt jelenti, amit megadtunk a parancssorban): ListFile could not find the file xxx Lthat, hogy hiba trtn, a program nem valamilyen rejtlyes zenetet kld a kpernyre, hanem rtheten megnevezi a hiba okt. Azt hogy nem tallt ilyen (xxx) nev fjlt.
A leggyakoribb kivtelek
A .NET keretrendszer szmos gyakrabban elfordul kivtel meghatrozst tartalmazza. Ezek kzl nhnnyal mr az elz pldkban is tallkoztunk. Most a leggyakoribb kivteleket soroljuk fel, melyek a System nvtrben szerepl kivtelosztlyok kzl a legfontosabbak: System nvtrben szerepl legfontosabb kivteltpusok Kivtel neve
MemberAccessException
Lers Hozzfrsi hiba. Egy bizonyos tag, pldul egy tagfggvny nem hozzfrhet 88
Kivtel neve
ArithmeticException
ArrayTypeMismatchException
DivideByZeroException
FormatException IndexOutOfRangeException
InvalidCastException
MulticastNotSupportedException
NotFiniteNumberException NotSupportedException
NullReferenceException
OutOfMemoryException
OverflowException
StackOverflowException TypeInitializationException
Paramterhiba. Egy tagfggvny valamelyik paramtere hibs. Null paramter. Egy tagfggvny null rtket kapott paramterknt, de az nem elfogadhat. Lers Matematikai hiba. Valamilyen hibs matematikai mvelet vgrehajtsa miatt keletkezett kivtel. Ez a hibatpus ltalnosabb, mint az OverflowException vagy a DivideByZeroException. Tmbtpussal kapcsolatos hiba. Ilyen hiba akkor keletkezik, ha egy tmbben nem a neki megfelel adattpust akarjuk trolni. Nullval val oszts. Nevnek megfelelen akkor keletkezik, ha egy mveletben nullval akarunk osztani. Hibs formtum. Valamelyik paramternek hibs a formtuma. Tl nagy vagy tl kicsi tmbindex. Ilyen tpus hiba akkor keletkezik, ha egy indexelshez (sorszmozshoz) hasznlt rtk kisebb, mint 0, vagy nagyobb, mint a legmagasabb tmbindex. rvnytelen tpus-talakts. Ilyen hiba akkor keletkezhet, ha nem sikerl vgrehajtani egy knyszertett tpustalaktst. A tbbes mvelet (multicast) nem tmogatott. Ilyen hiba kt nem null kpvisel rvnytelen kombinlsakor keletkezik. A megadott, vagy keletkezett rtk nem vges szm. Ez gyakorlatilag egy hibs szmalakot jelent. Nem tmogatott tagfggvny. Ez a kivteltpus akkor keletkezik, ha olyan tagfggvnyt hvunk meg, amelynek az adott osztlyban nincs megvalstsa. Null rtkre val hivatkozs. Ilyen hiba akkor keletkezik, ha hivatkozson keresztl egy null objektum tartalmhoz akarunk hozzfrni. Elfogyott a szabad memria. Ilyen kivtel akkor keletkezik, ha egy j mvelet elvgzshez nem ll rendelkezsre a kell nagysg szabad memria. Tlcsorduls kvetkezett be. Ilyen hiba akkor keletkezik, ha egy matematikai mvelet eredmnye tl nagy, vagy tl kicsi szm, s a checked kulcsszt hasznljuk. Veremtlcsorduls lpett fel. Ilyen hiba akkor keletkezik, ha a veremben mr tl sok mvelet van. Hibs tpusbellts. Ilyenkor egy static tpus konstruktorral van valami gond. 89
A throw kulcssz utn a kerek zrjelek hasznlata nem ktelez. A kvetkez kt kdsor egyenrtk: throw( exception ); throw exception;
90
class MyMath { static public int AddEm(int x, int y) { if(x == 3 || y == 3) throw( new MyThreeException() ); return( x + y );
91
Lthat, hogy a MyMath osztly statikus AddEm tagfggvnyt hasznljuk arra, hogy sszeadjunk kt szmot. Itt tallhat egy if utasts, ami megvizsglja, hogy x vagy y egyenl-e hrommal, ha igen, akkor kivtelt vlt ki, s kirjuk a konzolra, hogy: Ack! We don't like adding threes.
Kivtelek tovbbdobsa
Az eddigiek utn taln mr nem meglep, hogy ha mdunkban ll rendszerkivtelt kivltani, st sajt kivtelt is ltrehozhatunk, akkor lehetsgnk van a kivtelek tovbbdobsra is. A krds csak az, hogy mikor rdemes ilyen programszerkezetet kialaktani s pontosan mi rtelme van ennek a megoldsnak? Amint azt lttuk, a megfelel programblokk megrsa rn elfoghatunk s kezelhetnk brmilyen kivtelt. Ha ezt egy olyan osztly belsejben tesszk, amit egy msik osztly hvott meg, akkor bizonyos esetekben clszer lehet a hiba bekvetkezsrl a hv felet is rtesteni. Az is elfordulhat persze, hogy mieltt mg ezt az rtestst kikldennk, bizonyos mveleteket mi magunk is el akarunk vgezni. Vegynk egy olyan pldt, ami egy korbban bemutatott programon alapul. Ltrehozunk egy olyan osztlyt, amelyik megnyit egy fjlt, megszmolja, hny karakter van benne, majd ezt a szmot visszaadja a hv flnek. Ha a szmolst vgz osztlynak nem sikerl megnyitnia a fjlt, kivtel keletkezik. Ezt a kivtelt ott helyben el is foghatjuk,a szmll rtkt nullra lltjuk, majd ezt az rtket csendben visszaadjuk a hvnak. Ebbl azonban a hv nem fogja soha megtudni, hogy valami gond volt a fjllal. Csak annyit fog ltni, hogy a karakterek szma valamirt nulla, de hogy pontosan mirt, az ebbl nem derl ki. Ebben a helyzetben sokkal jobb megolds, ha a szmll rtkt nullra lltjuk, a kivtelt pedig tovbbadjuk a hvnak. gy a hv is pontosan tisztban lehet a trtntekkel, s szksg esetn reaglhat. Ahhoz, hogy egy kivtelt tovbbadhassunk, a catch parancsnl meg kell adnunk egy paramtert. Ez nem ms, mint a krdses kivtel tpusa. A kvetkez pldban azt mutatjuk meg, hogyan adhatunk tovbb egy kivtelt egy ltalnos szerkezet catch blokk segtsgvel:
catch (Exception e) { //Idejn a sajt kivtellogika throw(e); //az e az a paramter, amit ez a catch kap }
C# Amit a C# tudni rdemes! nagy vagy tl kicsi, kivtel keletkezik. Ha viszont az unchecked kulcsszt adtuk meg, a rendszer a krdses rtket automatikusan akkorra csonktja, hogy belefrjen a megadott helyre. Nzznk erre egy pldt: 3.38 Checked kulcssz hasznlata
using System; class CheckIt { public static void Main() { int result; const int topval = 2147483647; for( long ctr = topval - 5L; ctr < (topval+10L); ctr++ ) { checked { result = (int) ctr; Console.WriteLine("{0} assigned from {1}", result, ctr); } }
} }
Gpeljk be s nzzk meg mi lesz az eredmny. Ha a for ciklus elrte a 2147483647-et, s megprbl ennl a szmnl nagyobbat elhelyezni egy egszeket tartalmaz vltozban, akkor kivtel keletkezik. Most prbljuk ki gy ezt kdsort, hogy a checked kulcssz helyett az unchecked-et hasznljuk. Ekkor pedig nem vlt ki a program kivtelt, hanem a vltozban tlcsorduls kvetkezik be. Hasznlhatjuk ugyanakkor ezeket a kulcsszavakat mveletknt (opertorknt) is. Ebben az esetben az ltalnos alakjuk a kvetkez: [un]checked (kifejezs) Ilyenkor csak a kerek zrjelek kztt megadott kifejezsre fog vonatkozni az ellenrzs elrsa vagy tiltsa.
C# Amit a C# tudni rdemes! #define #else #elif #endregion #endif #if #error #line #region #undef #warning Egy szimblumot hatroz meg. Egy else blokkot nyit meg. Az if s az else parancs kombincija. Egy rgi vgt jelzi. Egy #if blokk vgt jelzi. Egy rtket vizsgl. A megadott hibazenetet kldi ki fordts kzben. A forrskd adott sornak sorszmt jelenti meg. Tartalmazhat fjl nevet is, ami szintn megjelenik a kimeneten. Egy rgi kezdett jelzi. A rgi a forrskd olyan rsze, amely egy egyestett fejlesztrendszerben kln nyithat, illetve becsukhat. Meghatrozatlann tesz egy szimblumot. A megadott figyelmeztetst kldi ki fordts kzben.
94
95
96
A sorszmok megvltoztatsa
A C# nyelv egy jabb gyakran hasznlt direktvja a #line. Ezzel a direktvval a kdban a sorok szmt hatrozhatjuk meg. Ennek hatsa akkor rzkelhet, amikor hibazeneteket kldnk ki fordts kzben. A #line direktva hasznlatt a kvetkez kdsor mutatja be: 3.40 A #line direktva hasznlata
using System; public class Lines { #line 100 public static void Main(String[] args) { #warning In Main... Console.WriteLine("In Main...."); myMethod1(); myMethod2(); #warning Done with main Console.WriteLine("Done with Main"); } #line 200 static void myMethod1() { Console.WriteLine("In Method 1"); #warning In Method 1... int x; // not used. Will give warning. } #line 300 static void myMethod2() { Console.WriteLine("in Method 2"); #warning In Method 2... int y; // not used. Will give warning. } }
97
98
C# Amit a C# tudni rdemes! Figyeljk meg, hogy ha az brt balrl jobbra, vagyis az rkls irnyban olvassuk, akkor egyetlen szlbl tbb gyermek is szrmazhat. Ha azonban jobbrl balra haladunk, mindig egyes kapcsolatokat ltunk, vagyis a gyermek-szl viszony egyszeres. Egy szrmaztatott osztlynak mindig csak egyetlen alaposztlya ltezik.
99
Ha pldul a Person alaposztlybl val rklst akarunk elrni, akkor a kvetkez formt hasznljuk az j osztly bevezetsekor: Class SzrmazottOsztlyNeve : AlapOsztlyNeve Az rkls jele teht a kettspont ( : ), amely az j szrmazott osztly s az eredeti, vagy ms nven alaposztly nevt vlasztja el a deklarciban. Nzzk meg most az rklst a Person alaposztlyra: 3.42 Az rkls legegyszerbb formja
using System; using System.Text; class Person
100
101
class NameApp { public static void Main() { Person myWife = new Person("Melissa", "Anne", "Jones", 21); Employee me = new Employee("Zstr","Csaba", 23); Employee you = new Employee("Kyle", "Rinni", 2000); myWife.displayFullName(); myWife.displayAge(); me.displayFullName(); Console.WriteLine("Year hired: {0}", me.hireYear); me.displayAge(); you.displayFullName(); Console.WriteLine("Year hired of him: {0}", you.hireYear); you.displayAge();
} }
Lthat, hogy az Employee nev osztly az, amelyik a Person osztlybl szrmazik. Az Employee osztly rkli a Person osztly minden tulajdonsgt, s kiegszti azt egy hYear nev j vltozval. Lthat, hogy az Employee osztlynak a konstruktorai olyanok, melyek bemen paramtereket vrnak. A kettspont utna a base kulcsszt ltjuk. Ebben a helyzetben azt jelenti, hogy a szrmaztatott osztlybl megkvnjuk hvni az alaposztly
102
C# Amit a C# tudni rdemes! konstruktort, mgpedig azzal a kt paramterrel, amit a szrmaztatott osztly konstruktora kap paramterknt. Az Employee osztly displayFullName tagfggvnynek deklarcijban a new kulcssz is szerepel. Mivel az alaposztlynak is volt szintn egy ilyen nev tagfggvnye, s mivel a new kulcsszt is megadtuk, ez a tagfggvny fellbrlja az alaposztly azonos nev tagfggvnyt, s az a kd fut le, ami itt ll, s nem az alaposztly azonos nev tagfggvnynek kdblokkja.
Ez a vltozat a szrmaztatott osztly displayFullName tagfggvnyt rintette, amely immr nem maga vgzi el a teljes munkt, hanem nmi szveg kirsa utn egyszeren meghvja az alaposztly megfelel tagfggvnyt, vagyis az eredeti displayFullName tagfggvnyt. Ez a mdszer lehetv teszi, hogy az alaposztly kpessgeit anlkl egsztsk ki, hogy a teljes kdot jra kellene rnunk.
103
class NameApp { public static void Main() { Employee me = new Employee("Zstr", "Csaba", 1983); Person Brad = me; me.displayFullName(); Console.WriteLine("Year hired: {0}", me.hireYear); } } Brad.displayFullName();
104
C# Amit a C# tudni rdemes! Mrmost ha a Brad nev s Person tpus objektumhoz egy Employee tpus msik objektumot rendelnk, akkor vajon ki fogja megmondani, hogy melyik tpus tagfggvnyeit vagy adattagjait kell a megfelel pontokon rteni? Pldul meghvhatjuk-e a Brad.hireYear tagfggvnyt, mikzben Brad lltlag Person, s ennek az osztlynak egyltaln nincs ilyen nev tagfggvnye. Kiltstalan tprengs helyett a legegyszerbb az lesz, ha kiprbljuk, mi trtnik. Szrjuk teht be a kvetkez sort: Console.WriteLine("Year hired: ",Brad.hireYear); Az ember azt gondoln, hogy egyszeren megjelenik a kpernyn az 1963-as szm, de nem. Brad Person tpus objektum, a Person osztlynak pedig nincs hireYear nev tagja. Az eredmny egy hibazenet lesz. Br az Employee tpus a Person minden tulajdonsgval rendelkezik, ennek az lltsnak a fordtottja mg akkor sem igaz, ha egy Person objektumnak egy Employee objektum tartalmt adjuk rtkl. Megint kiss ltalnosabban megfogalmazva a tapasztalatokat, azt mondhatjuk , hogy egy szrmazott osztly minden, ami az alaposztly volt, de az alaposztly soha nem lesz tbb azltal, hogy ms osztlyokat szrmaztatnak belle. Na s akkor hol van a tbbalaksg? Egszen egyszeren megfogalmazva, a tbbalaksg itt abban merl ki, hogy ugyanolyan nvvel hvhatjuk meg klnbz objektumok hasonl szerepet ellt tagfggvnyeit. Pldnkban a displayFullName tagfggvnyt mind a Person, mind az Employee objektumokkal kapcsolatban hasznlhattuk. Br az rtkadsnl volt egy kis zavar a tpusok kztt, a rendszer a megfelel ponton mindig a megfelel osztly adott nev tagfggvnyt hvta meg. Soha nem kellett azzal bajldnunk, hogy megmondjuk, mikor melyik tagfggvnyre gondolunk.
105
C# Amit a C# tudni rdemes! helyeken. Ez pedig a displayFullName tagfggvnyekkel kapcsolatban azt jelenti, hogy azok mindig a megfelel adatot fogjk megjelenteni. Egy szrmaztatott osztlynak felttlenl jeleznie kell az override kulcsszval, ha fellbrl egy virtulis tagfggvnyt. Nzznk erre is egy pldt: 3.43 Virtulis tagfggvnyek hasznlata
using System; class Person { protected string firstName; protected string lastName; public Person() { } public Person(string fn, string ln) { firstName = fn; lastName = ln; } public virtual void displayFullName() { Console.WriteLine("{0} {1}", firstName, lastName); }
class Employee : Person { public ushort hireYear; public Employee() : base() { } public Employee(string fn, string ln, ushort hy) : base(fn, ln) { hireYear = hy; } public override void displayFullName() { Console.WriteLine("Employee: {0} {1}", firstName, lastName); } } class Contractor : Person { public string company; public Contractor() : base() { }
106
class NameApp { public static void Main() { Person Brad = new Person("Bradley", "Jones"); Person me = new Employee("Bradley", "Jones", 1983); Person worker = new Contractor("Carolyn", "Curry", "UStorIt"); Brad.displayFullName(); me.displayFullName(); worker.displayFullName();
} }
Lthat, hogy a Person osztly displayFullName tagfggvnyt most virtulisknt (virtual) vezettk be. Ez teht azt jelzi a rendszernek, hogy ha menet kzben egy Person tpus objektumnak egy, a Person osztlybl szrmaztatott msik osztlyba tartoz objektum tartalmt adjuk rtkl, akkor az adott objektummal kapcsolatban e szrmaztatott osztly megfelel nev tagfggvnyt akarjuk hasznlni. A msik jelents vltozst az Employee osztlyon bell ltjuk, ahol is a displayFullName tagfggvnynl nem a new kulcsszt hasznltuk, hanem az override kulcsszt. Ez azt jelzi, hogy az Employee tpus valamennyi adatval kapcsolatban a displayFullName tagfggvnynek ezt a vltozatt akarjuk majd hasznlni.
C# Amit a C# tudni rdemes! A tagfggvnyek automatikus fellbrlst gy knyszerthetjk ki, hogy az alaposztly megfelel tagfggvnyt elvontknt adjuk meg. Ehhez a deklarciban az abstract kulcsszt kell hasznlnunk. Az elvont tagfggvny olyan tagfggvny, amelynek egyltaln nincs trzse, csak deklarcija. Az ilyen tagfggvnyek kifejezetten azzal a cllal kszlnek, hogy a szrmaztatott osztlyok fellbrljk a jelen esetben megvalstsk ket. Ha brmilyen tagfggvnyt elvontknt vezetnk be, akkor az egsz osztlyt is ezzel a jelzvel kell elltnunk. Az elvont osztlyok hasznlatt a kvetkez plda szemllteti, az Employee s a Contractor valamint a Person osztlyok segtsgvel: 3.44. Elvont osztlyok hasznlata
using System; abstract class Person { protected string firstName; protected string lastName; public Person() { } public Person(string fn, string ln) { firstName = fn; lastName = ln; } public abstract void displayFullName(); } class Employee : Person { public ushort hireYear; public Employee() : base() { } public Employee(string fn, string ln, ushort hy) : base(fn, ln) { hireYear = hy; } public override void displayFullName() { Console.WriteLine("Employee: {0} {1}", firstName, lastName); }
108
Fontos megjegyezni, hogy elvont osztlyt nem hasznlhatunk objektumok ksztsre. Ha teht az alkalmazsosztlyban megprblnnk egy Person tpus Brad nev objektumot ltrehozni, hibazenetet fogunk kapni. Teht a kvetkez kdsor hibt jelezne: Person Brad = new Person("Bradley", "Jones"); Arrl, hogy az elvont alaposztly abstract-knt bevezetett tagfggvnyei a megfelel mdon legyenek fellbrlva, maga a fordtprogram gondoskodik.
Osztlyok lezrsa
Az elvont osztlyokat eleve azzal a cllal hozzuk ltre, hogy azokbl ms osztlyok szrmaztathatk legyenek. De mi van akkor, ha kifejezetten meg akarjuk gtolni, hogy egy ltalunk ltrehozott osztlybl msok is szrmaztassanak? Mi van, ha le akarjuk zrni ezt az osztlyt, megakadlyozva az ltala nyjtott szolgltatsok brminem kiegsztst? A C# nyelvben erre a clra a sealed kulcssz szolgl. Ha egy osztly deklarcijban a sealed jelz szerepel, az megakadlyozza, hogy brmely ms osztly rkljn tle. Nzznk erre egy igen egyszer pldt: 3.45 Egy lezrt osztly
using System; sealed public class number { private float pi;
109
} //public class numbers : number //{ // public float myVal = 123.456F; //} class myApp { public static void Main() { number myNumbers = new number(); Console.WriteLine("PI = {0}", myNumbers.PI); // numbers moreNumbers = new numbers(); // Console.WriteLine("PI = {0}", moreNumbers.PI); // Console.WriteLine("myVal = {0}", moreNumbers.myVal); } }
Ha beiktatjuk a kdban a megjegyzsek kz tett sorokat is, akkor a fordtprogram hibazenettel adja tudtunkra, hogy egy lezrt osztlybl prbltunk ltrehozni egy msik osztlyt, ami pedig nem megengedett, ha a sealed kulcsszval vezetnk be egy osztlyt. Ha egy, a sealed jelzvel elltott osztlyban egy adattagot protected-knt prblunk bevezetni, figyelmeztet zenetet kapunk a fordttl. Itt nyilvn csak a private jelz hasznlatnak van rtelme, hiszen ettl az osztlytl gysem fog senki rklni.
Emlkezznk r, hogy a C# nyelvben minden, mg a literlok is objektumok, s minden objektum az Object osztlybl szrmazik. Ez pedig azt jelenti, hogy egy literlis rtk, pldul a 123 is objektum, mgpedig az Object osztlybl levezetett tpussal rendelkez objektum. Ebbl pedig kvetkezik, hogy az Object osztlytl rklt ToString tagfggvny segtsgvel az 123 objektumot karakterlncc alakthatjuk. Nem tl meglep mdon az eredmny 123 karakterlnc lesz. Az is lthat, hogy az 123 tpusa System.Int32, ami egyben nem ms, mint a .NET keretrendszerben a szabvnyos int tpus szinonimja.
Becsomagols s kicsomagols
Most hogy mr viszonylag tfog kpnk van az alap- s szrmaztatott osztlyok kapcsolatairl, ideje megismerkednnk mg kt fogalommal, a becsomagolssal (boxing) s a kicsomagolssal (unboxing). Korbban azt lltottuk, hogy a C# nyelvben minden objektum. Nos ez nem teljesen igaz. A helyes llts inkbb gy hangzik, hogy mindent kezelhetnk objektumknt. Mr tudjuk hogy az rtk szerinti adattpusok msknt troldnak, mint a hivatkozsi adattpusok, s hogy az objektumok valamennyien az utbbi kategriba tartoznak. Ugyanakkor az elz feladatban egy literlrtket kezdtnk el objektumknt kezelni. Mirt tehettk meg ezt?A C# valjban lehetsget ad arra, hogy egy rtk szerinti tpust objektumm, vagyis hivatkozsi tpuss alaktsunk.
111
C# Amit a C# tudni rdemes! Becsomagolsnak (boxing) nevezzk azt a mveletet, amelyben egy rtk szerinti tpust objektumm, vagyis hivatkozsi tpuss alaktunk. A kicsomagols (unboxing) az ellenkez irny talakts. Amikor egy rtket kicsomagolunk, akkor olyan adattpusban kell elhelyeznnk, ami a trolt adatnak megfelel. A kicsomagolshoz az szksges, hogy egy objektumot kifejezetten rtk szerinti tpuss alaktsunk. Ezt knyszertett tpustalaktssal (cast) tehetjk meg. A kvetkez kdrszlet egy ilyen feladatot valst meg: 3.47 Becsomagols s kicsomagols
using System; class myApp { public static void Main() { float val = 3.14F; object boxed = val; float unboxed = (float) boxed; Console.WriteLine("val: {0}", val); Console.WriteLine("boxed: {0}", boxed); Console.WriteLine("unboxed: {0}", unboxed); Console.WriteLine("\nTypes..."); Console.WriteLine("val: {0}", val.GetType()); Console.WriteLine("boxed: {0}", boxed.GetType()); Console.WriteLine("unboxed: {0}", unboxed.GetType()); } }
Az is kulcssz hasznlata
Nha elfordul, hogy egy sszehasonltssal szeretnnk meggyzdni rla, hogy egy bizonyos objektumnak azonos-e a tpusa egy msikkal. Az ilyen mveletek elvgzst knnyti meg a C# is kulcsszava. Az is kulcsszt arra hasznljuk, hogy segtsgvel eldntsk, egy objektum tpusa azonos-e az sszehasonltsban megadott msik tpussal. Hasznlatnak formja a kvetkez: (kifejezs is tpus) Itt a kifejezs egy hivatkozsi tpuss rtkeldik ki, a tpus pedig rvnyes tpus. A tpus teht ltalban egy osztly tpusa lesz. Ha a kifejezs megfelel a tpus-ban megadott tpusnak, akkor a kifejezs rtke true (igaz), ellenkez esetben a visszatrsi rtk false (hamis). Nzznk egy pldt az is hasznlatra:
112
public Person(string n)
public virtual void displayFullName() { Console.WriteLine("Name: {0}", Name); } } class Employee : Person { public Employee() : base()
{ } { }
public override void displayFullName() { Console.WriteLine("Employee: {0}", Name); } } class IsApp { public static void Main() { Person pers = new Person(); Object emp = new Employee(); string str = "String"; if( pers is Person ) Console.WriteLine("pers is a Person"); else Console.WriteLine("pers is NOT a Person"); if( pers is Object ) Console.WriteLine("pers is an Object"); else Console.WriteLine("pers is NOT an Object"); if( pers is Employee ) Console.WriteLine("pers is an Employee"); else Console.WriteLine("pers is NOT an Employee"); if( emp is Person ) Console.WriteLine("emp is a Person"); else Console.WriteLine("emp is NOT a Person"); if( str is Person ) Console.WriteLine("str is a Person");
113
Ha lefordtjuk ezt a kdot, valsznleg kapunk majd nhny figyelmeztet zenetet. A fordtprogram szmra a megadott sszehasonltsok egy rsze magtl rtetd lesz, ezrt jelzi, hogy ezek biztosan mindig igazz fognak kirtkeldni. Az is kulcssz kivl eszkz arra, hogy segtsgvel a program futsa kzben ellenrizznk egy hivatkozsi vltoz tpust.
Az as kulcssz hasznlata
Az as hasonlan mkdik, mint egy tpustalakts. Feladata, hogy egy adott tpus objektumot egy msik tpus objektumm alaktson. Ennek az talaktsnak termszetesen megvannak a maga korltai. A cltpusnak valamilyen szinten meg kell felelnie a kiindulsi tpusnak. Emlkezznk r, hogy a tpustalakts tulajdonkppen egyfajta knyszert eszkz, amellyel egy adott objektumra msik tpust knyszertnk r. Az as kulcssz hasznlatnak formja a kvetkez: kifejezs as AdatTpus Itt a kifejezs egy hivatkozsi tpuss rtkeldik ki, az AdatTpus pedig ilyen tpus. Egy ehhez hasonl tpustalakts a kvetkezkppen nzne ki: (AdatTpus) kifejezs Br az as kulcssz hasznlata valban nagyon hasonlt a knyszertett tpustalaktshoz, a vgeredmny a kt esetben nem azonos. Ha a tpustalakts sorn valamilyen hiba lp fel pldul, mert egy karakterlncot akarunk szmm alaktani - kivtel keletkezik. Ha viszont az as hasznlata kzben lp fel ilyen hiba, akkor a kifejezs a null rtket kapja, s a hiba ellenre megadott tpuss (AdatTpus) alakul. Ekzben kivtel nem keletkezik. Mindez azt jelenti, hogy bizonyos helyzetekben az as kulcsszval biztonsgosabban hajthatunk vgre tpustalaktst, mint egybknt.
114
115
Console.Write("\nEnter \'c\' for Contractor, \'e\' for Employee then press ENTER: "); buffer = Console.ReadLine(); } while (buffer == ""); if ( buffer[0] == 'c' || buffer[0] == 'C' ) { Console.Write("\nEnter the contractor\'s name: "); buffer = Console.ReadLine(); Contractor contr = new Contractor(buffer); myCompany[ctr] = contr as Person; } else if ( buffer[0] == 'e' || buffer[0] == 'E' ) { Console.Write("\nEnter the employee\'s name: "); buffer = Console.ReadLine(); Employee emp = new Employee(buffer); myCompany[ctr] = emp as Person; } else { Person pers = new Person("Not an Employee or Contractor"); myCompany[ctr] = pers; } ctr++; } while ( ctr < 5 ); Console.WriteLine( "\n\n\n==========================="); for( ctr = 0; ctr < 5; ctr++ ) { if( myCompany[ctr] is Employee ) { Console.WriteLine("Employee: {0}", myCompany[ctr].Name); } else if( myCompany[ctr] is Contractor ) { Console.WriteLine("Contractor: {0}", myCompany[ctr].Name); } else { Console.WriteLine("Person: {0}", myCompany[ctr].Name); } } Console.WriteLine( "===========================");
do {
} }
116
C# Amit a C# tudni rdemes! Amint a plda is mutatja, az is s az as kulcsszavak segtsgvel klnbz tpus objektumokat trolhatunk ugyanabban a tmbben, feltve, hogy azok kzs alaptpussal rendelkeznek. Mivel a C# nyelvben valamennyi objektum kzs se az Object tpus, ez a trkk tulajdonkppen minden esetben megoldhat.
Az informci formzsa
Amikor valamilyen informcit akarunk megjelenteni, a leggyakrabban clszer azt karakterlncc alaktani. Amikor azt korbban lttuk, a Console osztly Write s WriteLine tagfggvnyei ilyen karakterlncokat tudnak megjelenteni. A .NET keretrendszernek ezeken kvl szmos egyb tagfggvnye s formtumlerja van, amelyeket szintn karakterlncokkal kapcsolatban hasznlhatunk. A formtumler vagy formz karakter olyan jel, amely az informci formzsnak szksgessgt rja el. A formz karaktereket brmilyen karakterlnccal kapcsolatban hasznlhatjuk. A kvetkezkben e jelek kzl tekintnk t nhnyat. me az rintett tpusok ttekint listja: Szabvnyos szmformtumok Pnznemek Exponencilis szmok Egyedi szmformtumok Dtumok s idpontok Felsorolsok
A formz karaktereket tbbfle mdon hasznlhatjuk. A legegyszerbb taln a Write s a WriteLine tagfggvnyekben val szerepeltetsk, ahol a kiegszt formzs mikntjt adhatjuk meg segtsgkkel. Jelek segtsgvel trtn formzst a ToString tagfggvny meghvsakor is hasznlhatunk. Mr tudjuk, hogy a ToString tagfggvny az ltalnos Object osztly rsze. Mivel minden objektum se az Object osztly, a ToString tagfggvny is brmely osztlyban hozzfrhet. Az olyan osztlyok esetben, mint pldul az Int32, a ToString tagfggvnynek formzsra vonatkoz informcit is megadhatunk. Ha pldul a var egy egsz tpus vltoz, amely a 123-as szmot tartalmazza, akkor a pnznemek formzsra szolgl C jel megadsval a var.ToString("C"); utasts kimenete a kvetkez lesz: $123.00
117
C# Amit a C# tudni rdemes! A formz karakterek hasznlatnak harmadik lehetsge a string adattpus kezelsvel kapcsolatos. A string osztlynak van egy Format nev statikus tagfggvnye. ppen azrt, mert ez a tagfggvny statikus, hasznlhat egyszeren az osztly nevnek megadsval is, a string.Format formban. A tagfggvny hasznlatnak formja egybknt megegyezik azzal, amit a Console osztly kpernyt kezel tagfggvnyei hasznlnak: string KarakterLnc = string.Format( "formz_karakterlnc",rtk(ek)); Itt a KarakterLnc az az j karakterlnc, amely a formzott kimenetet tartalmazza. A formz_karakterlnc nevnek megfelelen a formzs mikntjt ler jelekbl alkotott karakterlnc. Ezek a jelek termszetesen megegyeznek a Write s WriteLine tagfggvnyekkel kapcsolatban hasznlhatkkal. Az rtk(ek) azokat az rtkeket tartalmazza, amelyeknek formzott alakban kell majd megjelennik a kimen karakterlncban. A C karakter a pnzsszegek formzsnak lersra hasznlt formz karakter. Amint azt korbban emltettk, ezt a jelet a ToString tagfggvnynek ketts idzjelek kztt bemen paramterknt kell megadnunk. Ha a formzst eleve karakterlncon akarjuk vgrehajtani, a formz karaktereket helyrzknt (placeholder) kell hasznlnunk. Ennek legltalnosabb formja a kvetkez: {hldr:X#} Itt a hldr a helyrz szm, amely a vltoz beillesztsnek helyt mutatja, az X pedig az a formzst ler jel, amely az illet vltozra vonatkozik. Ha a krdses szmot pnzsszegknt akarjuk megjelenteni, az X a C jel lenne. A # nem ktelez jel, s a megjelentene kvnt szmjegyek szmt adja meg. A kettskereszt jelentse a klnbz formzsokkal kapcsolatban klnbz lehet. Pnzsszeg formzsakor a tizedesjegyek szmt adja.
Szmok formzsa
Szmrtkek formzsra szmos klnbz formz karakter hasznlhat. Ezekrl a kvetkez tblzat ad sszefoglalst: A szmrtkek formzsra hasznlhat formz karakterek Formz karakter Lers Alaprtelmezett formtum C vagy c Pnzsszeg $xx,xxx,xx ($xx,xxx,xx) D vagy d Decimlis szm xxxxxxx -xxxxxxx E vagy e Hatvnyalak x.xxxxxxE+xxx x.xxxxxxe+xxx -x.xxxxxxE+xxx Ksztette: Zstr Csaba III. ves informatikus hallgat 118 Plda kimenetre $12,345,67 ($12,345,67) 1234567 -1234567 1.234567E+123 1.234567e+123 -1.23456E+123
C# Amit a C# tudni rdemes! -x.xxxxxxe+xxx x.xxxxxxE-xxx x.xxxxxxe-xxx -x.xxxxxxE-xxx -x.xxxxxxe-xxx xxxxxx.xx -xxxxxx.xx xx,xxx.xx 12d687 -1.23456e+123 1.23456E-123 1.23456e-123 -1.234567E+123 -1.23456e+123 123456.78 -123456.78 12,345.67 12D687
Vltoz (a legtmrebb formtumot hasznlja) Megrzi a pontossgot, ha a szmokat alaktunk karakterlncc, majd vissza
119
A dtum s id formzsa
A dtumot s az idt szintn megjelenthetjk formzott alakban. A formz karakterek kztt szmos olyat is tallunk, amelyek segtsgvel a ht napjaitl kezdve a teljes dtumot s a pontos idt tartalmaz idblyegig mindent megformzhatunk. Mieltt azonban rtrnnk ezek bemutatsra, meg kell tanulnunk, hogyan krdezhetjk le programjainkbl az aktulis dtumot s a pontos idt.
A dtum s id lekrdezse
A C# nyelv s a .NET keretrendszer az id s a dtum kezelsre s trolsra egy egsz osztlyt bocst rendelkezsnkre. Ez a DateTime nev osztly, amely a System nvtr eleme. Ez az osztly az aktulis dtumot s a pontos idt egyarnt trolja. A DateTime osztlynak szmos olyan tulajdonsga s tagfggvnye van, amelyeket munknk sorn minden bizonnyal hasznosnak fogunk tallni. Ezenkvl az osztlynak van nhny statikus tagja is. Ezek kzl a kt leggyakrabban hasznlt valsznleg a Now s a Today. Nevnek megfelelen a Now tag a meghvs pillanatban rvnyes dtumot s idt tartalmazza, a Today pedig az aktulis dtumot. Mivel mint emltettk ezek statikus tagok, az osztly nevvel, s nem az osztly tagjaival kapcsolatban hasznlhatk: DateTime.Now DateTime.Today A DateTime osztly egyb tagjainak s tagfggvnyeinek lerst a fejlesztrendszerhez kapott dokumentciban tallhatjuk meg. Nhnyat kzlk ugyanakkor a rvid lersukkal egytt itt is felsorolunk:
120
C# Amit a C# tudni rdemes! Date Month Day Year DayOfWeek DayOfYear TimeOfDay Hour Minute Second Millisecond Ticks A DateTime objektum dtummal kapcsolatos rszt adja vissza. A DateTime objektumban trolt hnap rtkt adja vissza. A DateTime objektumban trolt nap rtkt adja vissza (a szmformban megadott dtum nap rtke.) A DateTime objektumban trolt v rtkt adja vissza. Azt adja vissza, hogy a DateTime objektumban trolt idpont az adott ht hnyadik napjnak felel meg. Azt adja vissza, hogy a DateTime objektumban trolt idpont az adott v hnyadik napjnak felel meg. A DateTime objektumban trolt idpont rtkt adja vissza. A DateTime objektumban troltra rtkt adja vissza. A DateTime objektumban trolt percek rtkt adja vissza. A DateTime objektumban trolt msodpercek rtkt adja vissza. A DateTime objektumban trolt ezredmsodpercek rtkt adja vissza. Azt az rtket adja vissza, ami megmutatja, hogy a DateTime objektumban trolt rtk hnyszorosa egy 100 nanomsodperc hosszsg ratsnek.
A dtum s id formzsa
Szmos olyan formz karakter ltezik, amelyek a dtum s id formzsra hasznlhatk. Ezek segtsgvel a lehet legrvidebbtl kezdve a legrszletesebb formtumig mindenfle alakban megjelenthetjk az idt. Ezzel kapcsolatos formz karaktereket a kvetkez tblzat sorolja fel: A dtum s id formzsra hasznlhat karakterek Formz Lers Alaprtelmezett forma d D f F g G M vagy m R vagy r s t T u Rvid dtum Hossz dtum Teljes dtum s rvid id Teljes dtum s teljes id Rvid dtum s rvid id Rvid dtum s hossz id Hnap s nap RFC1123 Rendezhet (sortable) Rvid id Hossz id Rendezhet mm/dd/yyyy nap, hnap dd, yyyy nap, hnap dd, yyyy hh:mm AM/PM nap, hnap dd, yyyy hh:mm:ss AM/PM mm/dd/yyyy HH:mm mm/dd/yyyy HH:mm:ss AM/PM hnap nap ddd, dd hnap yyyy hh:mm:ss GMT yyyy-mm-dd hh:mm:ss hh:mm: AM/PM hh:mm:ss AM/PM yyyy-mm-dd hh:mm:ss 121 Plda a keletkez kimenetre 5/6/2001 Sunday, May 06, 2001 Sunday, May 06, 2001 13:30 PM Sunday, May 06, 2001 13:30:55 PM 6/5/2001 13:30 PM 6/5/2001 13:30:55 PM May 06 Sun, 06 May 2001 13:30:55 GMT 2001-05-06 T13:30:55 13:30 PM 13:30:55 PM 2001-05-06 13:30:55Z
} }
} }
Console.WriteLine("\nUsing yourPet: "); Console.WriteLine("d: {0:d}", yourPet ); Console.WriteLine("D: {0:D}", yourPet ); Console.WriteLine("g: {0:g}", yourPet ); Console.WriteLine("G: {0:G}", yourPet ); Console.WriteLine("x: {0:x}", yourPet ); Console.WriteLine("X: {0:X}", yourPet );
C# Amit a C# tudni rdemes! Tudva, hogy a karakterlncok nem mdosthatk, most legtbben valsznleg gy gondoljk, hogy ez igen ersen korltozza a tpus hasznlhatsgt. Ez rszben rthet is, hiszen nyilvn nehezen lehet elkpzelni, miknt mkdhetnek a karakterlncokat kezel tagfggvnyek s tulajdonsgok, ha a tartalom rinthetetlen. A trkk az, hogy minden tagfggvny, amely mdostan a karakterlnc tartalmt, egy j karakterlnc objektumot hoz ltre. Elfordulhat persze, hogy tnyleg szksgnk van a karakterlncok tartalmnak mdostsra. Erre a clra a C# egy msik osztlyt, a StringBuilder-t bocstja rendelkezsnkre. A karakterlncokat szoks nem vltoz (immutable) elemeknek is nevezni, ami ugyanazt jelenti, amirl eddig is sz volt: nem lehet a tartalmukat mdostani.
A karakterlncokkal kapcsolatban hasznlhat legfontosabb tagfggvnyek Tagfggvny Lers A String / string osztllyal kapcsolatos statikus tagfggvnyek Compare sszehasonltja kt karakterlnc tartalmt CompareOrdinal gy hasonltja ssze kt karakterlnc tartalmt, hogy kzben nem foglalkozik a nyelv vagy egyb nemzetkzi belltsok okozta eltrsekkel. Concat Kt vagy tbb karakterlncot egyetlen kimen karakterlncc fz ssze. Copy Msolatot kszt egy mr meglv karakterlncrl. Equals sszehasonltja kt karakterlnc tartalmt, s megllaptja, hogy azok azonosak-e. Ha igen, visszatrsi rtke true ellenkez esetben false lesz. Format A formzshoz hasznlt vezrl karaktereket az ltalunk jellt karakterlncokkal helyettesti. Join Kt vagy tbb karakterlncot egyest. Az eredetileg nll szakaszok kztt egy, a felhasznl ltal meghatrozott elvlaszt karakterlncot helyez el. A pldnyokkal kapcsolatban hasznlhat tagfggvnyek s tulajdonsgok Char A karakterlnc megadott helyen tallhat karaktert adja vissza. Clone A trolt karakterlnc msolatt adja vissza. CompareTo A krdses karakterlnc tartalmt egy msik karakterlnc tartalmval hasonltja ssze. Negatv szmot ad vissza, ha a krdses karakterlnc kisebb, mint az, amihez hasonltjuk; nullt, ha a kt karakterlnc egyenl; s pozitv szmot, ha az els karakterlnc a nagyobb. CopyTo tmsolja a karakterlnc egy rszt vagy a teljes karakterlncot egy msik karakterlncba vagy karaktertmbbe. Ksztette: Zstr Csaba III. ves informatikus hallgat 124
C# Amit a C# tudni rdemes! EndsWith Megllaptja, hogy a krdses karakterlnc vge azonos-e egy msik karakterlnccal. Ha igen, visszatrsi rtke true, ellenkez esetben false lesz. sszehasonlt kt karakterlncot, s megllaptja, hogy azonos rtket tartalmaznak-e. Ha igen, visszatrsi rtke true, ellenkez esetben false lesz. Egy karakter vagy karakterlnc els elfordulsnak helyt adja vissza az adott karakterlncban. -1-gyel tr vissza, ha a keresett szakasz egyltaln nem szerepel. Beilleszt egy karakterlncot a megadott karakterlncba. Az eredmnyt egy j karakterlncban adja vissza. Egy karakter vagy karakterlnc utols elfordulsnak helyt adja vissza. Visszatrsi rtke -1, ha a keresett rsz egyltaln nem fordul el. Az adott karakterlnc hosszt adja vissza. (Karakterek szmt) A karakterlnc tartalmt jobbra igaztja, a fennmarad res helyet pedig egy megadott karakterrel, vagy szkzzel tlti. A karakterlnc tartalmt balra igaztja, a fennmarad res helyet pedig egy megadott karakterrel, vagy szkzzel tlti. Lers Megadott szm karaktert trl a karakterlnc egy megadott helytl kezdden. A Join tagfggvny ellentte. A krdses karakterlncot kisebb karakterlncokra trdeli a megadott mezelvlasztk mentn. Megllaptja, hogy a krdses karakterlnc egy adott karakterrel vagy karakterlnccal kezddik-e. Ha igen, visszatrsi rtke true, ellenkez esetben false lesz. Ha a keresett karakter null, a visszatrsi rtk akkor is true lesz. Az eredeti karakterlnc egy rszhalmazt adja vissza a megadott helytl kezdden. A krdses karakterlnc tartalmt a kimenetknt megadott char tpus tmbbe msolja. Az adott karakterlnc tartalmt csupa kisbetvel megjelentve adja vissza. Az adott karakterlnc tartalmt csupa nagybetvel megjelentve adja vissza. Eltvoltja a megadott karakterlncot a krdses karakterlnc elejrl s vgrl. Eltvolt egy megadott karakterlncot a krdses karakterlnc vgrl. Eltvolt egy megadott karakterlncot a krdses karakterlnc elejrl.
Equals
IndexOf Insert LastIndexOf Length PadLeft PadRigth Tagfggvny Remove Split sWith
125
Karakterlncok ptse
A System.Text nvtr tartalmaz egy StringBuilder nev osztlyt, amely lehetv teszi olyan karakterlncok felptst, amelyek tartalma mdosthat. A StringBuilder osztly segtsgvel ltrehozott objektumok mkdsket tekintve rendkvl hasonltnak a kznsges karakterlncokhoz. Az eltrs tulajdonkppen csak annyi, hogy eme osztly tagfggvnyei kzvetlenl az objektumban trolt rtket tudjk mdostani. A StringBuilder osztly tagfggvnyei s tulajdonsgai Tagfggvny Lers Append Hozzfzi a megadott objektumot az aktulis StringBuilder objektumhoz. AppendFormat Vezrl karakterekkel megadott formtum alapjn objektumokat illeszt be egy karakterlncba. Capacity Belltja vagy lekrdezi a krdses objektumban trolhat karakterek szmt. Ezt az rtket menet kzben is nvelhetjk, egszen a MaxCapacity rtkig. Chars Belltja vagy lekrdezi az adott pozcin tallhat karakter rtkt. EnsureCapacity Gondoskodik rla, hogy az adott StringBuilder objektum kapacitsa legalbb a megadott rtk legyen. Ha tadunk egy rtket az EnsureCapacity tagfggvnynek, akkor erre az rtkre fogja lltani a Capacity rtkt. Ha a MaxCapacity rtke kisebb annl, mint amit megadtunk, kivtel keletkezik. Ksztette: Zstr Csaba III. ves informatikus hallgat 126
C# Amit a C# tudni rdemes! Equals Insert Length Megvizsglja, hogy a krdses StringBuilder objektum tartalma azonos-e a megadott rtkkel. Beilleszt egy objektumot a StringBuilder objektum adott pontjra. Belltja vagy lekrdezi a StringBuilder objektumban pillanatnyilag trolt karakterlnc hosszt. Ez az rtk nem lehet nagyobb, mint az objektum Capacity tulajdonsgban trolt. Ha a pillanatnyi rtk nagyobb, mint a belltani kvnt hossz, a rendszer csonkolja a trolt rtket. A StringBuilder objektum legnagyobb kapacitst krdezi le. A megadott helytl kezdden megadott szm karaktert eltvolt a krdses StringBuilder objektumbl. Az adott karakter valamennyi elfordulst lecserli egy msik karakterre. A StringBuilder objektumot kznsges String objektumm alaktja
A StringBuilder osztlyt pontosan ugyangy hasznlhatjuk, mint az sszes tbbit. Nzznk erre egy pldt: 3.53 A StrinfBuilder osztly hasznlata
using System; using System.Text; class buildName { public static void Main() { StringBuilder name = new StringBuilder(); string buffer; int marker = 0; Console.Write("\nEnter your first name: "); buffer = Console.ReadLine(); if ( buffer != null ) { name.Append(buffer); marker = name.Length; } Console.Write("\nEnter your last name: "); buffer = Console.ReadLine(); if ( buffer != null ) { name.Append(" "); name.Append(buffer); } Console.Write("\nEnter your middle name: "); buffer = Console.ReadLine();
127
class ReadIt { public static void Main() { StringBuilder Input = new StringBuilder(); int ival; char ch = ' '; Console.WriteLine("Enter text. When done, press CTRL+Z:"); while ( true ) { ival = Console.Read();
128
} }
129
C# Amit a C# tudni rdemes! az sem ritka, hogy teljesen ms adattpuss kell alaktanunk, mieltt a program feldolgozhatn. A System nvtrben tallhat Convert osztly kifejezetten az ilyen adat-talaktsokra szolgl. A Convert lezrt osztly, amely szmos statikus tagfggvnyt tartalmaz. Ezek mindegyike valamilyen adattpusok kzti talaktst valst meg. Mivel minden tagfggvnye statikus, a kvetkez minta szerint hasznlhatjuk ket: Convert.tagfggvny(eredeti_rtk); Nagyon fontos szben tartani, hogy ez az osztly az alaposztlyok knyvtrnak rsze, vagyis ms programozsi nyelvekbl is hasznlhatjuk. C# adattpusok helyett a Convert osztly .NET adattpusokat llt el. Tpusok kzti talaktst vgz tagfggvnyek Tagfggvny Miv alakt ToBoolean Logikai rtkk ToByte 8 bites eljel nlkli egssz ToChar Unicode karakterr ToDateTime DateTime tpuss ToDecimal Tzes szmrendszer rtkk ToDouble Ktszeres pontossg szmm Tpusok kzti talaktst vgz tagfggvnyek (folytats) Tagfggvny Miv alakt ToInt16 16 bites eljeles egssz ToInt32 32 bites eljeles egssz ToInt64 64 bites eljeles egssz ToSByte 8 bites eljeles egssz ToSingle Egyszeres pontossg lebegpontos szmm ToString Karakterlncc ToUInt16 16 bites eljel nlkli egssz ToUInt32 32 bites eljel nlkli egssz ToUInt64 64 bites eljel nlkli egssz 3.56 A Convert osztly egyik tagfggvnynek hasznlata
using System; using System.Text; class Converts { public static void Main() { string buff; int age; Console.Write("Enter your age: "); buff = Console.ReadLine();
130
} }
131
C# Amit a C# tudni rdemes! hatroz meg. A fellet teht ersen hasonlt egy elvont osztlyhoz, s ezzel egytt a fent bemutatott osztlyhoz. Ami azt illeti, a hasonlsg olyan alapvet, hogy a cShape osztlyt pillanatok alatt fellett alakthatjuk. Ehhez nem kell mst tennnk, mint elhagyni az abstract mdostkat, a class kulcsszt pedig lecserlni interface-re: public interface ISharpe { long Area(); long Circumference(); int sides(); }
A felletek hasznlata
Br els ltsra egy fellet nem tnhet olyan hatkonynak s jl hasznlhatnak, mint egy hasonl osztly, nagy elnye, hogy a felletet olyan helyeken is hasznlhatjuk, ahol osztlyt nem. Egy osztly mindssze egyetlen msik osztlytl rklhet, viszont tbb felletet is megvalsthat. Az is lnyeges szempont, hogy a kznsges struktrk nem rklhetnek sem ms struktrktl, sem osztlyoktl. Felleteket ugyanakkor ezek is megvalsthatnak. A C#, szemben a C++-szal s ms objektumkzpont nyelvekkel, nem tmogatja a tbbszrs rkldst, vagyis azt, hogy egy osztly tbb ms osztlytl rkljn. Ezt a lehetsget a nyelv tervezi termszetesen szndkosan hagytk ki, mgpedig az ltala okozott problmk, s a keletkez logikai szerkezetek nemkvnatos sszetettsge miatt. A C# a tbbszrs rkls elnyeit ugyanakkor gy valstja meg, hogy lehetv teszi tbb fellet egyidej megvalstst.
132
Felletek meghatrozsa
sszefoglalva az eddig elhangzottakat, a fellet tulajdonkppen annak lersa, hogy minek kell az t megvalst osztlyban szerepelnie. A felletek meghatrozsnak alapvet szerkezete a kvetkez: interface INv { tagok; } A tagfggvnyeket a hatkrkre vonatkoz brmilyen mdost nlkl adhatjuk meg. Amint korbban emltettk, a felleteken bell gyis valamennyi tagfggvny nyilvnos. Ezenkvl nem adhatunk meg semmifle rszletet a tagfggvnyek trzsvel kapcsolatban sem. A legtbb esetben teht csak a tagfggvnyek visszatrsi tpusa s a neve szerepel a meghatrozsban, amelyeket egy zrjelpros s egy pontosvessz kvet: interface IFormatForPrint { void FormatForPrint(PrintClass PrinterType); int NotifyPrintComplete(); }
133
C# Amit a C# tudni rdemes! Az IShape fellet meghatrozsa a kvetkezkppen fest: public interface IShape { double Area(); double Circumference(); int Sides(); } Azzal, hogy ezt a felletet beemeljk egy osztlyba, automatikusan egyetrtnk bizonyos jtkszablyokkal. Elszr is gondoskodni fogunk rla, hogy a krdses osztly tnylegesen megvalstsa a Circle s Square tagfggvnyeket, mgpedig abban a formban, ami a fellet meghatrozsban szerepel. Jelen esetben ez azt jelenti, hogy valamennyi osztlynak tartalmazni kell majd az Area, Sides s Circumference tagfggvnyeket. A leglnyegesebb ebben az egszben, hogy mindkt osztly garantltan az IShape felletben megadott jellegzetessgekkel fog rendelkezni. Ennek jtkony hatst magban a programban lthatjuk: 3.57 Az IShape fellet hasznlata
using System; public interface IShape { double Area(); double Circumference(); int Sides(); } public class Circle : IShape { public int x; public int y; public double radius; private const float PI = 3.14159F; public double Area() { double theArea; theArea = PI * radius * radius; return theArea; } public double Circumference() { return ((double) (2 * PI * radius)); } public int Sides() { return 1; } public Circle() { x = 0;
134
public class Square : IShape { public int side; public double Area() { return ((double) (side * side)); } public double Circumference() { return ((double) (4 * side)); } public int Sides() { return 4; } public Square() { side = 0; } } public class Shape { public static void Main() { Circle myCircle = new Circle(); myCircle.radius = 5; Square mySquare = new Square(); mySquare.side = 4; Console.WriteLine("Displaying Circle information:"); displayInfo(myCircle); Console.WriteLine("\nDisplaying Square information:"); displayInfo(mySquare);
static void displayInfo( IShape myShape ) { Console.WriteLine("Area: {0}", myShape.Area()); Console.WriteLine("Sides: {0}", myShape.Sides()); Console.WriteLine("Circumference: {0}", myShape.Circumference()); }
Ezen a ponton felmerl egy krds. Van-e a displayInfo tagfggvnynek ktfle tlterhelt vltozata, amelyek kzl az egyik Circle, a msik Square tpus objektumot tud Ksztette: Zstr Csaba III. ves informatikus hallgat 135
C# Amit a C# tudni rdemes! fogadni? Nincs. A displayInfo tagfggvny egy IShape tpus objektumot vr bemenetknt. A sz gyakorlati rtelmben ilyen objektumtpus persze nem ltezik, viszont vannak olyan objektumtpusok, amelyek rendelkeznek az IShape felletben krlrt jellemzkkel. Ez a tagfggvny teht tbbalak, hiszen brmely objektummal kpes mkdni, amely megvalstja az IShape felletet. Ezt az teszi lehetv, hogy az IShape-ben megadott tagfggvnyekre tmaszkodik, ezek pedig valamennyi, az IShape elrsainak megfelel osztly kteles pontosan a lert formban megvalstani.
public class Square : IShape { private int InSides; public int SideLength; public double Area() { return ((double) (SideLength * SideLength)); } public int Sides { get { return InSides; } set { InSides = value; } } public Square() { Sides = 4;
136
public class Props { public static void Main() { Square mySquare = new Square(); mySquare.SideLength = 5; Console.WriteLine("\nDisplaying Square information:"); Console.WriteLine("Area: {0}", mySquare.Area()); Console.WriteLine("Sides: {0}", mySquare.Sides);
} }
Ugyanakkor rdemes megjegyezni, hogy ilyen helyeken nem felttlenl muszj mind a kettt megadni. Az is teljesen elfogadhat volna, ha a tulajdonsg csak get vagy csak set tagfggvnyekkel rendelkezne. Ugyanakkor ha a fellet meghatrozsa mindkt tagfggvnyt tartalmazza, akkor valamennyi, a felletet megvalst osztly kteles is megvalstani mindkettt.
137
C# Amit a C# tudni rdemes! Vannak persze esetek, amikor a krdses tagfggvnyt fggetlenl akarjuk megvalstani mindkt fellethez. Ebben az esetben kifejezett (explicit) felletmegvalstst kell alkalmaznunk. Ez azt jelenti, hogy a krdses, tbbszr elfordul tag megvalstsnl meg kell adni a fellet nevt is. A tagfggvny hvsakor ezen kvl a megfelel tpus-talaktsrl is gondoskodni kell, amint a kvetkez plda is mutatja: 3.60 Explicit felletmegvalsts
using System; public interface IShape { double Area(); int Sides { get; } void Display(); } public interface IShapeDisplay { void Display(); } public class Square : IShape, IShapeDisplay { private int InSides; public int SideLength; public int Sides { get { return InSides; } } public double Area() { return ((double) (SideLength * SideLength)); } public double Circumference() { return ((double) (Sides * SideLength)); } public Square() { InSides = 4; } void IShape.Display() { Console.WriteLine("\nDisplaying Square Shape\'s information:"); Console.WriteLine("Side length: {0}", this.SideLength); Console.WriteLine("Sides: {0}", this.Sides); Console.WriteLine("Area: {0}", this.Area()); } void IShapeDisplay.Display() { Console.WriteLine("\nThis method could draw the shape..."); }
139
} }
Az I3DShape fellet az rkls jtkszablyainak megfelelen tartalmazza az IShape valamennyi elemt, de lehetnek benne j elemek is. Jelen esetben a Depth nev tulajdonsg jelenti ezt a tbbletet. Az I3DShape felletet ezek utn termszetesen pontosan ugyangy hasznlhatjuk, mint brmelyik ms felletet. sszesen ngy megvalstand tagja lesz, mgpedig az Area, a Circumference, a Sides s a Depth.
C# Amit a C# tudni rdemes! 3.61 Egy fellet egyik tagjnak elrejtse egy osztly ell
using System; public interface IShape { // members left out to simplify example... int ShapeShifter( int val ); int Sides { get; set; } } public class Shape : IShape { private int InSides; public int Sides { get { return InSides; } set { InSides = value; } } int IShape.ShapeShifter( int val ) { Console.WriteLine("Shifting Shape...."); val += 1; return val; } public Shape() { Sides = 5; } } public class Hide { public static void Main() { Shape myShape = new Shape(); Console.WriteLine("My shape has been created."); Console.WriteLine("Using get accessor. Sides = {0}", myShape.Sides); myShape.Sides = myShape.ShapeShifter(myShape.Sides); // error IShape tmp = (IShape) myShape; myShape.Sides = tmp.ShapeShifter( myShape.Sides); } } Console.WriteLine("ShapeShifter called. Sides = {0}", myShape.Sides);
//
141
Ha ltrehoztunk egy indexelt, az lehetv teszi, hogy szgletes zrjelek hasznlatval ( [] ) lltsuk be, illetve krdezzk le az objektum valamelyik rtkt. Amint az a fenti pldbl is lthat, az adatTpus helyn meg kell adnunk, hogy az indexel milyen tpus adatot llt be, illetve ad vissza. A get szakaszban ezt az adattpust adjuk vissza, a set utasts lersnl pedig ezzel az adattpussal vgznk valamilyen mveletet. Akrcsak a tulajdonsgoknl s a tagfggvnyeknl, itt is hasznlhatjuk a value kulcsszt. Ez az az rtk, amit a set eljrsnak tadunk. Ennyi bevezet utn az lesz a legjobb, ha egy egyszer pldn megnzzk egy indexel mkdst: 3.62 Az indexelk hasznlata
using System; public class SpellingList { protected string[] words = new string[size]; static public int size = 10; public SpellingList()
142
public string this[int index] { get { string tmp; if( index >= 0 && index <= size-1 ) tmp = words[index]; else tmp = ""; } set { } return ( tmp );
if( index >= 0 && index <= size-1 ) words[index] = value; } } public class Indexer { public static void Main() { SpellingList myList = new SpellingList(); myList[3] myList[4] myList[5] myList[6] myList[7] = = = = = "====="; "Csaba"; "was"; "Here!"; "=====";
A kpviselk felfedezse
Ebben a szakaszban a nyelvi elemek egy egszen kifinomult csoportjrl, a kpviselkrl lesz sz. A kpvisel (delegate, megbzott) olyan hivatkozsi tpus, amely egy tagfggvnyhvs alrst adja meg. A kpviselk ezek utn kpes az ennek a hvsi formtumnak megfelel tagfggvnyhvsokat fogadni s vgrehajtani. Mr volt sz a felletekrl, hogy a fellet olyan hivatkozsi tpus, amely lerja egy osztly felptst, de maga ebbl semmit nem valst meg. A kpviselk ennek megfelelen gyakran hasonltjk a felletekhez. A kpvisel ugyanis megadja egy tagfggvny felptst, de nem valstja meg azt. Ehelyett a kpvisel fogadni tudja a tagfggvnyhvsokat, s az alrs alapjn vgrehajtja azokat.
143
C# Amit a C# tudni rdemes! Mint megannyi ms esetben egy plda bemutatsval vlik vilgoss a kp. Jelen esetben egy olyan programot fogunk rni, amely kt szmot kpes nagysg szerint nvekv vagy cskken sorba rendezni. A rendezs irnyt most magban a kdban hatrozzuk meg, de annak sem lenne semmi akadlya, hogy a felhasznltl krjk be ezt az informcit. A rendezs irnytl fggen ms-ms tagfggvny fut le. Ennek ellenre a kd a kd csak egyetlen hvst fog tartalmazni, mgpedig egy kpviseln keresztl. A megfelel tagfggvnyt a kpvisel fogja megkapni. A kpviselk ltrehozsnak formja a kvetkez: public delegate visszatrsiTpus KpviselNeve(paramterek) Itt a public kulcsszt brmilyen ms, a helyzetnek megfelel elrsmdostval helyettesthetjk, a delegate kulcssz pedig azt jelzi a fordtnak, hogy kpviselrl van sz. A deklarci fennmarad rsze annak a tagfggvnynek a hvsi alrst adja meg, amellyel a kpvisel mkdni fog. A kpvisel neve arra a helyre kerl, ahol kznsges esetben a tagfggvny neve llna. Pldnkban egy Sort nev kpviselt hozunk ltre, amely tbb klnbz rendezsi tagfggvnyt kpes helyettesteni. E tagfggvnyeknek nem lesz visszatrsi rtkk, teht a kpvisel visszatrsi rtke is void. A kpviselk ltal kezelt tagfggvnyek valamennyien kt egsz, hivatkozs tpus bemen paramterrel mkdnek. Ez lehetv teszi, hogy a rendez algoritmus szksg esetn mdostsk sajt bemen paramtereiket. A kpvisel teljes meghatrozsnak alakja a kvetkezkppen nz ki esetnkben: public delegate void Sort(ref int a, ref int b); Figyeljk meg, hogy a meghatrozst pontosvessz zrja. Br ez a sor megtvesztsig hasonlt egy tagfggvny bevezetsre, valjban nem az. Egy igazi tagfggvnynek trzse is van, amit azonban ide lertunk, az csupn a forma meghatrozsa megvalsts nlkl. A kpvisel tbb klnbz tagfggvny sablonja. Esetnkben a Sort brmely olyan tagfggvnynek megfeleltethet, amely nem ad vissza rtket, viszont kt hivatkozs tpus egsz paramtert vr bemenetknt. A kvetkez kdrszlet egy ezzel a kpviselvel hasznlhat tagfggvnyre mutat pldt: public static void Ascending(ref int first, ref int second) { if(first>second) { int tmp = first; first = second; second = tmp; } } Lthat, hogy ez az Ascending nev tagfggvny nem ad vissza rtket, vagyis visszatrsi tpusa void. Ezenkvl pontosan kt egszre vonatkoz hivatkozs tpus bemen paramtert vr a hvtl. Ez pontosan megegyezik a Sort kpviselben meghatrozott alrssal, teht Ksztette: Zstr Csaba III. ves informatikus hallgat 144
C# Amit a C# tudni rdemes! az Ascending hasznlhat a Sort-on keresztl. Mivel a bemen paramterek hivatkozsok, a mdosts a kls adatokat is rinti. Ltrehozhatunk egy msik, ugyanilyen alak tagfggvnyt Descending nven: public static void Descending(ref int first, ref int second) { if(first<second) { int tmp = first; first = second; second = tmp; } } Ez a tagfggvny minden az elz msolata. Egyetlen eltrs, hogy most a nagyobb rtket tartjuk meg ell. Termszetesen tetszleges sok tovbbi tagfggvnyt is megadhatunk a Sort kpviselhz. Az egyetlen kvetelmny velk kapcsolatban az, hogy alrsuknak egyeznie kell az ott megadottal. Ezen kvl arra is lehetsg van, hogy a klnbz programok ms s ms rendezsi logikt alkalmazzanak, de azt valamennyien a Sort kpviselhz rendeljk. Most teht ott tartunk, hogy meghatroztunk agy kpviselt, s megrtunk hozz kt vagy tbb olyan tagfggvnyt, amelyeket kpviselhet. A kvetkez lps termszetesen az, hogy kapcsolatot teremtsnk a kpvisel s a tagfggvnyek kztt, vagyis sszerendeljk ket. Ezt kpvisel objektumok ltrehozsval tehetjk meg. A kpvisel objektum pont olyan, mint brmely ms objektumtpus. Az egyetlen lnyeges kittel, hogy itt a kezdeti a kpviselhz hozzrendelni kvnt tagfggvny nevvel kell elvgezni.
Ahhoz hogy egy, az Ascending tagfggvnnyel kapcsolatban hasznlhat kpvisel objektumot hozzunk ltre, a kvetkezt kell tennnk: Sort up = new Sort(Ascending); Ez egy up nev kpvisel objektumot hoz ltre, amit aztn a szoksos mdon hasznlhatunk. Az up objektum a korbban megvalstott Ascending tagfggvnnyel van sszerendelve. A kvetkez sor egy msik, a Descending tagfggvnnyel sszerendelt kpvisel objektumot ad meg, amit most down-nak hvnak: Sort down = new Sort(Descending); Ltrehoztuk teht egy kpvisel lerst, rtunk hozz neki megfelel tagfggvnyeket, majd ezeket kpvisel objektumok segtsgvel sszerendeltk. A kvetkez magtl rtetd krds az, hogy miknt lehet mindezt mkdsbe hozni, felhasznlni arra, amire ltrehoztuk? Ltre kell hoznunk egy tagfggvnyt, amely a kpvisel objektumot, mint bemen paramtert fogadja. Ez az ltalnos kd fogja aztn vgrehajtani a kpvisel segtsgvel a megfelel tagfggvnyt: Ksztette: Zstr Csaba III. ves informatikus hallgat 145
C# Amit a C# tudni rdemes! public void DoSort(Sort ar) { ar(ref val1, ref val2); } Amint lthat, a DoSort tagfggvny az ar nev bemen paramterben egy kpvisel objektumot vr bemenetknt, majd vgrehajtja azt, amit ebben tall. Figyeljk meg, hogy az ar-nak ugyanolyan alrsa van, mint a kpviselnek. A DoSort tagfggvny lnyegben brmelyik Sort tpus kpvisel objektumban megnevezett tagfggvnyt kpes vgrehajtani. Ha teht az up objektumot adjuk t neki paramterknt, akkor az ar(ref val1, ref val2); az Ascending tagfggvny hvsval lesz egyenrtk. Ha viszont down a bemen paramter tartalma, akkor az ar(ref val1, ref val2); a Descending hvsnak felel meg. Nzzk meg most a teljes programkdot: 3.63 Egy egyszer kpvisel hasznlata
using System; public class SortClass { static public int val1; static public int val2; public delegate void Sort(ref int a, ref int b); public static void DoSort(Sort ar) { ar(ref val1, ref val2); } } public class Delegate { public static void Ascending(ref int first, ref int second) { if(first>second) { int tmp = first; first = second; second = tmp; } } public static void Descending(ref int first, ref int second) { if(first<second) { int tmp = first; first = second; second = tmp; } }
146
Ebben a pldban bedrtozott rtkeket s elre ismert hvsokat hasznltunk. A kpviselk alkalmazsnak igazi haszna viszont tnylegesen majd csak akkor mutatkozik meg, ha ennl sokkal dinamikusabb programokat kezdnk fejleszteni.
Esemnyek hasznlata
Munknk sorn azt fogjuk tapasztalni, hogy a kpviselket leginkbb az esemnyek kezelsvel kapcsolatban alkalmazzuk. Az esemny egy olyan rtests, amit egy osztly bocst ki, jelezve, hogy valami trtnt. Az rtests alapjn azutn mi, vagy pontosabban fogalmazva az ltalunk rt ms osztlyok megtehetik a szksges lpseket. Az esemnyek feldolgozsnak jellemz pldja a Windows opercis rendszerek mkdse. Egy olyan opercis rendszerben, mint a Microsoft Windows, gyakran jelenik meg a kpernyn egy ablak, vagy prbeszdablak, amelyben a felhasznl klnbz mveleteket vgezhet. Egy gombra kattinthat, kijellhet egy menpontot, begpelhet valamilyen szveget, s gy tovbb. Valahnyszor a felhasznl elvgzi valamelyiket e tevkenysgek kzl, egy esemny keletkezik. Ha pldul egy gombra kattintott, akkor egy ButtonClick esemny kerl a rendszerhez feldolgozs vgett. A feldolgozst egy ehhez az esemnyhez tartoz esemnykezel vgzi, amely ismeri s vgre is hajtja a gombnyoms hatsra vgrehajtand mveletek sorozatt.
Esemnyek ltrehozsa
Egy esemny ltrehozsa s hasznlata tbblpcss folyamat. Elszr ltre kell hozunk egy, az esemnyhez tartoz kpviselt, majd egy osztlyt, amely a paramterek tadsban lesz segtsgnkre, azutn meg kell adnunk az esemny hatsra lefut kdot, meg is kell rnunk ezt az gynevezett esemnykezelt, s vgl el kell rnnk, hogy ez esemny valahogy be is kvetkezhessen.
147
Az esemnykpviselk mkdse
Az esemnyekkel kapcsolatos munka els lpse teht az, hogy az illet esemnyhez ltrehozunk egy kpviselt. Az esemnyhez ltrehozott kpviselk formtuma kttt:
delegate void EsemnyKezelNv(object forrs, xxxEsemnyParam e)
Egy esemny kpviselje mindig kt paramtert vesz t. Az els object forrs, vagyis az az objektum, amelyben az esemny bekvetkezett. A msodik, az xxxEsemnyParam e egy olyan osztly, amely az esemnykezel ltal hasznlhat adatokat tartalmazza. Ez az osztly mindig az EventArgs osztlybl szrmazik, amely a System nvtr rsze. A kvetkez programsor egy esemnyhez tartoz kpviselt hoz ltre. Ez az esemny hozzrendelt karaktereket ellenriz. Ha megtall egy adott karaktert, akkor egy ennek megfelel esemny keletkezik. Az ehhez az esemnyhez tartoz kpviselt a kvetkezkppen lehet megadni:
delegate void CharEventHandler(object source, CharEventArgs e);
Ez a sor egy CharEventHandler nev kpviselt hoz ltre. A bevezetsbl ltszik, hogy CharEventHandler nven ltre kell majd hoznunk egy, az EventHandler osztlybl szrmaz msik osztlyt.
Az gy szrmaztatott osztlyt kiegszthetjk az adott esemny kezelshez szksges egyb elemekkel, a konstruktorban pedig gondoskodhatunk ezen j elemek belltsrl is. Az esemnykezelnek ezt az osztlyt fogjuk tadni. Mg egyszer fontos hangslyozni, hogy ennek az tadott objektumnak, illetve osztlynak valamennyi, az esemny kezelshez szksges informcit tartalmazni kell.
148
C# Amit a C# tudni rdemes! Lthatjuk, hogy egy CharEventHandler nev kpviselt kell ltrehoznunk, amelynek egy CharEventArgs tpus objektumot kell tadni. Ezt az osztlyt a kvetkezkppen szrmaztathatjuk az EventArgs alaposztlybl: class CharEventArgs : EventArgs { public char CurrChar; public CharEventArgs(char InChar) { this.CurrChar = InChar; } } Fggetlenl attl, hogy pontosan milyen esemnyt akarunk kezelni, az ehhez szksges osztlyt mindig az EventArgs osztly alapjn kell ltrehozni a fent bemutatott mdon. Jelen esetben az j osztly mindssze egyetlen j elemet tartalmaz az alaposztlyhoz kpest, nevezetesen egy egyetlen karaktert jell CurrChar nev adattagot. Ezt az rtket fogja megkapni a krdses esemny kezelst vgz kd. Osztlyunk tartalmaz egy konstruktort is, amely az osztlyba tartoz objektumok ltrehozsakor kpes fogadni a CurrChar-ban elhelyezend karaktert.
149
Ez az osztly tartalmazza azt a kdot, amely a megfelel felttelek teljeslse esetn kivltja a krdses esemnyt.
Esemnykezelk ltrehozsa
Most teht ott tartunk, hogy ltrehoztunk egy kpviselt, megrtuk z a programszerkezetet, amely tovbbtja a szksges informcit az esemnykezelhz, s ltrehoztuk azt a kdot is, amely kivltja magt az esemnyt. Most azt a kdot kell megrnunk, ami akkor fut le, ha egy esemny bekvetkezett, vagyis ltre kell hoznunk a krtshez magt az esemnykezelt. Az esemnykezel olyan kdrszlet, ami rtestst kap, ha egy adott esemny bekvetkezett. Ahhoz hogy illeszkedjen a korbban kialaktott rendszerbe, az esemnykezel tagfggvnynek ugyanolyan formjnak kell lennie, mint a kpviselnek. Ez a forma a kvetkez: void kezelnv(object forrs, xxxEsemnyParam paramNv) { //esemnykezel kd } A kezelnv annak a tagfggvnynek a neve, ami az esemny hatsra lefut. A tagfggvny trzsben termszetesen brmi lehet, ami az esemnyre megfelel vlasz. Pldnkban legyen ez az esemny az, hogy ha a bemen paramter A volt, akkor azt a program cserlje le X-re. Nzzk a kdot: static void Drop_A(object sender, CharEventArgs e) { if(e.CurrChar=='a' || e.CurrChar=='A') { Console.WriteLine("Don't like 'a'!"); e.CurrChar = 'x'; } }
150
C# Amit a C# tudni rdemes! Ha pedig megvan az objektum, akkor mr hozzfrhet az esemny is. Valahnyszor lefut a CharChecker objektum set blokkja, vgrehajtdik az abban megalkotott logikai szerkezet is, amelynek rsze az esemny ltrehozsa s az esemnyobjektum vgrehajtsa. Ebben a pillanatban azonban az esemny s az esemnykezel mg fggetlen egymstl. Az esemnykezel s az esemnyobjektum sszerendelshez a += mveletet kell hasznlnunk, mgpedig a kvetkez mdon: ObjektumEsemnyNvvel.EsemnyObj += new EsemnykpviselNv(EsemnyNv); A mi pldnkban a kvetkezkppen nz ki: tester.TestChar += new CharEventHandler(Drop_A); Nzzk egyben az egsz programot: 3.64 Esemnyek s esemnykezelk hasznlata
using System; delegate void CharEventHandler(object source, CharEventArgs e); public class CharEventArgs : EventArgs { public char CurrChar; public CharEventArgs(char InChar) { this.CurrChar = InChar; } } class CharChecker { char InChar; public event CharEventHandler TestChar; public char In_Char { get { return InChar; } set { if (TestChar != null ) { CharEventArgs args = new CharEventArgs(value); TestChar(this, args); InChar = args.CurrChar; } } } } class Events { public static void Main() { CharChecker tester = new CharChecker();
151
152
class MyApp { public static void Main() { CharChecker tester = new CharChecker(); tester.TestChar += new CharEventHandler(Drop_A); tester.TestChar += new CharEventHandler(Change_D); tester.Curr_Char = 'B'; Console.WriteLine("{0}", tester.Curr_Char); tester.Curr_Char = 'r'; Console.WriteLine("{0}", tester.Curr_Char); tester.Curr_Char = 'a'; Console.WriteLine("{0}", tester.Curr_Char); tester.Curr_Char = 'd'; Console.WriteLine("{0}", tester.Curr_Char);
static void Drop_A(object source, CharEventArgs e) { if(e.CurrChar == 'a' || e.CurrChar == 'A' ) { Console.WriteLine("Don't like 'a'!"); e.CurrChar = 'X'; } } // j esemnykezel.... static void Change_D(object source, CharEventArgs e) { if(e.CurrChar == 'd' || e.CurrChar == 'D' ) { Console.WriteLine("D's are good!"); e.CurrChar = 'Z'; } } }
153
Esemnykezelk eltvoltsa
Az esemnykezelket hozzrendelhetjk esemnyekhez, de ezt a hozzrendelst menet kzben meg is szntethetjk. Az esemnykezelk eltvoltshoz a -= mveletet kell hasznlnunk a hozzrendelst szolgl += helyett. 3.66 Esemny eltvolts
using System; delegate void CharEventHandler(object source, CharEventArgs e); public class CharEventArgs : EventArgs { public char CurrChar; public CharEventArgs(char CurrChar) { this.CurrChar = CurrChar; } } class CharChecker { char curr_char; public event CharEventHandler TestChar; public char Curr_Char { get { return curr_char; } set { if (TestChar != null ) { CharEventArgs args = new CharEventArgs(value); TestChar(this, args); curr_char = args.CurrChar; } } } } class MyApp { public static void Main() { CharChecker tester = new CharChecker(); tester.TestChar += new CharEventHandler(Drop_A); tester.TestChar += new CharEventHandler(Change_D); tester.Curr_Char = 'B'; Console.WriteLine("{0}", tester.Curr_Char); tester.Curr_Char = 'r'; Console.WriteLine("{0}", tester.Curr_Char); tester.Curr_Char = 'a'; Console.WriteLine("{0}", tester.Curr_Char); tester.Curr_Char = 'd';
154
Ha egy esemnyhez tbb esemnykezelt rendelnk, lefutsuk sorrendjt nem szablyozhatjuk. Ezen kvl termszetesen az esemnykezelkben is keletkezhetnek kivtelek, illetve ltalnosabban ezek a kdrszletek is ugyangy viselkednek, mint a program tbbi rsze. Ha kivtel keletkezik, arra nincs garancia, hogy az adott esemnyhez rendelt tbbi esemnykezel lefut.
C# Amit a C# tudni rdemes! int mymethod( char x, long y, long z ); int mymethod( char x, long y, int z ); Mr arrl is esett sz, hogy nem csak a kznsges tagfggvnyeket, hanem az osztlyok konstruktorait is tl lehet terhelni. Most mg egy korltot ledntnk: megtanuljuk, hogy nemcsak a konstruktorok, de az osztlyok mveletei (opertorai) is tlterhelhetk.
Mveletek tlterhelse
A tagfggvnyek s az osztlyok tagjaihoz hozzfrst enged nyelvi elemek tlterhelsn kvl a legtbb objektumorientlt nyelv azt is lehetv teszi, hogy mveleteket terheljnk tl. Ez all a C# sem kivtel, hiszen az a nyelv is lehetv teszi szmos matematikai mvelet pldul az sszeads s kivons , illetve szmos logikai s sszehasonlt mvelet tlterhelst. A String osztly kivl pldja az olyan osztlyoknak, amelyek eleve rendelkeznek ilyen tlterhelt mvelettel, s annak nagy hasznt is ltjuk. Normlis esetben az sszeadsnak kt osztllyal kapcsolatban nem kellene mkdnie, a C# nyelvben azonban minden tovbbi nlkl sszeadhatunk kt karakterlncot a szoksos + mvelettel. Az eredmny pontosan az lesz, amit egy ilyen mvelettl elvrunk: a kt karakterlnc sszefzsvel keletkez szveget. Nzznk rgtn egy pldt: "animal" + " " + "crackers" E mvelet eredmnye a kvetkez: "animal crackers" Mindez pedig gy lehetsges, hogy a String osztly s a string adattpus tlterheli az sszeads mvelett. Ltni fogjuk, hogy a mveletek tlterhelsvel egyes programjaink nemcsak ttekinthetbbek lesznek, de jobban is fognak mkdni.
A mveletek tlterhelsnek formja hasonl a tagfggvnyeknl megismert formhoz. Az ltalnos mdszer a kvetkez:
public static visszatrsi_tpus operator op (tpus x, tpus y) { ... return visszatrsi_tpus; }
Egy tlterhelt mveletnek minden esetben nyilvnosnak kell lennie, hiszen msknt nem lehetne hozzfrni. A statikussgra szintn szksg van, hiszen ez biztostja, hogy a mvelethez az osztly s ne az objektumpldnyok szintjn tudjuk hozzfrni. Az operator sz termszetesen azt jelzi a fordtnak, hogy itt nem egy kznsges tagfggvnyrl, hanem mvelet (opertor) tlterhelsrl van sz. Azt a kulcsszt maga a tlterhelni kvnt mvelet (op) kveti, vgezetl a mvelet paramterei kvetkeznek. Ebben a pldban egy kttnyezs mveletet terhelnk tl, teht kt paramternk van. A paramterek kzl az egyik tpusa mindenkppen az az osztly kell legyen, amelyben a tlterhelst vgezzk. A msik paramter tpusa brmi lehet. Fontos gyakorlati szempont, hogy ha egy osztlyban tlterhelnk egy mveletet, akkor clszer megvalstani azt minden olyan adattpushoz, amivel kapcsolatban az adott osztlyon bell egyltaln szba jhet. Az AChar osztly az sszeads mvelett terheli tl, gy, hogy egy egsz szmot kpes hozzadni egy trolt karakterhez. Ez a kvetkezkppen fest: public static AChar operator+ (AChar x, int y);
157
} static public AChar operator- ( AChar orig, int val ) { AChar result = new AChar(); result.ch = (char)(orig.ch - val); return result; }
public class myAppClass { public static void Main(String[] args) { AChar aaa = new AChar('a'); AChar bbb = new AChar('b'); Console.WriteLine("Original value: {0}, {1}", aaa.ch, bbb.ch); aaa = aaa + 25; bbb = bbb - 1; Console.WriteLine("Final values: {0}, {1}", aaa.ch, bbb.ch); } }
Az egytnyezs mveleteket a kttnyezsekhez hasonlan kell tlterhelni. Az egyetlen eltrs, hogy bemenetknt itt csak egy paramtert kell megadni, amelynek tpusa rtelemszeren megegyezik azzal az osztllyal, amelyben a tlterhels trtnik. Nzznk erre egy pldt: 3.68 Az egytnyezs + s tlterhelse
using System; using System.Text;
public class AChar { private char private_ch; public AChar() { this.ch = ' '; } public AChar(char val) { this.ch = val; } public char ch { get{ return this.private_ch; }
158
static public AChar operator+ ( AChar orig ) { AChar result = new AChar(); if( orig.ch >= 'a' && orig.ch <='z' ) result.ch = (char) (orig.ch - 32 ); else result.ch = orig.ch; return result; } static public AChar operator- ( AChar orig ) { AChar result = new AChar(); if( orig.ch >= 'A' && orig.ch <='Z' ) result.ch = (char) (orig.ch + 32 ); else result.ch = orig.ch; return result; } } public class myAppClass { public static void Main(String[] args) { AChar aaa = new AChar('g'); AChar bbb = new AChar('g'); AChar ccc = new AChar('G'); AChar ddd = new AChar('G'); Console.WriteLine("ORIGINAL:"); Console.WriteLine("aaa value: {0}", Console.WriteLine("bbb value: {0}", Console.WriteLine("ccc value: {0}", Console.WriteLine("ddd value: {0}", aaa bbb ccc ddd = = = = +aaa; -bbb; +ccc; -ddd; aaa.ch); bbb.ch); ccc.ch); ddd.ch); aaa.ch); bbb.ch); ccc.ch); ddd.ch);
} }
Console.WriteLine("\n\nFINAL:"); Console.WriteLine("aaa value: {0}", Console.WriteLine("bbb value: {0}", Console.WriteLine("ccc value: {0}", Console.WriteLine("ddd value: {0}",
C# Amit a C# tudni rdemes! < <= > >= Szintn ide tartoznak a logikai mveletek: == != Ezekben az esetekben a deklarci kiss klnbzik az elbbiekben bemutatottl. Ahelyett, hogy a tlterhel osztly tpusnak megfelel objektumot adnnak vissza, ezeknek a mveleteknek a visszatrsi rtke mindig logikai (Boolean). Ha jl meggondoljuk, ez logikus is, hiszen e mveletek feladata, hogy kt tnyezt valamilyen szempontbl sszehasonltsk, vagy megmondjk az igazat. Nzznk egy pldt: 3.69 Az sszehasonlt mveletek tlterhelse
using System; using System.Text; public class Salary { private int AMT; public Salary() { this.amount = 0; } public Salary(int val) { this.amount = val; } public int amount { get{ return this.AMT; } set{ this.AMT = value; } } static public bool operator < ( Salary first, Salary second ) { bool retval; if ( first.amount < second.amount ) retval = true; else retval = false; return retval; } static public bool operator <= ( Salary first, Salary second ) { bool retval; if ( first.amount <= second.amount ) retval = true; else
160
static public bool operator > ( Salary first, Salary second ) { bool retval; if ( first.amount > second.amount ) retval = true; else retval = false; } return retval;
static public bool operator >= ( Salary first, Salary second ) { bool retval; if ( first.amount >= second.amount ) retval = true; else retval = false; } return retval;
public class myAppClass { public static void Main(String[] args) { Salary mySalary = new Salary(24000); Salary yourSalary = new Salary(24000); Salary PresSalary = new Salary(200000); Console.WriteLine("Original values: "); Console.WriteLine(" my salary: {0}", mySalary); Console.WriteLine(" your salary: {0}", yourSalary); Console.WriteLine(" a Pres' salary: {0}", PresSalary); Console.WriteLine("\n---------------------------\n"); if ( mySalary < yourSalary ) Console.WriteLine("My salary less than your salary"); else if ( mySalary > yourSalary ) Console.WriteLine("My salary is greater than your salary"); else Console.WriteLine("Our Salaries are the same"); if ( mySalary >= PresSalary ) Console.WriteLine("\nI make as much or more than a president."); else
161
162
public override int GetHashCode() { return this.ToString().GetHashCode(); } static public bool operator == ( Salary first, Salary second ) { bool retval; retval = first.Equals(second); } return retval;
static public bool operator != ( Salary first, Salary second ) { bool retval; retval = !(first.Equals(second)); return retval; } public override string ToString() { return( this.amount.ToString() ); } } public class myAppClass { public static void Main(String[] args) {
163
} }
164
C# Amit a C# tudni rdemes! A CLS valjban egy szablygyjtemny, melyet minden, a .NET krnyezetben fut nyelvnek kvetnie kell. E szablyok kz tartozik a kzs tpusrendszer (CTS) hasznlata. Ha egy program e szablyokhoz tartja magt, a kzs futsidej krnyezet kpes futtatni, fggetlenl attl, hogy milyen nyelven rtk. A CLS szablyainak kvetse azzal az elnnyel jr, hogy az egyik nyelven megrt programot gy egy msikbl is meghvhatjuk. Mivel a krnyezet eljrsai megfelelnek a CLS szablyainak, nemcsak a C#-ban hasznlhatjuk azokat, hanem ms, a CLS-nek megfelel nyelvekben, gy a Visual Basic.NET-ben, valamint a JScript.NET-ben is.
165
C# Amit a C# tudni rdemes! A Math lezrt osztly, ami, ha emlksznk r, azt jelenti, hogy az rklsben nem vehet rszt. Radskppen, minden itt hasznlatos osztly s adattag statikus, gy nem kszthetnk Math tpus objektumot sem; az adattagokat s tagfggvnyeket teht az osztly nevvel kell megadnunk. Matematikai eljrsok a Math osztlyban Tagfggvny neve Visszatrsi rtke Abs A szm abszolt rtke. Ceiling A legkisebb egsz, ami nem kisebb a megadott szmnl. Exp E a megadott kitevre emelve fordtottja a Log fggvny Floor A legnagyobb egsz, ami nem nagyobb a megadott szmnl. IEEERemainder Kt megadott szm osztsnak maradka. (Ez az osztsi mvelet megfelel az ANSI / IEEE 754-1985 szabvnya 5.1. bekezdsnek: IEEE Standard for Binary Floating-Point Arithmetic; Institute of Electrical and Electonics Engineering, Inc; 1985.) Log A megadott szm termszetes logaritmusa. Log10 A megadott szm tzes alap logaritmusa. Max Kt rtk nagyobbika. Min Kt rtk kisebbike. Pow Megadott szm megadott kitevj hatvnya Round A megadott szm kerektett rtke. A kerekts pontossgt meghatrozhatjuk; .5-nl lefel kerektnk. Sign A megadott szm eljelt jelz rtk. Negatv szmok esetn -1, nullnl 0, pozitv szmok esetn 1. Sqrt A megadott rtk ngyzetgyke. Acos Az a szg, amelynek koszinusza megegyezik a megadott rtkkel. Asin Az a szg, amelynek szinusza megegyezik a megadott rtkkel. Atan Az a szg, amelynek tangense megegyezik a megadott rtkkel. Atan2 Az a szg, amelynek tangense megegyezik a kt megadott rtk hnyadosval. Cos A megadott szg koszinusza. Cosh A megadott szg koszinusz hiperbolikusza. Sin A megadott szg szinusza. Sinh A megadott szg szinusz hiperbolikusza. Tan A megadott szg tangense. Tanh A megadott szg tangens hiperbolikusza. A Math osztlyban tallhatunk mg kt llandt is, ezek a PI s az E.
Fjlkezels
A fjlok hasznlatnak lehetsge sokat lendthet programunk hasznlhatsgn vonatkozhat ez sajt fjljaink rsra s olvassra, vagy ms fjlok kezelsre. A kvetkezkben lerakjuk a fjlkezels alapjait, megismerkednk a folyamok fogalmval.
167
C# Amit a C# tudni rdemes! A fjlok kezelsrt a System.IO nvtrben tallhat File alaposztly felel. Itt szmos statikus tagfggvnyt tallhatunk a fjlkezelshez (minden itt fellelhet tagfggvny statikus.). Fjlkezelsi tagfggvnyek Tagfggvny Lers AppendText Szveget fz a fjlhoz. Copy j fjlt kszt egy meglv alapjn. Create j fjlt kszt a megadott helyen. CreateText j fjlt kszt, amely alkalmas szveg trolsra Delete Trli az adott helyen tallhat fjlt. Ennek lteznie kell, ellenkez esetben kivtel keletkezik. Exists Meghatrozza, hogy adott helyen ltezik-e a megadott file. GetAttributes Tjkoztat a fjl tulajdonsgairl. GetCreationTime Megadja a fjl ltrehozsnak dtumt s idejt. GetLastAccessTime Megadja a fjl legutbbi elrsnek dtumt s idejt. GetLastWriteTime Megadja a legutbbi fjlba rs dtumt s idejt. Move Lehetv teszi, hogy fjlt thelyezznk, illetve megvltoztassuk a nevt. Open Megnyitja az adott helyen tallhat fjlt. Ezzel rhatunk bele, illetve olvashatunk belle. OpenRead Megnyit egy fjlt olvassra. OpenWrite Megnyit egy fjlt rsra. OpenText Megnyit egy fjlt, melynek tartalma szvegknt rtelmezhet. SetAttributes Belltja a megadott fjl tulajdonsgait. SetCreationTime Belltja a fjl ltrehozsnak dtumt s idejt. SetLastAccessTime Bellatja az utols elrs dtumt s idejt. SetLastWriteTime Belltja az utols mdostsa dtumt s idejt. 3.72 Fjl msolsa
using System; using System.IO; class FileCopy { public static void Main() { string[] CLA = Environment.GetCommandLineArgs(); if ( CLA.Length < 3 ) { Console.WriteLine("Format: {0} orig-file new-file", CLA[0]); } else { string origfile = CLA[1]; string newfile = CLA[2]; Console.Write("Copy...."); try
168
file.");
A fjlok adatai
A fjlok kezelsben a File mellett a FileInfo osztly is segtsgnkre lehet. Hasznlatt a kvetkez kdsor mutatja be: 3.73 A FileInfo osztly alkalmazsa
using System; using System.IO; class FileSize { public static void Main() { string[] CLA = Environment.GetCommandLineArgs(); FileInfo fiExe = new FileInfo(CLA[0]); if ( CLA.Length < 2 ) { Console.WriteLine("Format: {0} filename", fiExe.Name); } else { try { FileInfo fiFile = new FileInfo(CLA[1]); if(fiFile.Exists)
169
file.");
catch (System.IO.FileNotFoundException) { Console.WriteLine("\n{0} does not exist!", CLA[1]); return; } catch (Exception e) { Console.WriteLine("\nAn exception was thrown trying to copy Console.WriteLine(e); return;
} } }
Ismerkeds a folyamokkal
A fjl kifejezst tbbnyire a lemezen vagy a memriban trolt adatokkal kapcsolatban hasznljuk. Ha pedig ezekkel mveleteket vgznk, folyamokat alkalmazunk. A folyam adatramlst jelent, amely nem kell, hogy szveges legyen, s nem szksges fjlhoz tartoznia sem. A folyamokat hasznlhatjuk a memribl, hlzatrl, a Vilghlrl, egy karakterlncbl, vagy mshonnan szrmaz adatok kldsre s fogadsra. Emellett gyakran alkalmazzuk ket adatfjlok ki- s bemeneti mveleteiben.
A fjlolvass menete
Ha runk egy fjlba, vagy olvasunk belle, egy meghatrozott mveleti sorrendet kell kvetnnk. Elszr meg kell nyitni a fjlt. Ha j fjlt hozunk ltre, ez ltalban egytt jr a megnyitssal. Ha ezzel elkszltnk, egy folyamra van szksgnk ahhoz, hogy az adatokat a fjlban elhelyezzk, vagy kiolvassuk onnan. A folyam ltrehozsakor meg kell adnunk az Ksztette: Zstr Csaba III. ves informatikus hallgat 170
C# Amit a C# tudni rdemes! adatok ramlsnak irnyt, s hozz kell rendelnnk a fjlhoz. Ekkor kezddhet csak meg az olvass, illetve az rs. Elbbi esetben megeshet, hogy a fjl vgre is gyelnnk kell. Ha elkszltnk az rssal vagy az olvasssal, be kell zrnunk a fjlt.
171
public class Reading { public static void Main(String[] args) { if( args.Length < 1 ) { Console.WriteLine("Must include file name."); } else { string buffer; StreamReader myFile = File.OpenText(args[0]); while ( (buffer = myFile.ReadLine()) != null ) { Console.WriteLine(buffer); } myFile.Close(); } } }
C# Amit a C# tudni rdemes! csokornyi egsz szmot kzvetlenl a fjlba tudnnk rni, egszknt is olvashatnnk ki de ha szvegknt troljuk, a ksbb kiolvasott rtkeket egyenknt t kellene alaktanunk karakterlncrl egsz szmm. Szerencsre ennyi krlmnyeskedsre nincs szksg, hiszen alkalmazhatunk egy binris folyamot (BinaryStream), melyen keresztl binris adatokat vihetnk t. Binris adatok jellemzje, hogy megtartjk az adattpus eredeti trolsi formjt, nem alaktjk szvegg. 3.76 Adatok binris fjlba rsa
using System; using System.IO; class MyStream { public static void Main(String[] args) { if( args.Length < 1 ) { Console.WriteLine("Must include file name."); } else { FileStream myFile = new FileStream(args[0], FileMode.CreateNew); BinaryWriter bwFile = new BinaryWriter(myFile); for (int i = 0; i < 100 ; i++) { bwFile.Write(i ); } bwFile.Close(); myFile.Close();
} } }
A FileMode rtkei rtk Lersa Append Megnyit egy ltez fjlt, vagy jat kszt. Create j fjlt kszt. Ha a fjl mr ltezik, a program trli, s j fjlt hoz ltre helyette. CreateNew j fjlt hoz ltre. Ha a fjl mr ltezik, kivtelt vlt ki. Open Megnyit egy ltez fjlt. OpenOrCreate Megnyit egy fjlt, vagy ha nem ltezik ltrehozza. Truncate Megnyit egy ltez fjlt, s trli a tartalmt.
173
} } }
Windowsalkalmazsok ksztse
Windows ablakok ksztse
Napjainkban a legtbb opercis rendszer esemnyvezrelt programokat s ablakokat hasznl a felhasznlkkal val kapcsolattartsra. Ha mr fejlesztetnk Microsoft Windows rendszeren, nyilvn tallkoztunk a Win32 knyvtraiban az ablakok ksztst segt eljrsokkal. A .NET krnyezet alap-osztly knyvtrban is szintn ltezik egy hasonl, az ablakokkal kapcsolatos osztlycsald. Ez utbbinak nagy elnye, hogy brmely, a krnyezetbe tartoz programnyelvbl elrhet. Emellett ksztsnl odafigyeltek arra, hogy hasznlata, s gy az ablak alap alkalmazsok ksztse knnyebb legyen. Mindemellett, ahogy a .NET krnyezet s futsidej rendszer ms felletekre is trjk, programjaink egy csapsra hordozhatv vlnak.
174
C# Amit a C# tudni rdemes! Ha programunkban ablakot szeretnnk hasznlni, egy osztlyt kell ksztennk, amely a Form osztlybl rkldik. Ez utbbi a System.Windows.Forms nvtrben tallhat meg. Hasznlatt egy igen egyszer pldn mutatjuk meg: 4.1 Egyszer ablak
using System.Windows.Forms; public class FirstFrm : Form { public static void Main( string[] args ) { FirstFrm frmHello = new FirstFrm(); Application.Run(frmHello); } }
Lthatjuk hogy ez igen rvidke program, klnsen ahhoz kpest, mennyi mindent tesz. Ahhoz persze, hogy lssuk, elbb le kell fordtanunk ennek mikntjvel foglalkozunk a kvetkezkben.
Fordtsi belltsok
Az elz programocska fordtsnl a korbbiaktl eltren kell eljrnunk. Elfordulhat, hogy a parancssorban hivatkoznunk kell egyes, a programban hasznlt alaposztlyokra. Az ablakosztlyok a System.Windows.Forms.dll nev gynevezett szerelvnyben (assembly) tallhatk, programunk fordtsakor teht erre kell hivatkoznunk. A kdszveg elejre biggyesztett using utastssal valjban nem ptnk be egyetlen fjlt sem a programunkba, ez csak hivatkozst ad a fjlban trolt nvtr egy pontjra. Amint azt a korbbiakban lthattuk, mindez lehetv teszi, hogy az osztlyoknak ne kelljen a teljes nevt kirnunk. A legtbb ablakkal kapcsolatos vezrl s lehetsg ebben a szerelvnyben tallhat. Fordtskor, hogy biztosak legynk a hasznlatban, egy hivatkozst hasznlhatunk a parancssorban. Ha a Microsoft parancssori fordtjt hasznljuk, az egyszer fordtsi utastshoz a /reference: fjlnv kapcsolt kell hozzfznnk, ahol a fjlnv a szerelvny nevt jelenti. Ha teht az ablakok szerelvnyt hasznlva szeretnnk lefordtani az elz programot, a kvetkezt kell a parancssorba rnunk: csc /reference:System.Windows.Forms.dll Form1.cs A /reference: helyett hasznlhat a rvidebb /r:alak is. Ha vgrehajtjuk a parancsot, a fordts gy is rendben lefut .A Microsoft .NET krnyezet 1.1-es s ksbbi vltozatainak C# fordti automatikusan alkalmaznak egyes hivatkozsokat, kztk a System.Windows.Forms.dll-t is. A kapott eredmny a fordts utn:
175
Nos pontosan ezt szerettk volna! Vagy mgsem? Ha a programot kzvetlenl egy opercis rendszeren mondjuk Microsoft Windowson futtatjuk, az eredmny kiss eltr lesz. Ilyenkor ugyanis a kpernyn marad a parancssor ablak is, ami pedig csak pp a htunkon.
Ahhoz hogy eltntessk a nem kvnt ablakot, el kell rulnunk a fordtnak, hogy programunkat Windows rendszerbeli hasznlatra sznjuk. Erre a /target: (rvidtve /t:) kapcsol hasznlhat, mghozz a winexe belltssal. Teht a kvetkezt kell a parancssorba rnunk, ha a kvnt eredmnyt szeretnnk: csc /r:System.Windows.Forms.dll /t:winexe From1.cs Ha most elindtjuk a programot, a kpernyn nem jelenik meg a parancssor ablaka.
C# Amit a C# tudni rdemes! mindaddig fut, amg a felhasznl valamit nem tesz az ablakon, illetve az ablakos krnyezetben. A tettek zenetek keletkezsvel jrnak, ezek pedig esemnyeket vltanak ki. Ha ltezik az zenethez esemnykezel, a rendszer vgrehajtja, egybknt a ciklus fut tovbb.
gy ltszik, mintha a ciklus soha nem rne vget. Nos, magtl nem is, de egy esemny befejezheti a program futst. Az alapablak, melynek osztlytl (Form) rklnk, tartalmazza a bezrs vezrljt, valamint a parancsmenben egy Bezrs (Close) pontot ezek a vezrlk olyan esemnyt vlthatnak ki, melyek bezrjk az ablakot, s befejezik a programot. Mindezek fnyben bizonyra rjttnk mr, mire is j az Application osztly, vagy mg inkbb ennek Run tagfggvnye. Feladata a ciklus fenntartsa s a program mkdsnek biztostsa, mg a futs vgt jelz esemny be nem kvetkezik. Erre akkor kerl sor, ha a felhasznl megnyomja a Close gombot vagy a parancsmen Close pontjt vlasztja. Az Application osztly Run tagfggvnye kezel minden, a programfuts kzben ltrejv zenetet. Ezek szrmazhatnak az opercis rendszertl, alkalmazsoktl, vagy ms, a rendszerben fut programoktl. Ha egy zenet megfelel valamelyik esemnykezelnek, a rendszer vgrehajtja azt. Ha nincs alkalmas esemnykezel, a rendszer figyelmen kvl hagyja az zenetet.
Ablakok testreszabsa
Az elzekben egy egyszer ablakot mutattunk be. A Form osztlyhoz azonban szmos tulajdonsg, tagfggvny s esemny tartozik tl sok is ahhoz, hogy mindegyikkrl szt ejtsnk. Nem kell azonban aggdnunk, a dokumentciban minden krdsnkre megtalljuk a vlaszt.
177
C# Amit a C# tudni rdemes! Az elz pldban egy egyszer, res ablakot ksztettnk. A kvetkezkben is ezzel az res ablakkal dolgozunk tovbb, de minden pldval egyre jobban beleszlunk a mkdsbe. A kdban eleve elrhet nhny elem, gy a vezrlmen, valamint a Minimize, Maximize s a Close gombok a cmsoron. Ezek ki- vagy bekapcsolst tulajdonsgaik segtsgvel szablyozhatjuk: ControlBox HelpButton Meghatrozza, hogy megjelentsk-e a vezrlment. Jelzi, hogy a sggomb megjelenik-e az ablak cmsorban. E megjelensre csak akkor van md, ha a MaximizeBox s a MinimizeBox rtke egyarnt false. Jelzi, hogy megjelenik-e a Maximize gomb. Jelzi, hogy megjelenik-e a Minimize gomb. Az ablak cmsornak szvegt tartalmazza.
A fenti rtkek hatssal lehetnek egymsra is. gy a HelpButton rtke pldul csak akkor lehet true, ha a MaximizeBox s a MinimizeBox rtke egyarnt false. 4.2 Az ablak cmsornak tulajdonsgai
using System.Windows.Forms; public class FormApp : Form { public static void Main( string[] args ) { FormApp frmHello = new FormApp(); frmHello.MinimizeBox = true; frmHello.MaximizeBox = false; frmHello.HelpButton = true; frmHello.ControlBox = true; frmHello.Text = @"My Form's Caption"; } } Application.Run(frmHello);
178
szre vehetjk, hogy a Help gomb megjelentsrl is gondoskodtunk, azzal, hogy rtkt true-re lltottuk. A kpernyn ez azrt nem rezteti hatst, mert e gomb csak akkor jelenhet meg, hogy ha a MaximizeBox s a MinimizeBox rtke egyarnt false. Ha trjuk a kdot a kvetkezre: frmHello.MinimizeBox = false; frmHello.MaximizeBox = false; frmHello.HelpButton = true; frmHello.ControlBox = true; Akkor, ha jra fordtjuk a Help gomb megjelenik:
179
C# Amit a C# tudni rdemes! Ltezik egy tovbbi kombinci, amirl rdemes szlnunk. Ha a ControlBox tulajdonsgot false-ra lltjuk, mind a Close, mind a vezrlmen eltnik. St, ha a ControlBox, a MinimizeBox s a MaximizeBox rtke egyarnt false, s a cmfeliratnak nincs szvege, a cmsor is eltnik. Ekkor az ablakot az Alt+F4 billentykkel zrhatjuk be:
Ablakok tmretezse
Az ablakok kvetkez lnyeges tulajdonsgai a mrete s az alakja. Ezek mdostsra szmos tulajdonsgot s tagfggvnyt hasznlhatunk: A Form osztly mretezsi eszkzei. AutoScale Belltsval az ablak automatikusan tmretezi magt, a rajta hasznlt bettpusnak s vezrlknek megfelelen. AutoScaleBaseSize Az automatikus mretezs alapmrete. AutoScroll Belltsa esetn az ablak automatikus grgetsi kpessggel rendelkezik. AutoScrollMargin Az automatikus grgetshez hasznlt marg mrete. AutoScrollMinSize Az automatikus grgetskor lthat terlet legkisebb mrete. AutoScrollPosition Az automatikus grgetskor lthat terlet helyzete. ClientSize Az ablak bels terletnek (gyflterletnek) mrete. DefaultSize Vdett tulajdonsg, amely az ablak alaprtelmezett mrett adja meg. DesktopBounds Az ablak helye s mrete. DesktopLocation Az ablak helye. Height Az ablak magassga. MaximizeSize Az ablak legnagyobb lehetsges mrete. MinimizeSize Az ablak legkisebb lehetsges mrete. Size Az ablak mrete. A Size objektumban a set s a get utastsokkal egy x s y rtket rhetnk el. Ksztette: Zstr Csaba III. ves informatikus hallgat 180
C# Amit a C# tudni rdemes! SizeGripStyle A mretez foganty tpusa. A SizeGripStyle felsorol tpus egy rtke, ami Auto (automatikusan megjelenik, ha szksg van r), Hide (rejtett), vagy Show (mindig lthat) lehet. Az ablak kiindulsi helyzete. A FormStartPosition felsorol tpus egyik rtke, ami CenterParent (kzpre igaztva a szlablakon), CenterScreen (kzpre igaztva a kpernyn), Manual (a helyet s a mretet a kiindulsi helyzettel adhatjuk meg), WindowsDefaultBounds (alaprtelmezett helyzet), vagy WindowsDefaultLocation (alaprtelmezett helyzet, megadott mretekkel) lehet. Az ablak szlessge.
StartPosition
using System.Windows.Forms; using System.Drawing; public class FormSize : Form { public static void Main( string[] args ) { FormSize myForm = new FormSize(); myForm.Text = "Form Sizing"; myForm.Width = 400; myForm.Height = 100; Point FormLoc = new Point(200,350); myForm.StartPosition = FormStartPosition.Manual; myForm.DesktopLocation = FormLoc; Application.Run(myForm); } }
Az ablak mretnek mdostsa egyszer, a Width s Height tulajdonsgok belltsval. Az ablak helynek belltsa mr tbb odafigyelst ignyel. Lthat, hogy egy Point objektumot ksztnk, ami az ablak kvnt helyzetnek koordintit tartalmazza. Ezt az objektumot hasznljuk ki a DesktopLocation tulajdonsgnl. Ahhoz, hogy a Point objektumra ilyen egyszeren hivatkozzunk, hasznlatba kell vennnk a System.Drawing nvteret. Ksztette: Zstr Csaba III. ves informatikus hallgat 181
Application.Run(myForm); }
182
Ez a program egy kpet jelent meg az ablak htterben, melyet a parancssorban adhatunk meg. Ha ezt nem tesszk meg, a httr egyszn rzsaszn lesz (HotPink). A parancssor a kvetkez: PicForm Bmbi5.jpg
public class BorderForm : Form { public static void Main( string[] args ) { BorderForm myForm = new BorderForm();
183
Amint az bra is mutatja, ablakunk szeglye rgztett. Ha futs kzben megprblnnk tmretezni, nem jrnnk sikerrel.
184
Cmkk s szvegmegjelents
A Label vezrl segtsgvel szvegrszleteket jelenthetnk meg a kpernyn. Ahhoz, hogy a vezrlt az ablakra helyezzk, elbb ltre kell hoznunk, majd pedig testreszabni a tulajdonsgai s tagfggvnyei segtsgvel. Ha elvgeztk a kvnt belltsokat, elhelyezhetjk a vezrlt az ablakon. A cmke olyan vezrl, amely adatokat kzl a felhasznlval, de nem teszi lehetv, hogy az mdostsa a tartalmt (a programoz persze megteheti). A cmke ltrehozsa ugyangy trtnik, mint ms objektumok: Label myLabel = new Label(); Most mr van egy res cmknk, amit elhelyezhetnk az ablakon. Ehhez az ablak Controls tulajdonsgnak Add tagfggvnyt kell ignybe vennnk: myForm.Control.Add(myLabel); Ha ms vezrlre van szksg, ennek nevt egyszeren helyettestsk be a myLabel helyre. Nzznk egy pldt erre: 4.6 Cmke hasznlata.
using System; using System.Windows.Forms; using System.Drawing; public class ControlApp : Form { public static void Main( string[] args ) { ControlApp myForm = new ControlApp(); myForm.Text = Environment.CommandLine; myForm.StartPosition = FormStartPosition.CenterScreen; Label myDateLabel = new Label(); Label myLabel = new Label(); myLabel.Text = "This program was executed at:"; myLabel.AutoSize = true; myLabel.Left = 50; myLabel.Top = 20; DateTime currDate = DateTime.Now;;
185
Gombok hasznlata
A Windows alkalmazsok legismertebb vezrli kz tartoznak a gombok, melyek ksztsre a Button osztly szolgl. A gombok annyiban trnek el a cmkktl, hogy ltalban szeretnnk, hogy valami bekvetkezzen, amikor a felhasznl rjuk kattint. Mieltt a gombok mkdsnek rszleteibe bocstkoznnk, rdemes pr percig elidznnk ksztsknl s kirajzolsuknl. A cmkkhez hasonlan az els lps itt is a pldnyosts. Button myButton = new Button(); Ha ltrehoztuk a gombot, tulajdonsgai segtsgvel testreszabhatjuk megjelenst. A Label vezrlkhz hasonlan itt is tlsgosan sok tulajdonsg, adattag s tagfggvny ll rendelkezsnkre, hogy mindegyiket bemutassuk, azonban nhnyat a kvetkez tblzatban sorolunk fel, rvid lersukkal: A gombok nhny tulajdonsga Tulajdonsg Lersa BackColor A gomb httrsznnek belltsa vagy kiolvassa. BackgroundImage A gomb httrkpnek belltsa vagy kiolvassa. Bottom A gomb alja s a gombot tartalmaz trol teteje kzti tvolsg. Enabled A gomb engedlyezst jelz rtk belltsa vagy kiolvassa. Height A gomb magassgnak belltsa vagy kiolvassa. Image A gomb elterben elhelyezett kp belltsa van kiolvassa. Ksztette: Zstr Csaba III. ves informatikus hallgat 186
C# Amit a C# tudni rdemes! Left Right Text TextAlign Top Visible Width A gomb bal oldala helyzetnek belltsa vagy kiolvassa. A gomb jobb oldalnak belltsa vagy kiolvassa. A gomb feliratnak belltsa vagy kiolvassa. A gomb felirata igaztsnak belltsa vagy kiolvassa. A gomb teteje helyzetnek belltsa vagy kiolvassa. A gomb lthatsgt jelz rtk belltsa vagy kiolvassa. A gomb szlessgnek belltsa vagy kiolvassa .
Ha tzetesebben szemgyre vesszk a tblzatban tallhat rtkeket, szre vehetjk, hogy nhnyukat mr hasznltuk a cmkknl. Nos, e hasonlsgnak oka van minden vezrl egy ltalnosabb, Control nevezet osztlybl szrmazik. Ez teszi lehetv, hogy minden vezrl ugyanazokat a tagfggvnyeket s neveket hasznlja ugyanazon feladatok elvgzsre. gy pldul a Top mindig a vezrl tetejt adja meg, legyen az gomb, szvegmez, vagy ms egyb.
Gombesemnyek
Ne feledjk azonban, hogy a gombok hasznlatnak igazi rtelme, hogy segtsgkkel mveleteket indthatunk el ehhez pedig esemnyeket hasznlunk. Miutn egy gombot ltrehoztunk, esemnyeket rendelhetnk hozz. Elszr el kell ksztennk az esemny kezelsre szolgl tagfggvnyt, melyet a program az esemny bekvetkezsekor hv meg. Amint a korbbiakban megtanultuk, ez a tagfggvny kt paramtert kell fogadjon: az esemnyt kivlt objektum nevt, valamint egy System.EventArgs vltozt. A tagfggvnynek ezen kvl vdettnek kell lennie, s void tpusnak. A meghatrozs a kvetkezkppen fest: protected void tagfggvnyNv (object sender, System.EventArgs paramterek) Ha ablakokkal dolgozunk, a tagfggvnyek nevt tbbnyire az esemnyt kivlt vezrl s az esemny nevbl lltjuk ssze. Pldul, ha az ABC gombra kattintunk, az esemnykezel neve lehet ABC_Click. Az esemny kivltshoz ssze kell ktnnk az esemnyt a megfelel kpviselvel. Az ablakok esemnyeit a System.EventHandler kpvisel objektum felgyeli, gy ha ezt rendeljk esemnykezelinkhez, hvsuk a megfelel idben kvetkezik be. A hozzrendels a kvetkezkppen trtnhet: VezrlNv.Esemny += new System.EventHandler(this.tagfggvnyNv); Nzzk meg az elz programot gy, hogy egy gombot helyeznk el, amely megnyomsakor frissti az idt: 4.7 Gombok s esemnyek hasznlata
using System; using System.Windows.Forms; using System.Drawing;
187
DateTime currDate = new DateTime(); currDate = DateTime.Now; myDateLabel.Text = currDate.ToString(); myDateLabel.AutoSize = true; myDateLabel.Location = new Point( 50, 20); myDateLabel.BackColor = this.BackColor; this.Controls.Add(myDateLabel); // Add label to form
btnUpdate.Text = "Update"; btnUpdate.BackColor = Color.LightGray; btnUpdate.Location = new Point(((this.Width/2) - (btnUpdate.Width / 2)),(this.Height - 75)); this.Controls.Add(btnUpdate); // Add button to form
btnUpdate.Click += new System.EventHandler(this.btnUpdate_Click); btnUpdate.MouseEnter += new System.EventHandler(this.btnUpdate_MouseEnter); btnUpdate.MouseLeave += new System.EventHandler(this.btnUpdate_MouseLeave); myDateLabel.MouseEnter += new System.EventHandler(this.myDataLabel_MouseEnter); myDateLabel.MouseLeave += new System.EventHandler(this.myDataLabel_MouseLeave); } protected void btnUpdate_Click( object sender, System.EventArgs e) { DateTime currDate =DateTime.Now ; this.myDateLabel.Text = currDate.ToString(); }
188
protected void btnUpdate_MouseEnter( object sender, System.EventArgs e) { this.BackColor = Color.HotPink; } protected void btnUpdate_MouseLeave( object sender, System.EventArgs e) { this.BackColor = Color.Blue; } protected void myDataLabel_MouseEnter(object sender, System.EventArgs e) { this.BackColor = Color.Yellow; } protected void myDataLabel_MouseLeave(object sender, System.EventArgs e) { this.BackColor = Color.Green; } public static void Main( string[] args ) { Application.Run( new ButtonApp() ); }
OK gomb ksztse
Szmos ablakon tallkozunk az OK gombbal, melyre a felhasznl akkor kattint, ha befejezte a mveleteit az ablakon. A kattints eredmnyekppen az ablak tbbnyire bezrdik. Ha magunk hozzuk ltre az ablakot, s az Application osztly Run tagfggvnyvel Ksztette: Zstr Csaba III. ves informatikus hallgat 189
C# Amit a C# tudni rdemes! mkdtetjk, kszthetnk egy esemnykezelt, ami kilp a Run tagfggvnybl, ha a felhasznl az OK gombra kattintott: private void btnOK_Click(object sender, System.EventArgs e) { Application.Exit(); } Ha nem szeretnnk kilpni a teljes alkalmazsbl, illetve mkdsi ciklusbl, hasznlhatjuk e clra az ablak Close tagfggvnyt is. Az OK gomb mkdst azonban egy, az eddigiektl gykeresen eltr mdszerrel is megvalsthatjuk. Elszr is, feledkezznk el az Application osztly Run tagfggvnyrl; hasznljuk inkbb a Form osztly ShowDialog tagfggvnyt. Ez ugyanis egy prbeszdablakot jelent meg, s mindaddig gy hagyja, mg a felhasznl el nem vgzett rajta minden szksges mveletet. A prbeszdablak egybirnt egy egyszer ablak, ltrehozsa minden ms rszletben megegyezik a korbban megismert ablakoknl ltottakkal. ltalban, ha a felhasznl leti egy ablakon az ENTER billentyt, ez mkdsbe hozza az OK gombot. Az ENTER-t knnyen sszekthetjk egy gombbal az ablak AcceptButton tulajdonsgnak hasznlatval. Amelyik gombot ehhez hozzrendeljk, az lp mkdsbe az ENTER lenyomsra.
Szvegmezk hasznlata
A kzismert vezrlk kz tartoznak a szvegmezk is, melyek a felhasznl szveges bemenett kpesek fogadni. gy teht a szvegmezkkel s esemnyeikkel a programunkban is hasznlhat adatokhoz juthatunk a felhasznltl: 4.8 Szvegmez vezrl hasznlata
using System; using System.Windows.Forms; using System.Drawing; public class GetName : Form { private Button btnOK; private private private private private Label Label Label Label Label lblFirst; lblMiddle; lblLast; lblFullName; lblInstructions;
private TextBox txtFirst; // szvegmez private TextBox txtMiddle; private TextBox txtLast; public GetName() { InitializeComponent(); }
190
btnOK = new Button(); lblFirst.AutoSize = true; lblFirst.Text = "First Name:"; lblFirst.Location = new Point( 20, 20); lblMiddle.AutoSize = true; lblMiddle.Text = "Middle Name:"; lblMiddle.Location = new Point( 20, 50); lblLast.AutoSize = true; lblLast.Text = "Last Name:"; lblLast.Location = new Point( 20, 80); lblFullName.AutoSize = true; lblFullName.Location = new Point( 20, 110 ); txtFirst.Width = 100; txtFirst.Location = new Point(140, 20); txtMiddle.Width = 100; txtMiddle.Location = new Point(140, 50); txtLast.Width = 100; txtLast.Location = new Point(140, 80); lblInstructions.Width = 250; lblInstructions.Height = 60; lblInstructions.Text = "Enter your first, middle, and last name." + "\nYou will see your name appear as you type." + "\nFor fun, edit your name after entering it."; lblInstructions.TextAlign = ContentAlignment.MiddleCenter; lblInstructions.Location = new Point(((this.Width/2) - (lblInstructions.Width / 2 )), 140); this.Controls.Add(lblFirst); // Add label to form this.Controls.Add(lblMiddle); this.Controls.Add(lblLast); this.Controls.Add(lblFullName); this.Controls.Add(txtFirst);
191
btnOK.Click += new System.EventHandler(this.btnOK_Click); txtFirst.TextChanged += new System.EventHandler(this.txtChanged_Event); txtMiddle.TextChanged += new System.EventHandler(this.txtChanged_Event); txtLast.TextChanged += new System.EventHandler(this.txtChanged_Event);
protected void btnOK_Click( object sender, System.EventArgs e) { Application.Exit(); } protected void txtChanged_Event( object sender, System.EventArgs e) { lblFullName.Text = txtFirst.Text + " " + txtMiddle.Text + " " + txtLast.Text; } public static void Main( string[] args ) { Application.Run( new GetName() ); } }
192
193
= = = = = = = =
new System.Drawing.Point(220, 90); new System.Drawing.Size(90, 15); 4; "Under 21"; new System.Drawing.Point(220, 40); new System.Drawing.Size(90, 15); 5; "Age Group";
this.Controls.Add(rdMale); this.Controls.Add(rdFemale); this.Controls.Add(lblText1); this.Controls.Add(rdYouth); this.Controls.Add(rdAdult); this.Controls.Add(lblText2); this.Controls.Add(btnOK); } private void btnOK_Click(object sender, System.EventArgs e) { Application.Exit(); } static void Main() { Application.Run(new BadRadio()); }
194
A kd egy ablakot kszt ngy vlasztgombbal s egy gombbal. Tallhatunk rajta tovbb kt szvegmezt is, melyek a felhasznl tulajdonsgra szolglnak. Ha futtatjuk, akkor lthatjuk, hogy a vlasztgombok a vrtnak megfelelen mkdnek. Vagy mgsem? Ha bejellnk egy vlasztgombot, az ssze tbbi kivlasztsa megsznik. Az igazi az volna, ha a kt kategrit el tudnnk valahogy vlasztani egymstl. A legtbb vezrl rendelkezik TabIndex tulajdonsggal, amely meghatrozza a vezrlk kivlasztsnak sorrendjt, ha a felhasznl a Tab billentyt nyomkodja. Az els vezrl sorszma 0, a msodik 1 s gy tovbb. A vlasztgombok kezelshez nem kell kln kdot rnunk, hiszen a kivlaszts s kivlaszts megszntetsnek kdja mr eleve megvan bennk. Amit azonban a korbbiakban emltettnk, ez a kd nem egszen gy mkdik, ahogy azt elkpzeltk. Valami vltoztatsra van szksg, hogy a vlasztgombok kt csoportja egymstl fggetlenl mkdhessen.
Trolk hasznlata
Feladatunk megoldsban a trolkat hvjuk segtsgl, melyek lehetv teszik, hogy vezrlket csoportokba foglaljuk. Egy trolt mr eddig is hasznltunk a fablakot. Emellett azonban sajt trolkat is ltrehozhatunk, melyeket az ablak troljban vagy ms trolkban elhelyezhetnk. Van azonban egy msik lehetsg is a vezrlk elvlasztsra: a csoportmez (GroupBox) hasznlata. Ez ugyangy mkdik, mint egy trol, nhny tovbbi lehetsggel, gy pldul cmkefeliratot is feltntethetnk rajta: 4.10 Vlasztgombok csoportba helyezs
using System.Drawing; using System.Windows.Forms;
public class GoodRadio : Form { private GroupBox gboxAge; private GroupBox gboxSex; private RadioButton rdMale;
195
public GoodRadio() { InitializeComponent(); } private void InitializeComponent() { this.gboxAge = new GroupBox(); this.gboxSex = new GroupBox(); this.rdMale = new RadioButton(); this.rdFemale = new RadioButton(); this.rdYouth = new RadioButton(); this.rdAdult = new RadioButton(); this.btnOK = new Button(); // Form1 this.ClientSize = new Size(350, 200); this.Text = "Grouping Radio Buttons"; // gboxSex this.gboxSex.Location this.gboxSex.Size this.gboxSex.TabStop this.gboxSex.Text // rdMale this.rdMale.Location this.rdMale.Size this.rdMale.TabIndex this.rdMale.Text = = = = = = = = new Point(15, 30); new Size(125, 100); false; "Sex"; new Point(35, 35); new Size(70, 15); 0; "Male"; = = = = = = = = = = = = = = = = new Point(35, 60); new Size(70, 15); 1; "Female"; new Point(200, 30); new Size(125, 100); false; "Age Group"; new Point(35, 35); new Size(70, 15); 3; "Over 21"; new Point(35, 60); new Size(70, 15); 4; "Under 21";
// rdFemale this.rdFemale.Location this.rdFemale.Size this.rdFemale.TabIndex this.rdFemale.Text // gboxAge this.gboxAge.Location this.gboxAge.Size this.gboxAge.TabStop this.gboxAge.Text // rdYouth this.rdYouth.Location this.rdYouth.Size this.rdYouth.TabIndex this.rdYouth.Text // rdAdult this.rdAdult.Location this.rdAdult.Size this.rdAdult.TabIndex this.rdAdult.Text
196
this.Controls.Add(gboxSex); this.Controls.Add(gboxAge); this.gboxSex.Controls.Add(rdMale); this.gboxSex.Controls.Add(rdFemale); this.gboxAge.Controls.Add(rdYouth); this.gboxAge.Controls.Add(rdAdult); this.Controls.Add(btnOK); } private void btnOK_Click(object sender, System.EventArgs e) { Application.Exit(); } static void Main() { Application.Run(new GoodRadio()); }
E kd a csoportmezk hasznlatra sszpontost. Ha helyettk trolkat hasznltunk volna, a kd hasonlan festene, annyi klnbsggel, hogy ez esetben nem hasznlhatnnk a trolk Text s ms tulajdonsgait. Ahhoz, hogy kialaktsuk ugyanezt a kpet, ms vezrlkre is szksgnk lenne (pldul cmkkre). A kd igazn fontos rsze az, ahol a kt csoportot (ezek a gboxSex s a gboxAge) az ablakra helyezzk. A vlasztgombok nem az ablakra, hanem a csoportmezkbe kerlnek. Ksztette: Zstr Csaba III. ves informatikus hallgat 197
C# Amit a C# tudni rdemes! Mivel pedig ezek a csoportmezk az ablak (this) rszei, a bennk tallhat elemek is megjelennek az ablakon. this.Controls.Add(gboxSex); this.Controls.Add(gboxAge); this.gboxSex.Controls.Add(rdMale); this.gboxSex.Controls.Add(rdFemale); this.gboxAge.Controls.Add(rdYouth); this.gboxAge.Controls.Add(rdAdult); A vlasztgombokat a csoportmezkbe helyezssel kln trolkba tettk. Ennek eredmnyekppen, ha futtatjuk a kdot, lthatjuk, hogy a Sex s Age kategrik nincsenek hatssal egymsra. Lehetsgnk van arra is, hogy tudatos kapcsolatot teremtsnk a kt kategria kztt; ehhez a vezrlknek egyms tulajdonsgait kell mdostaniuk.
Listamezk hasznlata
Az ablakon gyakran hasznlatos vezrl a listamez (ListBox), amely lehetv egy kismret mezben sok elemet soroljunk fel. Bellthatjuk gy, hogy a grgethesse a tartalmt s akkor tbb elemet is kivlaszthasson. Mivel a tulajdonsgainak belltsa kiss sszetettebb feladat, mint a korbbiakban vezrlk esetben, rdemes elidznnk itt egy kicsit. teszi, hogy felhasznl listamezk bemutatott
A listamezk ksztse pontosan ugyangy trtnhet, mint ms, eddig megismert vezrlk. Elszr ablakunk rszeknt bevezetjk a listamezt: private ListBox myListBox; Ezutn kvetkezhet a pldnyosts: myListBox = new ListBox(); Termszetesen e kt utastst egy sorba is rhattuk volna: private ListBox myListBox = new ListBox(); Ha elkszltnk, akkor ideje, hogy elhelyezzk az ablakon, ppen gy, mint ms trsait: This.Controls.Add(myListBox); A listt azonban fel kell tltennk elemekkel. (Egybknt mire is hasznlnnk?) Itt mr nem kapaszkodhatunk az korbban tanultakba. Az elemek beillesztse tbb lpsbl ll folyamat. Mindenekeltt tudatnunk kell a listamezvel, hogy tartalmt frissteni szeretnnk. Ehhez meg kell hvnunk a BeginUpdate tagfggvnyt a myListBox esetben ez a kvetkezkppen nz ki: myListBox.BeginUpdate();
198
C# Amit a C# tudni rdemes! Ha ezzel elkszltnk, szabad az t az elemek beillesztshez. Ne gondoljunk itt valami bonyolult dologra, mindssze a listamez Item tagjnak Add tagfggvnyt kell hasznlnunk: myListBox.Items.Add("Els elem"); myListBox.Items.Add("Msodik elem"); myListBox.Items.Add("Harmadik elem"); Ha befejeztk az elemek beillesztst, kzlnnk kell a listamezvel, hogy elkszltnk. Erre szolgl az EndUpdate tagfggvny: myListBox.EndUpdate(); Nzzk meg ezt az egszet egy teljes kdsorban: 4.11 Listamezk hasznlata
using System.Windows.Forms; using System.Drawing; public class GetName : Form { private Button btnOK; private Label lblFullName; private TextBox txtFullName; private ListBox lboxSex; private Label lblSex; private ListBox lboxAge; public GetName() { InitializeComponent(); } private void InitializeComponent() { this.FormBorderStyle = FormBorderStyle.Fixed3D; this.Text = "Get User Info"; this.StartPosition = FormStartPosition.CenterScreen; lblFullName txtFullName btnOK lblSex lboxSex lboxAge = = = = = = new new new new new new Label(); TextBox(); Button(); Label(); ListBox(); ListBox();
lblFullName.Location = new Point(20, 40); lblFullName.AutoSize = true; lblFullName.Text = "Name:"; txtFullName.Width = 170; txtFullName.Location = new Point(80, 40); btnOK.Text = "Done";
199
lboxAge.Location = new Point(80, 100); lboxAge.Size = new Size(100, 60); lboxAge.SelectionMode = SelectionMode.One; lboxAge.BeginUpdate(); lboxAge.Items.Add(" "); lboxAge.Items.Add(" Under 21 "); lboxAge.Items.Add(" 21 "); lboxAge.Items.Add(" Over 21 "); lboxAge.EndUpdate(); lboxAge.SelectedIndex = 0; this.Controls.Add(btnOK); this.Controls.Add(lblFullName); this.Controls.Add(txtFullName); this.Controls.Add(lboxSex); this.Controls.Add(lblSex); this.Controls.Add(lboxAge); btnOK.Click += new System.EventHandler(this.btnOK_Click); } protected void btnOK_Click( object sender, System.EventArgs e) { Application.Exit(); } public static void Main( string[] args ) { Application.Run( new GetName() ); }
200
A ListBox vezrl kivlasztsi mdjai Md Lersa SelectionMode.One Egyszerre csak egy elem vlaszthat. SelectionMode.MultiExtended Egyszerre tbb elem vlaszthat, s a vlasztshoz hasznlhatjuk a Shift, Ctrl s nylbillentyket is. SelectionMode.MultiSimple Egyszerre tbb elem vlaszthat. SelectionMode.None Egyetlen elem sem vlaszthat. A listamezk minden ms tulajdonsgukban gy viselkednek, mint a vezrlk ltalban. Esemnyek tjn rteslhetnk arrl, ha a felhasznl ms elemet vlasztott, vagy ha elhagyta a vezrlt. rhatunk olyan kdot is, amely biztostja, hogy a felhasznl vlasszon a lehetsgek kzl, de szmos ms lehetsgnk is van.
Menk az ablakokon
Az ablakok lv ttelre nem csak a vezrlk adnak lehetsget, hasznlhatunk menket is. A legtbb ablakos alkalmazsokban ignybe veszik ezt a lehetsget, legalbb egy Fjl vagy Sg men erejig, melyek kivlasztsuk esetben ltalban adnak nhny menpontot. Ablakainkon magunk is hasznlhatunk menket. Nzzk megint azt a pldt, amikor egy gomb segtsgvel frisstettk az ablakon megjelen dtumot. rjuk t ezt a kdot olyanra, hogy men segtsgvel frisstsk a dtumot: 4.12 Egyszer men ksztse
using System; using System.Windows.Forms; using System.Drawing; public class Menu : Form { private Label myDateLabel; private MainMenu myMainMenu;
201
DateTime currDate = new DateTime(); currDate = DateTime.Now; myDateLabel.Text = currDate.ToString(); myDateLabel.AutoSize = true; myDateLabel.Location = new Point( 50, 70); myDateLabel.BackColor = this.BackColor; this.Controls.Add(myDateLabel); // Add label to form
this.Width = (myDateLabel.PreferredWidth + 100); myMainMenu = new MainMenu(); MenuItem menuitemFile = myMainMenu.MenuItems.Add("File"); menuitemFile.MenuItems.Add(new MenuItem("Update Date", new EventHandler(this.MenuUpdate_Selection))); menuitemFile.MenuItems.Add(new MenuItem("Exit", new EventHandler(this.FileExit_Selection))); this.Menu = myMainMenu; } protected void MenuUpdate_Selection( object sender, System.EventArgs e ) { DateTime currDate = new DateTime(); currDate = DateTime.Now; this.myDateLabel.Text = currDate.ToString(); } protected void FileExit_Selection( object sender, System.EventArgs e ) { this.Close(); } public static void Main( string[] args ) { Application.Run( new Menu() ); }
202
Az ablak elsdleges menjt fmennek hvjuk, amely jelen esetben a File pontot tartalmazza, de msok is lehetnek rajta. A kdban egy myMainMenu nev MainMenu objektumot hozunk ltre. Ha tzetesebben megnzzk a kdot, ltjuk, hogy mennyi minden trtnik benne. Egy j, menuitemFile nev tagot vezettnk be, majd hozzrendeljk a myMainMenu objektumhoz adott j elemet. Az j elem hozzadsnak kdjt rdemes kln is lernunk: myMainMenu.MenuItems.Add("File"); Vagyis fmennek egy File nev elemet adunk. ltalnosabban fogalmazva az itt ltottakat elmondhatjuk, hogy a MenuItems.Add tagfggvnyt, meghvhatjuk akr egy men, akr egy menelem esetben. Ha fmenben tesszk, egy menhz jutunk, mg ha egy menpontban hvjuk meg ezt a tagfggvnyt, egy almen elemt illesztjk be. Ha a MenuItems.Add tagfggvnynek egy paramtert adunk t, akkor gy veszi, hogy a menpont szvegt szeretnnk megadni. Lthat, hogy tallunk olyan tagfggvnyhvst, melynek kt paramtert adunk t. Az els a menpont neve, a msodik pedig egy j esemnykezel. Ezt hvja meg a rendszer, ha a felhasznl a menpontot vlasztja. Kszthetnk olyan ment is, amelyik gyorsbillenty hatsra is mkdik. Ehhez nem kell mst csinlni, mint a men azon betje el rni egy & jelet, amit ki szeretnnk vlasztani, s a kdot kiegszteni a ShortCut adattpussal, amely lehetv teszi, hogy ltalban a ShortCut.Ctrl * jellst hasznljuk, ahol a * helyn tetszleges bet llhat.
203
C# Amit a C# tudni rdemes! Nzzk meg, hogy is nz ez ki: MenuItem menuitemFile = myMainMenu.MenuItems.Add("&File"); menuitemFile.MenuItems.Add(new MenuItem("Update &Date", new EventHandler(this.MenuUpdate_Selection), Shortcut.CtrlD)); menuitemFile.MenuItems.Add(new MenuItem("E&xit", new EventHandler(this.FileExit_Selection), Shortcut.CtrlX)); MenuItem menuitemHelp = myMainMenu.MenuItems.Add("&Help"); menuitemHelp.MenuItems.Add(new MenuItem("&About", new EventHandler(this.FileAbout_Selection))); Az elz kdsorba helyettestsk be azt a fenti kdsort, akkor a kvetkez kimenetet kapjuk:
Bejellhet menelemek
A menk ismert s szles krben elterjedt lehetsge, hogy elemeiket bejellssel, ki- vagy bekapcsolhatjuk. A kvetkez kdszvegben bemutatjuk, miknt pthetjk be ezt a lehetsget meninkbe, tovbb egy j mdszert is adunk a menk bevezetsre s meghatrozsra: 4.13 Menpontok bejellse
using System; using System.Windows.Forms; using System.Drawing; public class CheckedMenu : Form {
204
public CheckedMenu() { InitializeComponent(); } private void InitializeComponent() { this.Text = "STY Menus"; this.StartPosition = FormStartPosition.CenterScreen; this.FormBorderStyle = FormBorderStyle.Sizable; myDateLabel = new Label(); // Create label
DateTime currDate = new DateTime(); currDate = DateTime.Now; myDateLabel.Text = currDate.ToString(); myDateLabel.AutoSize = true; myDateLabel.Location = new Point( 50, 70); myDateLabel.BackColor = this.BackColor; this.Controls.Add(myDateLabel); // Set width of form based on Label's width this.Width = (myDateLabel.PreferredWidth + 100); } CreateMyMenu();
protected void MenuUpdate_Selection( object sender, System.EventArgs e) { if( menuitemActive.Checked == true) { DateTime currDate = new DateTime(); currDate = DateTime.Now; this.myDateLabel.Text = currDate.ToString(); } else { this.myDateLabel.Text = "** " + this.myDateLabel.Text + " **"; } } protected void FileExit_Selection( object sender, System.EventArgs e) { Application.Exit(); } protected void FileAbout_Selection( object sender, System.EventArgs e)
205
public void CreateMyMenu() { myMainMenu = new MainMenu(); // FILE MENU menuitemFile = myMainMenu.MenuItems.Add("&File"); menuitemUD = new MenuItem(); menuitemUD.Text = "Update &Date"; menuitemUD.Shortcut = Shortcut.CtrlD; menuitemUD.Click += new EventHandler(this.MenuUpdate_Selection); menuitemFile.MenuItems.Add( menuitemUD ); menuitemExit = new MenuItem(); menuitemExit.Text = "E&xit"; menuitemExit.Shortcut = Shortcut.CtrlX; menuitemExit.ShowShortcut = false; menuitemExit.Click += new EventHandler(this.FileExit_Selection); menuitemFile.MenuItems.Add( menuitemExit ); // HELP MENU menuitemHelp = myMainMenu.MenuItems.Add("&Help"); menuitemActive = new MenuItem(); menuitemActive.Text = "Active"; menuitemActive.Click += new EventHandler(this.ActiveMenu_Selection); menuitemActive.Checked = true; menuitemHelp.MenuItems.Add( menuitemActive ); menuitemAbout = new MenuItem(); menuitemAbout.Text = "&About"; menuitemAbout.Shortcut = Shortcut.CtrlA; menuitemAbout.ShowShortcut = false; menuitemAbout.Click += new EventHandler(this.FileAbout_Selection); menuitemHelp.MenuItems.Add( menuitemAbout ); this.Menu = myMainMenu; } public static void Main( string[] args ) { Application.Run( new CheckedMenu() ); } }
206
A korbbiaktl eltren az osztlymeghatrozs elejn nem csak a MainMenu objektumot s a tbbi legfels szint menpontot vezetjk be, hanem az sszes, az ablakon elfordul menelemet. A korbbiakkal megegyez mdon a men ltrehozsnak kdjt most is kln tagfggvnybe helyeztk. A kd mindemellett tartalmaz egy msik jdonsgot is. A Help men Active pontjt ugyanis ki- s bekapcsolhatjuk. Ha bekapcsoljuk, a dtumot s az idt frissthetjk a msik men Update Date pontjval, mg ha kikapcsoljuk, a dtum s az id csillagok kzt jelenik meg az ablakon. Minderre a menelem Checked tulajdonsga knl lehetsget, valamint nmi kd a menelem esemnykezeljben. Ebben az esemnykezelben nincs semmi jdonsg, mgis rdemes foglalkoznunk vele. Hasonlan ms esemnykezelkhz, az els paramter itt is az esemnyt kivlt objektum, melynek tpusa menelemrl lvn sz MenuItem. Ksztnk egy ideiglenes MenuItem tpus vltozt, s a paramter rtkt ebbe helyezzk. Ezentl a tmp nev vltoz segtsgvel rhetjk el a MenuItem osztly tulajdonsgait s tagfggvnyeit. Tudjuk azt is, hogy esemnynket az Active menpont kivlasztsa vltotta ki. Megvizsgljuk, hogy a menpont Checked tulajdonsgnak rtke igaz-e. Ha igen, akkor hamisra lltjuk, ha pedig nem, akkor igazra. Tagfggvnynk teht ki-be kapcsolgatja az Active menpontot. A MenuUpdate esemnykezelt szintn mdostottuk nmileg. j alakjban kirja az aktulis dtumot s az idt, ha az Active menpontot a felhasznl bejellte, mg ellenkez esetben csillagok kztt rja ki a korbbi rtket. Az esemnykezel lnyege nem abban rejlik, hogy mit r ki igazn fontos az, hogy kpesek vagyunk kezelni a menpontok jellst.
207
protected void PopUp_Selection( object sender, System.EventArgs e) { this.Text = ((MenuItem) sender).Text; } private void CreatePopUp() { myPopUp = new ContextMenu(); myPopUp.MenuItems.Add("First Item", new EventHandler(this.PopUp_Selection)); myPopUp.MenuItems.Add("Second Item", new EventHandler(this.PopUp_Selection)); myPopUp.MenuItems.Add("-"); myPopUp.MenuItems.Add("Third Item", new EventHandler(this.PopUp_Selection)); this.ContextMenu = myPopUp; } public static void Main( string[] args ) { Application.Run( new PopUp() ); }
208
A kdban lthatjuk, hogy ha helyi ment szeretnnk kszteni, a MainMenu helyett a ContextMenu osztlyt kell hasznlnunk. Itt ksztettnk egy myPopUp vltozt. Az elemek beillesztse ugyangy trtnik, mint a MainMenu osztly esetben; itt is a MenuItem.Add tagfggvnyt kell hasznlnunk. Programunkban ngy elemet helyeznk a helyi menbe. Az els, a msodik s a negyedik semmifle meglepetssel nem szolgl, de a harmadik elem klnleges. Els ltsra gy ltszik, mintha egy egyszer elvlasztjelet illesztennk be menpont gyannt a valsgban azonban egy, a ment teljes szlessgben tr vonal keletkezik. Ha minden elemet beillesztettnk a myPopUp objektumba, a men az aktulis ablak helyi menjv vlik. Azt is szre vehetjk, hogy a hrom menelem ugyanazt a PopUp_Selection esemnykezelt hasznlja.
A MessageBox osztly
A Windows programozsa sorn gyakran lehet szksgnk zenetablakok hasznlatra, ezrt nem meglep, hogy ltezik szmukra egy osztly a BCL-ben is. Ez lehetv teszi, hogy zeneteket egy elugr ablakban jelentsk meg ezt tesszk a kvetkez kdban: 4.15 A MessageBox osztly hasznlata
using System; using System.Windows.Forms; using System.Drawing; public class MsgBox : Form { private ContextMenu myPopUp; public MsgBox() { MessageBox.Show( "You have started the application.", "Status"); InitializeComponent(); CreatePopUp(); MessageBox.Show( "Form has been initialized.", "Status"); }
209
public static void Main( string[] args ) { Application.Run( new MsgBox() ); MessageBox.Show( "You are done with the application", "Status"); } }
210
C# Amit a C# tudni rdemes! A kd egyetlen MessageBox objektumot hasznl, melyet klnbz tartalommal a program ms ms pontjn jelent meg. A MessageBox legegyszerbb alakjban egy olyan prbeszdablakot ad, melyen egy megadott szveg, valamit egy OK gomb szerepel, de emellett megadhatjuk a cmsort is. A MessageBox osztly Show tagfggvnye kt paramtert fogad. Az els a megjelentend zenet, mg a msodik a cmsor tartalma.
public class Canned : Form { private MainMenu myMainMenu; public Canned() { InitializeComponent(); } private void InitializeComponent() { this.Text = "Canned Dialogs"; this.StartPosition = FormStartPosition.CenterScreen; this.FormBorderStyle = FormBorderStyle.Sizable; this.Width = 400; myMainMenu = new MainMenu(); MenuItem menuitemFile = myMainMenu.MenuItems.Add("&File"); menuitemFile.MenuItems.Add(new MenuItem("Colors Dialog", new EventHandler(this.Menu_Selection))); menuitemFile.MenuItems.Add(new MenuItem("Fonts Dialog", new EventHandler(this.Menu_Selection))); menuitemFile.MenuItems.Add(new MenuItem("Print Preview Dialog", new EventHandler(this.Menu_Selection))); menuitemFile.MenuItems.Add("-"); menuitemFile.MenuItems.Add(new MenuItem("Exit", new EventHandler(this.Menu_Selection)));
211
protected void Menu_Selection( object sender, System.EventArgs e ) { switch (((MenuItem) sender).Text ) { case "Exit": Application.Exit(); break; case "Colors Dialog": ColorDialog myColorDialog = new ColorDialog(); myColorDialog.ShowDialog(); break; case "Fonts Dialog": FontDialog myFontDialog = new FontDialog(); myFontDialog.ShowDialog(); break; case "Print Preview Dialog": PrintPreviewDialog myPrintDialog = new PrintPreviewDialog(); myPrintDialog.ShowDialog(); break; default: MessageBox.Show("DEFAULT", "PopUp"); break; } }
Lthatjuk, milyen egyszeren bepthetjk programjainkba, a ltvnyos eredmnyt pedig a kvetkez brkon lthatjuk:
212
protected void Menu_Selection( object sender, System.EventArgs e ) { switch (((MenuItem) sender).Text ) { case "Exit": Application.Exit(); break; case "My Form": subForm aForm = new subForm(); aForm.Text = "A Show form"; aForm.Show(); break; case "My Other Form": subForm bForm = new subForm(); bForm.Text = "A ShowDialog form"; bForm.ShowDialog(); break; default: MessageBox.Show("DEFAULT", "PopUp"); break; } }
214
public class subForm : Form { private MainMenu mySubMainMenu; public subForm() { InitializeComponent(); } private void InitializeComponent() { this.Text = "My sub-form"; this.StartPosition = FormStartPosition.CenterScreen; this.FormBorderStyle = FormBorderStyle.FixedDialog; this.Width = 300; this.Height = 250; mySubMainMenu = new MainMenu(); MenuItem menuitemFile = mySubMainMenu.MenuItems.Add("&File"); menuitemFile.MenuItems.Add(new MenuItem("Close", new EventHandler(this.CloseMenu_Selection))); this.Menu = mySubMainMenu;
215
Felhasznlt irodalom
1. Programming C#, 2nd Edition Szerz: Jesse Liberty, Kiad: OReilly, 2. C# Essentials, 2nd Edition Szerz: Ben Albahari, Peter Drayton, Brad Merrill Kiads ve: 2001. Kiads ve: 2002. Kiad: OReilly,
3. C#, Your visual blueprint for building .NET applications by Eric Butow, Tommy Rayn Szerz: Eric Butow, Tommy Rayn Kiad:Hungry Minds Inc. Kiads ve: 2002. 4. C#.NET Web Developers Guide Szerz:Adrian Turtschi DotThatCom.com Jason Werry Greg Hack Joseph Albahari Saurabh Nandu Technical Editor Wei Meng Lee Series Editor Kiad: Syngress Publishing, Inc. Kiads ve: 2002. 5. Designing Microsoft ASP.NET Applications Szerz: Douglas J. Reilly Kiad: Microsoft Press 6. Programming Microsoft Windows with C# Szerz: Charles Petzold Kiad: Microsoft Press Kiads ve: 2002. Kiads ve: 2002.
7. Teach Yourself The C# Language in 21 Days Szerz:Bradley L. Jones Kiad: Pearson Education Inc. Kiads ve: 2004.
216