You are on page 1of 200

11

ILLS ZOLTN

Programozs C# nyelven

JEDLIK OKTATSI STDI


Budapest, 2005

I. Alapismeretek

Minden jog fenntartva. Ezt a knyvet vagy annak rszleteit a kiad engedlye nlkl brmilyen formban vagy eszkzzel reproduklni, trolni s kzlni tilos. A knyv ksztse sorn a kiad s a szerz a legnagyobb gondossggal jrt el. Az esetleges hibkat s szrevteleket a jos@jos.hu e-mail cmen szvesen fogadjuk.

Szakmailag ellenrizte: Heizlern Bakonyi Viktria, ELTE Anyanyelvi lektor: Gulysn Felkai gnes Bort: Sarkadi Csaba, 2004 Kiad: Jedlik Oktatsi Stdi Bt. 1212 Budapest, Tncsics M. u. 92. Internet: http://www.jos.hu E-mail: jos@jos.hu Felels kiad: a Jedlik Oktatsi Stdi Bt. cgvezetje

Nyomta: LAGrade Kft. Felels vezet: Szutter Lnrd

ISBN: 963 86514 1 5 Raktri szm: JO 0331

Bevezet ................................................................................................... 11 I. Alapismeretek ....................................................................................... 13 I.1. A nyelv trtnete............................................................................ 13 I.2. A nyelv jellemzi........................................................................... 13 I.3. A .NET krnyezet ttekintse ........................................................ 15 I.4. A program szerkezete .................................................................... 16 I.5. Parancssori krnyezet hasznlata................................................... 20 I.6. A krnyezet hasznlata .................................................................. 21 I.7. Windows alkalmazsok ksztse .................................................. 25 I.8. Feladatok........................................................................................ 27 II. A C# nyelv alaptpusai ........................................................................ 28 II.1. Vltozk definilsa ..................................................................... 28 II.2. llandk definilsa ..................................................................... 29 II.3. Vltozk inicializlsa.................................................................. 29 II.4. Elemi tpusok................................................................................ 30 II.5. Felsorols tpus ............................................................................. 35 II.6. Feladatok ...................................................................................... 37 III. Kifejezsek, mveletek ...................................................................... 38 III.1. Egyoperandus opertorok.......................................................... 38 III.2. Ktoperandus opertorok .......................................................... 39 III.3. Hromoperandus opertor ......................................................... 42 III.4. Ktoperandus rtkad opertorok............................................ 43 III.5. Feladatok ..................................................................................... 46 IV. sszetett adattpusok.......................................................................... 47 IV.1. Tmbk ....................................................................................... 47 IV.2. Struktra...................................................................................... 51 IV.3. Feladatok..................................................................................... 54 V. Utastsok ............................................................................................ 56 V.1. sszetett utasts .......................................................................... 56 V.2. Kifejezs utasts.......................................................................... 56 V.3. Elgazs utasts........................................................................... 57 V.4. Ciklus utasts............................................................................... 59 V.5. Ugr utastsok............................................................................. 63 V.6. Feladatok ...................................................................................... 67 VI. Fggvnyek........................................................................................ 68 VI.1. A fggvnyek paramtertadsa ................................................. 68 VI.2. A Main fggvny paramterei .................................................... 72 VI.3. Fggvnyek vltoz szm paramterrel.................................... 74

I. Alapismeretek

VI.4. Fggvnynevek tdefinilsa...................................................... 75 VI.5. Delegltak, esemnyek................................................................ 77 VI.6. Feladatok..................................................................................... 80 VII. Osztlyok .......................................................................................... 81 VII.1. Osztlyok definilsa................................................................. 82 VII.2. Konstruktor- s destruktor fggvnyek ..................................... 84 VII.3. Konstans, csak olvashat mezk ............................................... 92 VII.4. Tulajdonsg, index fggvny..................................................... 94 VII.5. Osztlyok fggvnyparamterknt ............................................ 97 VII.6. Opertorok jradefinilsa......................................................... 98 VII.7. Interface definilsa................................................................. 104 VII.8. Osztlyok rkldse............................................................... 107 VII.9. Vgleges s absztrakt osztlyok .............................................. 110 VII.10. Virtulis tagfggvnyek, fggvnyelfeds ............................ 112 VII.11. Feladatok................................................................................ 117 VIII. Kivtelkezels ............................................................................... 118 VIII.1. Kivtelkezels hasznlata....................................................... 118 VIII.2. Sajt hibatpus definilsa ...................................................... 121 VIII.3. Feladatok ................................................................................ 125 IX. Input-Output..................................................................................... 126 IX.1. Standard input-output................................................................ 126 IX.2. Fjl input output ..................................................................... 129 IX.3. Feladatok................................................................................... 133 X. Prhuzamos programvgrehajts....................................................... 134 X.1. Szlak definilsa ....................................................................... 134 X.2. Szlak vezrlse ......................................................................... 135 X.3. Szlak szinkronizlsa................................................................ 138 X.4. Feladatok .................................................................................... 143 XI. Attribtumok.................................................................................... 144 XI.1. Attribtumok definilsa........................................................... 145 XI.2. Attribtumok hasznlata ........................................................... 146 XI.3. Knyvtri attribtumok............................................................. 151 XI.4. Feladatok................................................................................... 152 XII. Szabvnyos adatments .................................................................. 153 XII.1. Knyvtri tpusok szabvnyos mentse................................... 153 XII.2. Sajt tpusok szabvnyos mentse ........................................... 155 XII.3. Feladatok.................................................................................. 158 XIII. Knyvtrak, tvoli s web knyvtrak .......................................... 159 XIII.1. Helyi knyvtrak hasznlata .................................................. 159

XIII.2. Tvoli knyvtrhvs.............................................................. 162 XIII.3. Webknyvtrak hasznlata..................................................... 168 XIII.4. Feladatok ................................................................................ 173 XIV. Az elfeldolgoz ........................................................................... 174 XIV.1. Szimblumdefinci hasznlata ............................................. 174 XIV.2. Terleti jells........................................................................ 175 XIV.3. Feltteles fordts ................................................................... 176 XIV.4. Hibazenet.............................................................................. 176 XIV.5. Feladatok ................................................................................ 176 XV. Nem felgyelt kd hasznlata ........................................................ 177 XV.1. Nem felgyelt knyvtr elrse............................................... 177 XV.2. Mutatk hasznlata.................................................................. 178 XV.3. Feladatok ................................................................................. 179 XVI. Grafikus alkalmazsok alapjai ...................................................... 180 XVI.1. Windows alkalmazsok alapjai .............................................. 180 XVI.2. Webes alkalmazsok alapjai .................................................. 185 XVI.3. Feladatok ................................................................................ 189 Irodalomjegyzk..................................................................................... 190

Bevezet
Valamilyen programot megrni nem nehz, de j programot rni bizony nem egyszer feladat. Nehz lenne megmondani, hogy melyik az aranyt, amely a j programkszts iskoljnak tekinthet, de az bizonyosan llthat, hogy j s hatkony programot csakis megfelel fejlesztsi krnyezetben tudunk kszteni. Mai rohan vilgunkban a gyors gazdasgi, trsadalmi vltozsok mellett is szembetl, mennyire gyors, milyen dinamikus a vltozs az informatikban. Nem telik el gy hnap, hogy az informatika valamelyik terletn be ne jelentennek valamilyen jdonsgot, legyen az hardver, vagy szoftver. A szoftver fejlesztsi krnyezeteket tekintve az utbbi idk egyik legnagyobb s legtbb jdonsgot hoz egysgcsomagjt kaptk meg a fejlesztk az j Microsoft .NET rendszerrel. Ebben a krnyezetben, brmilyen terletre gondolunk, j technolgik, j lehetsgek segtik a fejlesztk munkjt (Common Language Runtime (clr), ASP.NET, stb.). Ismerjk mr: j msorhoz j frfi kell. Ezt az elvet alkalmazva a mr klasszikusnak tekinthet Basic s C++ nyelvek mellett megjelent az j C# (ejtsd: angolosan sz srp, magyarosan C kettskereszt, Cisz) programozsi nyelv a .NET rendszer rszeknt. A nyelv mottjnak taln a kvetkez kpletet tekinthetjk: A Basic egyszersge + a C++ hatkonysga = C#! Ebben a knyvben a fejlesztsi eszkztrnak ezt az alapjt, a C# programozsi nyelvet, annak lehetsgeit ismerhetik meg. Terveim szerint egy kvetkez knyvben a nyelv legfontosabb krnyezetbeli alkalmazsi lehetsgeit rszletesen trgyalni fogjuk. Remlem, hogy ez a knyv szles olvastbornak fog hasznos informcikat nyjtani. A programozssal most ismerkedknek egy j vilg j eszkzt mutatja meg, mg a programozsban jrtas Olvask taln ennek a knyvnek a segtsgvel megrzik azt, hogy ez az a nyelv, amit kerestek. Befejezsl remlem, hogy a magyarzatokhoz mellkelt pldaprogramok jl szolgljk a tanulsi folyamatot, s az anyag szerkesztse folytn nem kerltek bele nemkvnatos elemek. Vgl, de nem utolssorban meg kell ksznnm felesgemnek e knyv olvashatsgt segt munkjt. Ills Zoltn

11

I. Alapismeretek

I. Alapismeretek
I.1. A nyelv trtnete
A C# programozsi nyelv a Microsoft j fejlesztsi krnyezetvel, a 2002-ben megjelent Visual Studio.NET programcsomaggal, annak rszeknt jelent meg. Br a nyelv hossz mlttal nem rendelkezik, mindenkppen eldjnek tekinthetjk a C++ nyelvet, a nyelv szintaktikjt, szerkezeti felptst. A C, C++ nyelvekben kszlt alkalmazsok elksztshez gyakran hoszszabb fejlesztsi idre volt szksg, mint ms nyelvekben, pldul a MS Visual Basic esetn. A C, C++ nyelv komplexitsa, a fejlesztsek hosszabb idciklusa azt eredmnyezte, hogy a C, C++ programozk olyan nyelvet keressenek, amelyik jobb produktivitst eredmnyez, ugyanakkor megtartja a C, C++ hatkonysgt. Erre a problmra az idelis megolds a C# programozsi nyelv. A C# egy modern objektumorientlt nyelv, knyelmes s gyors lehetsget biztostva ahhoz, hogy .NET keretrendszer al alkalmazsokat ksztsnk, legyen az akr szmols, akr kommunikcis alkalmazs. A C# s a .NET keretrendszer alapja a Common Language Infrastructure(CLI).

I.2. A nyelv jellemzi


A C# az j .NET keretrendszer bzisnyelve. Tipikusan ehhez a keretrendszerhez terveztk, nem vletlen, hogy a szabvnyostsi azonostjuk is csak egy szmmal tr el egymstl. A nyelv teljesen komponens orientlt. A fejlesztk szmra a C++ hatkonysgt, s a Visual Basic fejleszts gyorsasgt, egyszersgt tvztk ebben az eszkzben. A C# nyelv legfontosabb elemei a kvetkezk: Professzionlis, Neumann-elv. Nagy programok, akr rendszerprogramok rsra alkalmas. A program tbb fordtsi egysgbl modulbl vagy fjlbl ll. Minden egyes modulnak vagy fjlnak azonos a szerkezete. Egy sorba tbb utasts is rhat. Az utastsok lezr jele a pontosvessz (;). Minden vltozt deklarlni kell. Vltozk, fggvnyek elnevezsben az kezetes karakterek hasznlhatak, a kis- s nagybetk klnbzek.

13

I. Alapismeretek A keretrendszer fordtsi parancsa parancssorbl is egyszeren hasznlhat. (pl. csc /out:alma.exe alma.cs). Minden utasts helyre sszetett utasts (blokk) rhat. Az sszetett utastst a kapcsos zrjelek kz {} rt utastsok definiljk. rtk (alaptpusok, enum, struct, value) illetve referencia (class) tpus vltozk. Nincs mutathasznlat; biztonsgos a vektorhasznlat. Boxing, unboxing. Minden tpus se az object, gy pldul egy egsz tpust (int) csomagolhatunk objektumba (boxing) illetve vissza (unboxing). Fggvnyek defincii nem gyazhatk egymsba, nmagt meghvhatja (rekurzi). Teht fggvnydefinci esetn nincs blokkstruktra. Blokkon bell statikus vagy dinamikus lettartam vltozk deklarlhatk. Fggvnypolimorfizmus megengedett. rtk, referencia (ref) s output (out) fggvnyparamterek. Kezd paramter-rtkads, vltoz paramterszm fggvny deklarlsa. Delegltak, esemnyek hasznlata. Hierarchikus nvterekben hasznlt osztlyok. Mivel minden osztly, ezrt a program, a Main fggvny public static hozzfrs. Tbb osztly is tartalmazhat Main fggvnyt, de ilyen esetben a fordtskor meg kell mondani, hogy melyik osztlybeli Main fggvny legyen az aktulis indul (/main:osztlynv). j opertorok: is opertor egy objektum tpust ellenrzi (x is Labda), as opertor a bal oldali operandust jobb oldali tpuss konvertlja (Labda l = x as Labda;). A hagyomnyos konverzis opertortl abban klnbzik, hogy nem generl kivtelt! Privt konstruktor (nem akarunk egy pldnyt se), statikus konstruktor (statikus mezk inicializlsa, mindig pldny konstruktor eltt hvdik meg, futsi idben az osztlybetlt hvja meg) hasznlata. Nincs destruktor, helyette a keretrendszer szemtgyjtsi algoritmusa van. Szksg esetn az osztly Dispose metdusa jradefinilhat. Egyszeres rkls, interface-ek hasznlata. Opertorok definilsnak lehetsge, property, indexer definils. Kivtelkezels megvalstsa. Prhuzamos vgrehajts szlak definilhatsga.

I. Alapismeretek

I.3. A .NET krnyezet ttekintse


A Visual Studio 6.0 fejlesztrendszer tdolgozsaknt 2002-ben jelent meg a Microsoft legfrissebb fejleszteszkze. Utalva a lnyeges vltoztatsokra, a hlzati munka integrlsra, a fejleszteszkz a Visual Studio.NET nevet kapta. Jelenleg az eszkz 2003-as frisstse a legutols verzi. A knyv szempontjbl nincs lnyeges klnbsg a kt verzi kztt, gy nem is trnk ki a klnbsgek bemutatsra. Az j eszkz a korbbi fejlesztrendszerekkel ellenttben nem a hagyomnyosnak tekinthet n. Win32 alap, hanem a .NET krnyezet alatt futtathat alkalmazsokat kszt. Ez azt jelenti, hogy az j eszkzzel kszlt alkalmazsok csak olyan opercis rendszer alatt futtathatk, melyek tmogatjk a .NET keretrendszert (.NET Framework). Alaprtelmezsknt a jelenlegi opercis rendszerek egyike sem tmogatja ezt, viszont Windows 98 opercis rendszertl felfel utlag feltelepthet. A fordt a forrskdot nem natv, hanem egy kztes kdra fordtja le. Ezt a kztes kdot MSIL (Microsoft Intermediate Language) nven szoktk emlteni. A Visual Studio.NET teleptse teht a keretrendszer teleptsvel kezddik. A .NET keretrendszer legfontosabb ernyei: Webszabvnyokon alapul (XML, HTML, SOAP). Univerzlis alkalmazsi modellt hasznl, azaz egy .NET osztly, szolgltats tetszleges .NET kompatibilis nyelvbl hasznlhat. A .NET kompatibilitst a Common Language Specification (CLS) definilja. Minden nyelvbl ugyanazok a tpusok hasznlhatk (Common Type System) Minden .NET osztly a fejlesztk rendelkezsre ll. A keretrendszer a fejleszteszkz szmra fordtsi idej szolgltatsokat vgez, mg az gy lefordtott alkalmazsoknak futsi idej krnyezetet biztost (Common Language Runtime). A keretrendszer biztostja a fentiek mellett az alkalmazsok szmra a mr nem hasznlt objektumok memriabeli felszabadtst (Garbage Collection). A keretrendszer osztlyknyvtra az alkalmazsok tpusa alapjn tbb csoportba oszthat: ADO.NET, adatbzis alkalmazsok j genercis knyvtra. ASP.NET, webes alkalmazsok (Web Forms) ksztsnek knytra. XML Web Service, interneten keresztl elrhet knyvtr. Windows alap felhasznli (Windows Forms, Console Application), alkalmazi knyvtr.

I. Alapismeretek Az osztlyknyvtrak hasznlathoz egy fejleszt nyelvre van szksg. A Visual Studio.NET alaprtelmezsben hrom nyelvet biztost a fejlesztk szmra. A Visual Basic s a Visual C++ nyelveket, mint az eld keretrendszerbl megmaradt bzisnyelveket, s egy j nyelvet, amit a .NET keretrendszerhez fejlesztettek ki, a Visual C#-ot. Ma mr a Java utdnyelv, a J# is a Visual Studio.NET 2003 fejlesztrendszer rsze. Az j C# nyelvet szabvnyostottk, ami a szleskr elterjedsnek fontos felttele. A C# nyelv szabvnyostott dokumentcijhoz ECMA-334 kd alatt frhetnk hozz. A .NET keretrendszer lnyege, hogy a kzs nyelvi defincik mr szabvnyostottak. Ebben a szabvnyostsban a Microsoft mellett az informatikban rdekelt legnagyobb szervezetek is (HP, Intel, IBM, Sun, Fujitsu, Netscape) rszt vettek. Ez ECMA-335-s azonostval, mint a kzs nyelvi infrastruktra vagy eredeti nevn Common Language Infrastucture (CLI) nemzetkzi szabvnyv vlt.

I.4. A program szerkezete


Egy C# program tetszleges szm fordtsi egysgbl (modulbl) llhat. Szoks ezen modulok vagy fjlok sszessgt projektnek nevezni. A program ezen modulokban definilt osztlyok sszessge. Egy fjl tartalmazza az egyes modulok kzti hivatkozsokat (using), osztlytpus-, vltoz- s fggvnydeklarcikat. Egy modul egy tetszleges nvtr rsze lehet. A nvtr (namespace) az a logikai egysg, amiben az azonostnknak egyedinek kell lennie. Nem ktelez a nvtr definilsa, ebben az esetben az n. nv nlkli nvtr rsze lesz az adott kd. Nvtr szerkezete: namespace j_nvtrnv { class j_osztlynv { Tpusdefinci; Fggvnydefinci; } }

I. Alapismeretek Fggvnyek defincijnak formja: visszaadott_tpus nv(argumentumlista, ha van) { vltoz defincik, deklarcik s utastsok } Az osztlyok egyikben kell egy Main nev fggvnynek szerepelnie, amely futtatskor az opercis rendszertl a vezrlst megkapja. A nyelv megengedi, hogy tbb tpusban (osztlyban) is definiljunk ilyen fggvnyt. Ebben az esetben fordtskor kell megmondani, hogy melyik tpus Main fggvnye legyen a fprogram. A programban hasznlt neveknek betvel vagy _ jellel kell kezddnik, majd a msodik karaktertl tetszleges bet s szm kombincija llhat. A nyelvben a kis- s nagybetk klnbzek, gy pldul a kvetkez kt nv sem azonos: alma aLma Az azonostnevek hossza ltalban 32 karakter lehet, de sok rendszerben az ignyeknek megfelelen lehet ezen vltoztatni. A .NET keretrendszer 16 bites unikd karakterbrzolst hasznl, amiben a magyar kezetes karakterek is benne vannak. A nyelvi fordt ezeket az kezetes betket is megengedi, gy az albbi nv is megengedett: krte Azonostk hasznlatra nem megengedettek a C#-ban a kvetkez kulcsszavak vagy vdett azonostk: abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public

I. Alapismeretek readonly short switch typeof ushort ref stackalloc this uint using return static throw ulong virtual sbyte string true unchecked void sealed struct try unsafe while

Egy forrsllomny szerkesztse sorn magyarzatokat is elhelyezhetnk a /* s */ jelek kztt. Az ilyen megjegyzs tbb soron t is tarthat. Egy soron bell a // jel utn rhatunk magyarzatot. A mai fejlesztkrnyezetekben egyltaln nem ritka, hogy valamilyen specilis megjegyzst arra hasznljanak fel, hogy ennek a programszvegbl trtn kigyjtsvel a forrsllomnynak vagy magnak a programnak egy dokumentcijt kapjk. Ezt a kigyjtst a fordt vgzi el. A C# fordtnak ha a /doc:fjlnv formban adunk egy fordtsi paramtert, akkor /// karakterek utni informcikat XML fjlba (a megadott nvvel) kigyjti. Ha nem parancssori fordtt hasznlunk, ami a Visual Studio.NET krnyezet hasznlatakor gyakran (majdnem mindig) elfordul, akkor ezt a belltst a projekt Tulajdonsgok dialgusablakban az XML Documentation File paramter rtkeknt llthatjuk be.

1. bra

Ha a keretrendszerben egy vltoz vagy fggvny defincija el beszrjuk a /// karaktereket, akkor azt a szvegszerkeszt automatikusan kiegszti a kvetkez formban:

I. Alapismeretek Plda:
/// <summary> /// ez egy vltoz /// </summary> int i; /// <summary> /// ez meg egy fggvny /// </summary> /// <param name="i"></param> public void szamol(int i) { }

A /** .*/ forma is megengedett, szintn dokumentcis clokra. Mivel az elz mdszer nem gyjti ki az ilyen formj megjegyzst, nem is hasznljk gyakran. Ezek alapjn nzzk meg a szoksosnak nevezhet bevezet programunk forrskdjt. Plda:
using System; class foci { static void Main() { Console.WriteLine("Hajr Fradi!"); } }

Programunk rvid magyarzataknt annyit mondhatunk, hogy a forrskdunk a legegyszerbb esetben egyetlen llomnybl ll, amiben nem definilunk nvteret, hanem csak egy foci osztlyt. (Valamilyen tpust kell definilnunk!) Ebben az osztlyban egyetlen fggvnyt definilunk, a programot jelent Main fggvnyt. Mivel egyetlen osztlytpus egyetlen pldnya sem ltezik a ltrehozsig (a definci mg nem ltrehozs!), ezrt ahhoz, hogy a fggvnynk pldny nlkl is ltezzen, a static jelzvel kell a hozzfrsi szintet meghatrozni. A C stlus nyelvek hagyomnyaknt a C# nyelvnek sem rszei a beolvas s kir utastsok, gy knyvtri szolgltatsokra kell hagyatkoznunk, ami a System nvtr rsze, s ennek a nvtrnek a Console osztlya biztostja a klasszikus kpernyre rs, Console.WriteLine() s billentyzetolvass, Console.ReadLine() feladatt.

I. Alapismeretek

I.5. Parancssori krnyezet hasznlata


A tetszleges szvegszerkesztvel megrt forrskdot egy alma.cs (a nyelv a cs kiterjesztst szereti) fjlba menthetjk, majd az albbi utastssal fordthatjuk le:
csc alma.cs

A fordts eredmnye egy alma.exe llomny lesz, amit futtatva a kperny kvetkez sorban lthatjuk kedvenc buzdt mondatunkat. Termszetesen akkor kapunk hibamentes fordtsi eredmnyt, ha a fordtnk s a knyvtrak hasznlathoz szksges tvonali, krnyezeti vltoz belltsok helyesek. Ezt a vcvars32.bat llomny elvgzi. Ilyen parancssori krnyezetet legknnyebben a Visual Studio.NET programcsoportbeli segdeszkzk kzl tudunk elindtani. (Ekkor lefut a vcvars32.bat, nem kell neknk kzzel indtani!)

2. bra

A parancssori fordtnak a /? paramterrel trtn futtatsa, mint egy segtsg funkci, megadja a fordt fontosabb kapcsolit. Ezek kzl a legfontosabbak a kvetkezk: /t:exe alaprtelmezs, exe llomnyt fordt. /t:library a fordtand llomny knyvtr (dll) lesz. /out:nv a fordts eredmnynek nevt hatrozhatjuk meg, alaprtelmezsben ez a nv megegyezik a fordtott fjl nevvel. /r:valami.dll egy knyvtr felhasznlsa fordtskor, ha tbb knyvtri llomnyt kell hozzfordtani, akkor az llomnynevek kz vesszt kell tenni. /main:osztlynv a nyelv megengedi, hogy tbb osztly is tartalmazzon Main fggvnyt, ekkor ezzel a kapcsolval mondhatjuk meg, hogy a sok Main fggvny kzl melyik legyen a fprogram.

I. Alapismeretek A keletkezett exe llomnyrl el kell mondani, hogy annak futtatshoz nem elegend egy hagyomnyos 32 bites Microsoft opercis rendszer, gyakran ezt gy fogalmazzk meg, hogy a keletkezett program nem natv kdot tartalmaz, hanem szksges az opercis rendszerhez hozztelepteni a .NET keretrendszert! Ezt termszetesen a Visual Studio.NET installlsa elvgzi, gy a sajt gpnkn nem tnik fel annak hinya sem. Az irodalom ezt az exe kdot gyakran menedzselt (managed) kdnak nevezi. ltalban elmondhat, hogy az j fejlesztkrnyezet minden egyes nyelvi eszkze olyan kdot fordt, aminek szksge van erre a keretrendszerre. Termszetesen mint az let minden terletn, gy itt is vannak kivtelek. Ilyen kivtel pldul a C++ nyelv, ahol alaprtelmezs szerint meg kell mondani, hogy a programunkat menedzselt vagy natv kdra fordtsa-e a fordtnk. Natv kd alatt rtjk azt a fordtott eredmnyt, ami processzor szint utastsokat tartalmaz. Ebben a fejlesztkrnyezetben ezt a kdot a menedzselt ellentteknt, nem menedzselt (unmanaged) kdnak is nevezik.

I.6. A krnyezet hasznlata


Mieltt a kvetkez rszben a nyelv rszletes jellemzinek ismertetst kezdennk, nzzk, hogy a felinstalllt Visual Studio.NET krnyezet segtsgvel mikppen tudjuk az eddigi egy, illetve a ksbbi pldaprogramokat kiprblni. Termszetesen nincs szksgnk egy tetszleges szvegszerkeszt (pl: emacs ) hasznlatra, hiszen a fejlesztkrnyezet ad egy jl hasznlhat bels szvegszerkesztt, s nincs szksg a parancssori fordts parancs kiadsra sem, hiszen ez a parancs egy menpontra van rdefinilva. A fejlesztkrnyezet installcija utn a Start \ Programok menponton keresztl indthatjuk el a Visual Studio.NET krnyezetet, ami a 3. brn lthat jellemz ablakkal jelenik meg. A jelenlegi fejlesztkrnyezetekben minden program valjban egy projektfednv alatt kszl el. Egy vagy tbb projekt felgyelete a Solution Explorer ablakban vgezhet. A f munkaterleten egy indul Start Page lthat, amiben a legutbbi projektek szerepelnek, illetve j vagy korbbi ltez projektet nyithatunk meg. Termszetesen a File menponton keresztl is elvgezhetk ezek a feladatok.

I. Alapismeretek

3. bra

A New Project menpont kivlasztsa utn, ahogy az az albbi ablakban is ltszik, hrom f krdsre kell vlaszolnunk:

4. bra

I. Alapismeretek 1. Ki kell vlasztani a programozsi nyelvet. 2. Az adott nyelvhez meg kell mondani, hogy milyen jelleg alkalmazst szeretnnk kszteni. 3. Meg kell adni a munkaknyvtrat s a projekt nevt. Ebben a knyvben a nyelvet illeten mindig a Visual C# Project lehetsget vlasztjuk, amit a nyitott mappajel is mutat. A Templates ablakban vlaszthatjuk ki az alkalmazs jellegt. Jelen esetben, illetve a kvetkez rsz pldiban az n. Console Application lehetsget vlasztjuk, ami egy hagyomnyos karakteres fellet programkrnyezetet jelent. Ezek az alkalmazsok parancssori ablakban futnak. A munkaknyvtr s a projekt nevnek megadsa azt jelenti, hogy ltrehozza a munkaknyvtron bell a projekt nvvel megadott knyvtrat, esetnkben a c:\programok\hajra knyvtrat, s ezen bell egy nknyes class1.cs llomnyt, aminek tartalma a kvetkez:

5. bra

Ahogy lthat, a keretrendszer a class1.cs llomnyba mindent elkszt, hogy csak a valdi feladatra kelljen koncentrlnunk. Az llomny tartalma lnyegben megegyezik a korbbi els programkddal. Ahogy mr emltettem, nem ktelez nvteret (namespace) definilni, illetve nem ktelez a Main fggvny paramtert jellni, s a vgrehajtsi szl attribtum jellse is opcionlis.

I. Alapismeretek Ezeket, illetve a dokumentcis megjegyzseket figyelembe vve lthat, hogy a kt kdrszlet azonos. Amint a 3. brrl lthat, a fejlesztkrnyezet rendelkezik a mr szoksosnak nevezhet berskori rtelmezssel (IntelliSense), s ha ltala ismert tpust fedez fel, akkor egy helyi ablakban megmutatja az aktulis objektum elrhet jellemzit. A projekt a 3. brn lthat forrskd mellett mg egy assemblyinfo.cs llomnyt is tartalmaz, amiben hrom jellemz attribtum belltst vgezhetjk el. Bellthatjuk programunk jellemz adatait, verziszmt, illetve a digitlis alrs kulcsllomnyra vonatkoz informcit is. Ezek a tulajdonsgok a .NET keretrendszer szolgltatsain alapulnak, aminek rszletezse meghaladja ennek a knyvnek a kereteit. A programot a Debug menpont Start (F5) vagy Start without debugging (CTRL-F5) menpontjval fordthatjuk le, illetve futtathatjuk. Ez utbbi menpontot hasznlva a parancssori ablak nem tnik el a program futsa utn, lehetsget biztostva a program eredmnynek megnzsre.

6. bra

A fordts hatsra ltrejn a c:\programok\hajra knyvtrban egy bin s egy obj knyvtr. Ez utbbiban a lefordtott llomnyok, mg a bin knyvtrban egy Debug vagy Release knyvtrban ltrejn a kvnt exe program is. A kt vltozat kzti klnbsg a nevbl addik, nevezetesen a Debug vltozatban a nyomkvets elsegtst biztostva kszl el a futtathat llomny. Ez a lehetsg a programfejlesztsek sorn nagyon hasznos, hiszen logikai vagy egyb hibk keressben a lpsenknti, nyomkvet mdszerrel trtn vgrehajts nlklzhetetlen. A Release, kiadsi vgleges vltozatot a program befejezseknt az 5. bra fejlcben lthat Debug-Release vlasztmez lltsval kszthetjk el. Tbbfelhasznls krnyezetben, pldul Windows XP opercis rendszer alatt, a Debugger Users csoportba minden fejlesztt bele kell rakni. A knyv msodik rszben a C# nyelv elemeinek megismersekor jellemz projekttpusknt konzolalkalmazst (6. bra) hasznlunk.

I. Alapismeretek

I.7. Windows alkalmazsok ksztse


Az alkalmazsok msik, s taln ma mr szlesebb krben hasznlt csoportja a grafikus alkalmazs ksztse. Ezeket a programokat Windows alkalmazsnak is szoktk nevezni. Ahogy a karakteres alkalmazsoknl mr lttuk, j feladatot (projektet) ksztve a Windows Application (Windows alkalmazs) lehetsget vlasztjuk s megadjuk a nevet, ahogy az a kvetkez kpen lthat.

7. bra

Miutn a fenti dialgusablakban befejezzk az adatok megadst, azt lthatjuk, hogy a karakteres alkalmazsokhoz kpest a munkafellet megvltozik, hiszen ebben a rendszerben az az alapelkpzels, hogy egy res ablak (form) az indul program. Ez valjban azt jelenti, hogy egy grafikus tervezablakot kapunk (Form1), amibe az eszkztrbl (Toolbox) a szksges vezrlelemeket a grafikus felletre visszk, s ekzben a forrskdot (form1.cs) a keretrendszer a felletalaktsnak megfelelen automatikusan mdostja.

I. Alapismeretek Az els grafikus programunkhoz hrom lpst vgezznk el! 1. rjuk t az ablak fejlcszvegt. Ehhez kattintsunk egyet a form-ra, majd a jobb als Properties (Tulajdonsgok) ablakban rjuk t a Text tulajdonsgot. (Els program!) 2. A Toolbox ablakbl helyezznk fel egy Button, nyomgomb objektumot. A Tulajdonsg ablakban lltsuk t a Text mezt a Vge szvegre. 3. Kattintsunk kettt a nyomgomb objektumra, ezzel a nyomgomb alaprtelmezett kattints esemny fggvnyt definiltuk. Ebbe rjuk be a Close(), ablakbezrs utastst. Ekkor a form1.cs forrskd rszlete a kvetkezkppen nz ki:
[STAThread] static void Main() { Application.Run(new Form1()); } private void button1_Click(object sender, System.EventArgs e) { Close(); }

Ezen hrom lps utn fordtsuk le, majd futtassuk a programot. Ezt, ahogy a korbbi karakteres program esetben is a Debug men Start menpontjval tehetjk meg. Ahhoz, hogy tovbbi grafikus alkalmazsokat tudjunk kszteni, elengedhetetlenl szksges, hogy ismerjk egyrszt a vlasztott nyelv lehetsgeit, msrszt a rendszer knyvtri szolgltatsait. Az elbbi, a nyelvi lehetsgek megismerse ltalban a legknnyebb s leggyorsabb feladat. Ez remnyeim szerint a kvetkez rsz ttanulmnyozsa utn a kedves Olvasnak is sikerl. Viszont az utbbi, a rendszer knyvtri szolgltatsainak megismerse hosszabb, tbb idt, sok egyni munkt jelent feladat. Azt remlem, hogy a befejez, a grafikus alkalmazsok alapjaival foglalkoz rsz utn mindenki elg btorsgot rez magban a tovbbi nll munka folytatshoz.

I. Alapismeretek

I.8. Feladatok
1. Milyen kd programot fordt a Visual Studio.NET fejlesztkrnyezet? 2. Mit csinl a Garbage Collection (szemtgyjt) algoritmus? 3. Lehet-e kezetes karaktereket hasznlni a C# programban? 4. Mik a Main fggvny jellemzi? 5. Egy program hny Main fggvnyt tartalmazhat, hogy tudjuk lefordtani?

II. A C# nyelv alaptpusai


Egy programozsi nyelvben az egyik legfontosabb tulajdonsg az, hogy programkszts sorn hogyan s milyen tpus adatokat hasznlhatunk. Meg kell jegyezni, hogy van nhny olyan programozsi nyelv is (pl. PhP), ahol ez a terlet nem igazn fontos, tpusok gyakorlatilag nincsenek, adatot szksg szerinti tpusban a programoz rendelkezsre bocst. A C# szigoran tpusos nyelv, ebben a nyelvben csak ennek figyelembevtelvel hasznlhatunk sajt vltozkat.

II.1. Vltozk definilsa


A nyelvben a vltozk definilsnak alakja: tpus vltoznv ; Azonos tpus vltozkat egymstl vesszvel elvlasztva definilhatunk. A tpusok ismerete nlkl nzznk nhny pldt vltozk definilsra. Plda:
char ch; int egy, tizenegy; // ch vltoz karakter tpus // az egy s tizenegy egsz tpus

Vltozk lehetnek klsk, azaz fggvnyen kvliek, vagy belsk, azaz fggvnyen belliek. A fggvnyen kvli vltozk is termszetesen csak osztlyon belliek lehetnek. Gyakran hvjk ezeket a vltozkat adatmezknek is. Bels vltozk, az adott blokkon (fggvnyen) belli loklis vltozk lehetnek dinamikus vagy statikus lettartamak. Mdost jelz nlkli definils esetn dinamikusnak vagy automatikusnak nevezzk, s ezek lettartama a blokkban val tartzkods idejre korltozdik. Ha a blokk vgrehajtsa befejezdtt, a dinamikus vltozk megsznnek. Statikus lettartam bels vltozt a static sz hasznlatval (ahogy kls vltoz esetn igen) nem definilhatunk. Lttuk, a fggvnyek lehetnek statikusak (lsd Main fggvny), melyekre ugyanaz igaz, mint az osztlyvltozkra, ezen fggvnyek lettartama is a programval egyezik meg, ms szval ezen fggvnyek a program indulsakor jnnek ltre.

28

II. A C# nyelv alaptpusai A vltozkat kt kategriba sorolhatjuk, az osztlytpus vltozk referencia tpusak, melyek mindig a dinamikus memriban helyezkednek el (az irodalomban ezt gyakran heap-nek nevezik), mg minden ms nem osztlytpus, az gynevezett rtktpus (value type) vltoz. Az rtktpus vltozkat szoktk stack vltozknak is nevezni. Az rtktpus vltozk kezdrtkt, az inicializls hinyban, 0, false, null rtkre lltja be a fordt. A vltozk definilsakor rgtn elvgezhet azok direkt inicializlsa is.

II.2. llandk definilsa


llandk definilst a tpusnv el rt const tpusmdost szcska segtsgvel tehetjk meg. A definci alakja: const tpus nv = rtk; Plda:
const float g=9.81; g=2.3; const int min=0; // vals konstans // !!! HIBA // egsz konstans

II.3. Vltozk inicializlsa


Vltozk kezd rtkadsa, inicializlsa azok definilsakor is elvgezhet a kvetkez formban: tpus vltoz = rtk; Plda:
char s='a'; int []a={1,2,3}; char[] b="Egy";

A vltozk, konstansok s fggvnyek hasznlatra nzzk a kvetkez pldt.

II. A C# nyelv alaptpusai Plda:


// A valtozo.cs fjl tartalma: using System; // A kirshoz szksges deklarcit tartalmazza. class vltoz { static int alma=5; //alma vltoz defincija //s inicializlsa static float r=5.6F //statikus vals tpus vltoz //vals konstanst zrhat az //F (float) bet const float pi=3.1415; //konstans definci static void Main() { Console.WriteLine( Console.WriteLine( int alma=6; Console.WriteLine( Console.WriteLine(

//eredmny Test //eredmny 5 //helyi vltoz alma ) ; //eredmny 6 vltoz.alma ); //a kls takart (5) //vltozra hivatkozs Console.WriteLine( terlet(r)); //a terlet fggvny // meghvsa // fggvnydefinci

"Teszt"); alma );

} static float terlet(float sugr) { return(pi*sugr*sugr); } }

Br mg nem definiltunk fggvnyeket, gy taln korainak tnhet ez a plda, de inkbb felhvnm mg egyszer a figyelmet az kezetes karakterek hasznlatra. A ksbbi mintafeladatokban, ha elfordul kezet nlkli vltoz, fggvnydefinci, akkor az csak a korbbi krnyezetek rossz uthatsnak ksznhet. Egy osztlyon bell a fggvnyek definilsi sorrendje nem lnyeges. Sok krnyezetben furcsa lehet amit a fenti pldban ltunk, hogy elbb hasznljuk, s csak ezutn definiljuk a fggvnynket. (terlet fggvny)

II.4. Elemi tpusok


char karakter tpus (2 byte hossz)

II. A C# nyelv alaptpusai A karakter tpus 16 bites karakterbrzolst (unikd) hasznl. ltalban igaz, hogy minden alaptpus mrete rgztett. A karakter tpus vltoz rtkt aposztrf (') jelek kztt tudjuk megadni. Plda:
char c; c='a';

A backslash (\) karakter specilis jelentssel br. Az utna kvetkez karakter(eke)t, mint egy escape szekvencit dolgozza fl a fordt. Az gy hasznlhat escape szekvencik a kvetkezk: \a \b \f \r \n a 7-es kd csipogs backspace, elz karakter trlse formfeed, soremels karakter kocsi vissza karakter j sor karakter (soremels+kocsi vissza)

Az j sor karakter hatsa azonos a formfeed s a kocsi vissza karakterek hatsval. \t \v \\ \' \" \? \uxxyy tabultor karakter fggleges tabultor backslash karakter aposztrf idzjel krdjel xx s yy unikd karakter

string karaktersorozat
A System.String osztlynak megfelel tpus. Szvegek kztt a + s a += szvegsszefzst vgz opertorok ismertek. A [] opertor a szveg adott index karaktert adja meg. Az indexels 0-val kezddik. A @ karakter kikszbli a szvegen belli rzkeny karakterek hatst. Ilyen pldul a backslash (\) karakter. Plda:
char c='\u001b'; string s="alma"; string n="alma"+"barack"; s+="fa"; // c= a 27-es kd (Esc) karakterrel //s= almafa

II. A C# nyelv alaptpusai


char c1=s[2]; // c1= m char c2="szia"[1]; // c2=z string f="c:\\programok\\alma.txt"; string file=@"c:\programok\alma.txt";

A String osztly a fenti lehetsgeken kvl egy sor fggvnnyel teszi hasznlhatbb ezt a tpust. Ezen fggvnyek kzl a legfontosabbak: Length Csak olvashat tulajdonsg, megadja a szveg karaktereinek a szmt:
string s="alma"; int i=s.Length; //i=4

CompareTo(string) Kt szveg sszehasonltst vgzi. Ha az eredmny 0, akkor azonos a kt szveg:


string str1="egyik", str2="msik"; int cmpVal = str1.CompareTo(str2); if (cmpVal = = 0) // az rtkek azonosak {} else if (cmpVal > 0) // str1 nagyobb mint str2 {} else // str2 nagyobb mint str1

Equals(string) Megadja, hogy a paramterl kapott szveg azonos-e az eredeti szveggel:


string str1="egyik", str2="msik"; if (str1.Equals(str2){} // azonos else{} // nem azonos

IndexOf(string) Tbb alakja van, megadja, hogy az eredetiben melyik indexnl tallhat a paramterl kapott szveg. A visszaadott rtk 1 lesz, ha nincs benn a keresett szveg:
int i="almafa".IndexOf("fa"); //4

Insert(int,string) A msodik paramterl kapott szveget, az els paramterrel megadott indextl beszrja az eredeti szvegbe:

II. A C# nyelv alaptpusai


string s="almafa alatt"; string ujs=s.Insert(4," a "); // alma a fa alatt

A szvegtpus tovbbi szolgltatsait, fggvnyeit a szvegosztly (System.String) online dokumentcijban rdemes megnzni. Meg kell emlteni mg azt, hogy a szvegosztly fggvnyei nem mdostjk az eredeti szveget, szvegobjektumot, pldaknt az elz s szveges vltoz rtke vltozatlan marad. Szveges feldolgozsi feladatok sorn a regulris kifejezsekkel megadhat szvegmintk segtsgt is ignybe vehetjk. A .NET Framework a Perl5 kompatibilis regulris kifejezshasznlatot tmogatja. A Regex osztly szolgltatja a regulris kifejezst, mg a Match a tallati eredmnyt. Az osztlyokat a System.Text.RegularExpressions nvtrben talljuk. Plda:
using System; using System.Text.RegularExpressions; class regulris { public static void Main() { Regex reg_kif = new Regex("fradi"); // a fradi keresse Match tallat = reg_kif.Match("A Fradi j csapat?"); if (tallat.Success) { // (hol talltuk meg Console.WriteLine("A tallat helye: " + tallat.Index); } } }

A fenti plda nem ad eredmnyt, hiszen alaprtelmezsben a kis- s nagybet klnbzik, mg ha a regulris kifejezst egy kicsit mdostjuk, az albbiak szerint:
Regex reg_kif = new Regex("adi");

akkor a futsi eredmny az albbi lesz:

II. A C# nyelv alaptpusai

8. bra

Ha azt szeretnnk elrni, hogy az eredeti szvegnk is vltozzon, akkor ehhez a System.Text nvtr StringBuilder osztlyt tudjuk ignybe venni. Plda:
using System.Text; StringBuilder s1 = new StringBuilder("almafa alatt"); s1.Insert(4," a "); Console.WriteLine(s1); // "alma a fa alatt"

int egsz tpus(4 byte)


Az egsz tpus rtkek ngy bjtot foglalnak a ma leggyakrabban hasznlt nyelvi krnyezetben , gy rtelmezsi tartomnyuk -231, 231- 1 kztt van. long short sbyte float double decimal hossz egsz (8 byte) rvid egsz (2 byte) eljeles (signed) byte vals (4 byte) dupla pontossg vals (8 byte) pnzgybeli tpus (16 byte), 28 helyirtk

Mindkt egsz tpus eljeles, ha erre nincs szksgnk, hasznlhatjuk az eljel nlkli vltozatukat, melyek: uint, ushort, byte, ulong. Vals szmok definilsakor a 10-es kitevt jell e konstans hasznlhat. Plda:
float a=1.6e-3; // 1.6 * 10-3

void tpus nlkli tpus


Az olyan fggvnynek (eljrsnak) a tpusa, amelyik nem ad vissza rtket.

II. A C# nyelv alaptpusai Plda:


void nvel(ref int mit) { mit++; }

Az imnti fggvny paramternek jellse referencia szerinti paramtertadst jelent, amirl a Fggvnyek c. fejezetben rszletesen szlunk.

bool logikai tpus (1 byte)


A logikai tpus rtke a true (igaz) vagy false (hamis) rtket veheti fel. Ahogy a nyelv foglalt alapszavainl lthattuk, ezeket az rtkeket a true s false nyelvi kulcssz adja meg. ltalban elmondhat, hogy mg a nyelv nem definil sok alaptpust, addig az egyes implementcik, fleg azok grafikus fellet alatti knyvtrai ezt bsgesen ptoljk, s gyakran tbb idt kell az 'j tpusok' megfejtsnek szentelni, mint a fggvnyek tanulmnyozsnak.

II.5. Felsorols tpus


A felsorols tpus gyakorlatilag nem ms, mint egsz konstans(ok), szinonimk definilsa. Felsorols tpust nvtren vagy osztlyon bell definilhatunk. Ennek a kulcsszava az enum. A kulcssz utn a felsorols tpus azonostjt meg kell adni. A System.Enum osztly szinonimjt adja az ezen kulcssz segtsgvel definilt tpus. Plda:
enum szinek {piros,kk,zld,srga}; enum betuk {a='a', b='b'}; betuk sajtbet=betuk.a; // vltoz kezdrtke a enum valami { x="alma"}; // hiba

Ekkor a 0,1, rtkek rendeldnek hozz a felsorolt nevekhez, s a nevek kirsakor ezen szmokat is ltjuk. A kezdrtkads lehetsgvel lve nem kell ezeket felttlenl elfogadnunk, hanem mi is megadhatjuk az rtkket. Plda:
class Szinek { enum jszinek {piros=4, kk=7, zld=8, srga=12}; public static void Main()

II. A C# nyelv alaptpusai


{ Console.WriteLine(jszinek.zld); // kirja a sznt //ciklus a szneken trtn vgighaladsra for(jszinek i=jszinek.kk; i<jszinek.srga; i++) { //kirja a szneket Console.WriteLine(i); }

} }

A fenti ciklus eredmnyeknt azon egszek esetn, ahol az egsz rtkhez egy nevet rendeltnk hozz, a nv kerl kirsra, egybknt a szm. Az eredmny a kvetkez lesz:
kk zld 9 10 11

Mivel ez a tpus a System.Enum megfelelje, ezrt rendelkezik annak jellemzivel is. Ezek kzl a kt legjellemzbb a GetHashCode() s a ToString() fggvny. Az elbbi a bels trolsi formt, a megfelel egsz szmot adja meg, mg a ToString(), mint alaprtelmezett reprezentci, a szveges alakot (kk,zld, stb) adja meg. Plda:
jszinek s=jszinek.piros; Console.WriteLine(s.GetHashCode()); // eredmny: 4

A felsorols tpus alaprtelmezsben egsz tpus rtkeket vesz fel. Ha ez nem megfelel, akr byte (vagy tetszleges egsz szinonima) tpus rtkeket is felvehet gy, hogy a tpusnv utn kettsponttal elvlasztva megadom a tpusnevet. (Nem adhatom meg a vals vagy karakter tpust!) Plda:
enum sznek:byte {piros,kk,zld,srga}; enum hibs:float {rossz1, rossz2}; // ez fordtsi hiba

Elfordulhat, hogy olyan felsorolsadatokra van szksgem, melyek nem egy egsz konstanshoz, hanem egy bithez ktdnek, hiszen ekkor a logikai

II. A C# nyelv alaptpusai s/vagy mveletekkel a felsorolsadatok kombincijt hatrozhatjuk meg. Ebben az esetben a [Flags] attribtumot kell az enum szcska el szrni. Plda:
[Flags] enum alma {piros=1,jonatn=2,zld=4,golden=8}; alma a=alma.piros | alma.jonatn; Console.WriteLine(a); // piros, jonatn a=(alma) System.Enum.Parse(typeof(alma),"zld,golden"); // a felsorols tpus egyszer rtkadsa helyett // a knyvtri hvs lehetsgt is hasznlhatjuk // Console.WriteLine(a.GetHashCode()); // eredmny 12 lesz

Bithez kttt rtkek esetn ktelez minden egyes konstans nvhez megadni a neki megfelel bites brzolst! Az alaptpusokat a .NET keretrendszer biztostja, gy ennek a fejlesztsi krnyezetnek egy msik nyelvben pontosan ezek a tpusok llnak rendelkezsre. Az termszetesen elfordulhat, hogy nem ezekkel a nevekkel kell rjuk hivatkozni, de a nyelvi fordt biztosan ezen rtelmezs szerinti kdot (kztes kd) fordtja le a keretrendszer, mint futtat krnyezet szmra. Az alaptpusok zrsaknt meg kell jegyezni, hogy a mutat tpus is rtelmezett, ahogy a C++ vilgban, de ennek a hasznlata csak olyan C# programrszben megengedett, amely nem biztonsgos krnyezetben helyezkedik el (unsafe context). Errl rviden a knyv XIV. fejezetben olvashat.

II.6. Feladatok
1. Milyen alaptpusokat ismer a C# nyelv? 2. Mi a vltoz s az lland kztt a klnbsg? 3. Mi a klnbsg egy statikus s egy dinamikus lettartam vltoz kztt? 4. Definiljon kt szveg tpus vltozt, adja meg a hosszukat! 5. brzolja felsorols tpussal az NB 1 bajnoksg csapatait!

III. Kifejezsek, mveletek


A nyelv jellemzje a korbban (pldul C++ nyelvben) megismert, megszokott kifejezsfogalom, amit tmren gy is fogalmazhatunk, hogy a vezrlsi szerkezeteken kvl a nyelvben minden kifejezs. Egy kifejezs vagy elsdleges kifejezs, vagy opertorokkal kapcsolt kifejezs. Elsdleges kifejezsek: azonost (kifejezs) elsdleges kifejezs[] fggvnyhvs elsdleges kifejezs.azonost A kifejezseket egy-, kt- vagy hromoperandus opertorokkal kapcsolhatjuk ssze. Egy kifejezsen bell elszr az elsdleges kifejezsek, majd utna az opertorokkal kapcsolt kifejezsek kerlnek kirtkelsre. A nyelvben hasznlhat opertorok prioritsi sorrendben a kvetkezk.

III.1. Egyoperandus opertorok


new A dinamikus helyfoglals opertora. A helyfoglals opertornak egyetlen operandusa az, hogy milyen tpus objektumnak foglalunk helyet. Sikeres helyfoglals esetn a mvelet eredmnye a lefoglalt memria cme. Sikertelen helyfoglals esetn a null mutat a visszatrsi eredmny. Plda:
int[]a; a = new int; a = new int[5] //egy egsz trolshoz //elegend hely foglalsa //t egsz szmra foglal helyet

A new utasts gyakran szerepel a vektorokkal sszefggsben, amirl ksbb rszletesen szlunk.

38

III. Kifejezsek, mveletek A .NET keretrendszer egyik legfontosabb tulajdonsga az, hogy a dinamikusan foglalt memriaterleteket automatikusan visszacsatolja a felhasznlhat memriatartomnyba, ha arra a memrira a programnak mr nincs szksge. Sok nyelvi krnyezetben erre a delete opertor szolgl. ! ~ ++,-(tpus) kifejezs Plda:
double d=2.3; int i=(int) d; // i=2

aritmetikai negls logikai negls (not) bitenknti negls, inc, dec. tpusknyszerts

A ++ s -- opertor szerepelhet mind pre-, mind postfix formban. Prefix esetben a vltoz az opertorral vltoztatott rtkt adja egy kifejezs kirtkelsekor, mg postfix esetben az eredetit. Plda:
a= ++b; a= b++; // hatsa: b=b+1; a=b; // hatsa: a=b; b=b+1;

Az egyoperandus opertorok s az rtkads opertora esetn a vgrehajts jobbrl balra haladva trtnik, minden ms opertor esetn azonos precedencinl balrl jobbra.

III.2. Ktoperandus opertorok


* / % szorzs oszts maradkkpzs

E hrom opertorral mindig igaz: az (a/b)*b+a%b kifejezs az a rtkt adja. (% opertor esetn az operandusok nem lehetnek valsak, s a prioritsuk azonos.)

III. Kifejezsek, mveletek + << >> sszeads, string esetn azok sszefzse kivons bitenknti balra lptets bitenknti jobbra lptets

A jobbra lptets opertorhoz pldnak tekintsk az a >> b; utastst. Ekkor ha az a unsigned, akkor balrl nullval, klnben pedig az eljelbittel tlt a bitenknti jobbra lptets opertora. Plda: int a= 1, b; b= a >> 2; <,> <=, >= ==, != & ^ | && || // b rtke -1 marad

kisebb, nagyobb relcis opertorok kisebb vagy egyenl, ill. a nagyobb vagy egyenl opertorok egyenl, nem egyenl relcis opertorok bitenknti s bitenknti kizr vagy bitenknti vagy logikai s logikai vagy

is Logikai opertor, egy objektumrl megmondja, hogy a bal oldali operandus a jobb oldali tpusnak egy vltozja-e. Plda:
int i=3; if (i is int) Console.WriteLine("Bizony az i egsz!"); else Console.WriteLine("Bizony az i nem egsz!");

as Ktoperandus tpusknyszerts. A bal oldali vltozt a jobb oldali referencia tpusra alaktja, ha tudja. Ha sikertelen az talakts, akkor eredmnyl a null rtket adja. Plda:
double d=2.5; Object o= d as Object; Console.WriteLine(o); // eredmny: 2.5 // Object-re mindent lehet alaktani, aminek van toString kir //fggvnye. Errl bvebben ksbb esik sz.

III. Kifejezsek, mveletek typeof Egy System.Type tpus objektumot kszt. Ennek az objektumnak a mezfggvnyeivel, tulajdonsgaival (FullName, GetType()) tudunk tpusinformcihoz jutni. Plda:
using System; class Teszt { static void Main(){ Type[] t = { typeof(int), typeof(string), typeof(double), typeof(void) }; for (int i = 0; i < t.Length; i++) { Console.WriteLine(t[i].FullName); } } }

A program futsa a kvetkez eredmnyt produklja:


System.Int32 System.String System.Double System.Void

A tpuskonverzival kapcsolatban elmondhat, hogy minden rtktpusbl ltrehozhatunk egy neki megfelel Object tpus objektumot. Ezt gyakran boxing-nak, csomagolsnak, mg az ellenkez kicsomagol mveletet, amihez a zrjeles tpuskonverzi opertort kell hasznlni, unboxing-nak nevezi a szakirodalom. Plda:
int i=5; Object o=i; int j=(int) o; // boxing, becsomagols // unboxing, kicsomagols

Az Object tpus, ami a System.Object tpusnak felel meg, minden tpus seknt tekinthet. Ennek a tpusnak a fggvnyei ily mdon minden ltalunk hasznlt tpushoz rendelkezsre llnak.

III. Kifejezsek, mveletek Az Object tpus tagfggvnyei a kvetkezk: ToString() Megadja az objektum szveges reprezentcijt. Ha erre van szksg, pldul kirsnl, akkor ezt automatikusan meghvja. Ha ezt egy j tpushoz jradefiniljuk, akkor ez hvdik meg kirs esetn.
Console.WriteLine(o); // indirekt ToString hvs Console.WriteLine(o.ToString());

GetType() Megadja az objektum tpust, hasonl eredmnyt ad, mint a korbban ltott typeof opertor. Equals(object) Megadja, hogy kt objektum egyenl-e, logikai rtket ad eredmnyl.
int i=5; object o=i; Console.WriteLine(o.Equals(5));

Az Equals fggvnynek ltezik egy statikus vltozata is, aminek a formja: Object.Equals(object, object) GetHashCode() Megadja az objektum hash kdjt, ami egy egsz szm. Tetszleges sajt utdtpusban jradefinilhatjuk, amivel a sajt tpusunk hash kdjt tudjuk szmolni.

III.3. Hromoperandus opertor


Az opertorral kpezhet kifejezs alakja a kvetkez: e1 ? e2 : e3 , ahol a ? s a : az opertor jelei, mg e1,e2,e3 kifejezsek. A kifejezs rtke e2 ha e1 igaz (nem 0), klnben e3. Plda:
char c; int a; a=((c>='0' && c<='9') ? c-'0' : -1);

III. Kifejezsek, mveletek Az a vltoz vagy a 0-9 vagy 1 rtket kapja. A hromoperandus opertor valjban egy logikai elgazs utasts. A hatkony kifejezskszts, tmrebb rsmd kivl eszkze.

III.4. Ktoperandus rtkad opertorok


= rtkads opertora

A nyelvben az rtkads sajtos, nmaga is kifejezs. Az egyenlsgjel bal oldaln olyan kifejezs, vltoz llhat, amely ltal kpviselt adat j rtket vehet fel. Gyakran hvja a szakirodalom ezt balrtknek is (lvalue). Az egyenlsgjel jobb oldaln egy rtket ad kifejezs kell, hogy lljon (jobbrtk, rvalue). Ez gyakorlatilag azt jelenti, hogy a jobbrtkre semmilyen korltozs nincs. Az rtkads sorn a bal oldal megkapja a jobb oldali kifejezs rtkt, s egyben ez lesz a kifejezs rtke is. Plda:
char []d=new char[80]; // msoljuk az s forrsszveget d-be while (i<s.Length) { d[i]=s[i]; i++; } char []c={'L','a','l','i'}; d=c; // hiba!! mivel d mr egy 80 karakteres //terletet jell, ezrt j terletet mr nem // jellhet, d nem lehet balrtk

Az rtkads opertora jobbrl balra csoportost, ezrt pl. az a=b=2; utasts hatsra a s b is 2 lesz. Az egyenlsgjel mellett mg nhny, az aritmetikai opertorokkal 'kombinlt' rtkad opertor is hasznlhat. Ezek az opertorok a kvetkezk: +=, =, *=, /=, %=, >>=, <<=, &=, ^=, |= Jelentsk: az e1 opertor e2 kifejezs, ahol e1 s e2 is kifejezsek, az e1 = e1 op e2 kifejezsnek felel meg, ahol op az egyenlsgjel eltti opertor.

III. Kifejezsek, mveletek Plda:


int a=2; a *= 3; // a= a*3, azaz a rtke 6 lesz string b="alma"; b+="fa"; // b=almafa

A tpusok egyms kzti konverzijval kapcsolatban azt lehet mondani, hogy a C vagy C++-ban ismert automatikus konverzik nem lteznek. Egy egsz tpus vltozt egy valsba gond nlkl berhatunk, mg fordtva mr hibt jelez a fordt. A konverzis lehetsgek szles skljt nyjtja a fejleszteszkznk. Konverzikkal kapcsolatban kt esetet szoktak megklnbztetni. Ezek kzl az els szm szvegg alaktsa. Ez gyakorlatilag nem ignyel semmilyen segtsget, a szmtpushoz tartoz osztly ToString fggvnyt hvja meg a fordt. Ehhez nem kell semmit sem tenni. Plda:
int a=2; string s="Az eredmny:" + a;

A msik eset, mikor szvegbl szeretnnk szmot kapni, mr nem ilyen automatikus, de semmikppen nem lehet bonyolultnak nevezni. Tbbfle mdszer lehet az alaktsra, de a legltalnosabb taln a Convert osztly hasznlata. Az osztly konvertl fggvnyei azonos nvkonvencival az albbi formjak:
Convert.ToCTStpusnv

ahol a CTS (Common Type System) tpusnv az albbi lehet: Boolean, Int16 (short int), Int32 (rendes int), Int64 (hossz int), Float, Double, String, Decimal, Byte, Char. Plda:
string s="25"; int i=Convert.ToInt32(s); // i=25 lesz

rdekessgknt megemltem, hogy ltezik a Convert.ToDateTime(object) fggvny is, ami egy knyvtri dtumtpust kszt a paramterl kapott objektumbl. Ha brmelyik konvertl fggvny hibs paramtert kap, nem tud eredmnyt produklni, akkor InvalidCastException kivtelt vagy ms, a hiba okra utal kivtelt generl. A kivtelkezelsrl ksbb rszletesen is fogunk beszlni.

III. Kifejezsek, mveletek ltalban igaz, hogy grafikus alkalmazsok sorn a bert adataink szvegesek, gy minden esetben az azokkal trtn szmols eltt konvertlnunk kell, ezrt a konvertl fggvnyek hasznlata elg gyakori. Hasonl konvertl szolgltatsokat kapunk, ha az alaptpusok Parse fggvnyt hasznljuk (int.Parse(szveg), double.Parse(szveg)). Gyakran elfordul, hogy az alapmveletek nem elgtik ki a szmolsi ignyeinket. A System nvtr Math osztlya a leggyakrabban hasznlt szmolsi mveleteket biztostja. A leggyakrabban hasznlt fggvnyek a kvetkezk: Math.Sin(x) Math.Cos(x) Math.Tan(x) Math.Exp(x) Math.Log(x) Math.Sqrt(x) Math.Abs(x) Math.Round(x) Math.Ceiling(x) Math.Floor(x) Math.Pow(x,y) Math.PI Math.E Plda:
double dd=Math.Sin(Math.PI/2); Console.WriteLine(dd); // rtke 1. dd=Math.Pow(2,3); Console.WriteLine(dd); // 8

sin(x), ahol az x szg rtkt radinban kell megadni cos(x) tg(x) ex ln(x) x ngyzetgyke x abszolt rtke kerekts a matematikai szablyok szerint felfel kerekts lefel kerekts hatvnyozs, xy a PI konstans (3.14159265358979323846) az e konstans (2.7182818284590452354)

Matematikai, statisztikai feladatoknl a vletlenszmok hasznlata gyakori igny. A System nvtr Random osztlya nyjtja a pszeudo-vletlenszmok generlsnak lehetsgt. Egy vletlenszm-objektum ltrehozst a rendszeridhz (paramter nlkli konstruktor) vagy egy adott egsz szmhoz kthetjk. A vletlenobjektum Next fggvnye a kvetkez vletlen egsz szmot, a NextDouble a kvetkez vals vletlenszmot adja. A Next fggvnynek hrom, mg a NextDouble fggvnynek egy vltozata van, amit a kvetkez plda is bemutat.

III. Kifejezsek, mveletek Plda:


Random r=new Random(); //r vletlenszm objektum rendszerid alap ltrehozsa Random r1=new Random(10); // r1 vletlenobjektum genertor a 10 rtkbl indul ki // int v= r.Next(); // vletlen egsz szm 0 s MaxInt (legnagyobb egsz) kztt //0 lehet az rtk, MaxInt nem // int v1=r.Next(10); // vletlen egsz szm 0 s 10 kztt, 0<=v1<10 // int v2=r.Next(10,100); // vletlen egsz szm 10 s 100 kztt, 10<=v2<100 // double d=r.NextDouble(); // vletlen vals szm 0 s 1 kztt, 0<=d<1

III.5. Feladatok
1. Mit neveznk ktoperandus opertornak? 2. Melyik opertor hrom operandus? 3. Milyen szm-szveg konverzis lehetsgeket ismer? 4. Fogalmazza meg kt elem kzl a nagyobb kivlasztst operator segtsgvel! 5. Ismerjk egy hromszg kt oldalt s kzbezrt szgt. Szmoljuk ki a szggel szemkzti oldal hosszt!

IV. sszetett adattpusok


IV.1. Tmbk
A feladataink sorn gyakori igny az, hogy valamilyen tpus elembl tbbet szeretnnk hasznlni. Amg ez a tbb kett vagy hrom, addig megolds lehet, hogy kt vagy hrom vltozt hasznlunk. Amikor viszont tz, hsz adatra van szksgnk, akkor ez a fajta megolds nem igazn knyelmes, s sok esetben nem is kivitelezhet. Lehetsg van azonos tpus adatok egy kzs nvvel val sszekapcsolsra, s az egyes elemekre index segtsgvel hivatkozhatunk. Ezt az adatszerkezetet tmbnek nevezzk. A tmbk elemeinek elhelyezkedse a memriban sorfolytonos. A tmb helyett gyakran hasznljuk a vektor szt, annak szinonmjaknt. A C# nyelv minden tmb- vagy vektortpus defincit a System.Array osztlybl szrmaztat, gy annak tulajdonsgai a meghatrozak. A tmbk defincijnak formja a kvetkez: tpus[] nv; Az egyes tmbelemekre val hivatkozs, a tmbk indexelse mindig 0-val kezddik. Az index egsz tpus kifejezs lehet, a tpus pedig tetszleges. Egy tmb ltalnos defincija nem tartalmazza az elemszm rtkt. Br a nyelv krnyezetben nem lehet mutatkat definilni, de ez gyakorlatilag azt jelenti. A vektor defincija egy referencia tpus ltrehozsa, s a nyelv minden referencia tpust a new opertorral kell konkrt rtkekkel inicializlni (pldnyostani). Ekkor kell megmondani, hogy az adott vektor hny elem lesz. Minden vektornak, ellenttben a C++ nyelvvel, a ltrehozsa utn lekrdezhet az elemszma a Length tulajdonsggal. Plda:
int[] numbers; numbers = new int[10]; numbers = new int[20]; int db = 15; numbers = new int[db]; // egsz vektordefinci // 10 elem lesz az egsz vektorunk // most meg 20 elem lett // egy vltoz adja a hosszt

47

IV. sszetett adattpusok Mivel a nyelv minden dinamikus referencia tpusnak memriabeli felszabadtst a rendszer automatikusan vgzi ezt az irodalom gyakran szemtgyjtsi algoritmusnak (garbage collection) nevezi , ezrt a pldabeli 10 elem vektor memriahelyt automatikusan visszakapja az opercis rendszer. A vektorelemek a fenti dinamikus ltrehozs utn 0 kezdrtket kapnak. Ha egyb elemekkel szeretnnk az inicializcit elvgezni, kapcsos zrjelek kz rva adhatjuk meg azokat. tpus[] nv={rtk, rtk,}; Plda:
int[] n={3,4,5,6}; int hossz= n.Length; // vektorhossz meghatrozs

Ha logikai vektort definilunk, akkor a vektorelemek kezdrtkads hinyban logikai hamis (false), mg ha referencia vektort definilunk, akkor a referenciaelemek a null kezdrtket kapjk meg. Plda:
int[] numbers = {1, 2, 3, 4, 5}; int[] numbers = new int[5] {1, 2, 3, 4, 5}; string[] nevek = new string[3] {"Ali", "Pali", "Robi"}; int[] numbers = new int[] {1, 2, 3, 4, 5}; string[] nevek = new string[] {"Ali", "Pali", "Robi"};

A C# nyelvben nem csak a fenti egydimenzis vektor definilhat. Ezenkvl mg definilhat kt- vagy tbbindex, multidimenzis vektor, illetve vektorok vektora.

Multidimenzis vektor:
Plda:
string[,] nevek; nevek= new string[2,4];

A vektor dimenzijt a Rank tulajdonsggal krdezhetjk le.


Console.WriteLine(nevek.Rank); // 2 // az egyes dimenzikbeli mretet a GetLength adja Console.WriteLine(nevek.GetLength(0)); // 2

IV. sszetett adattpusok


Console.WriteLine(nevek.GetLength(1)); // 4

Termszetesen a norml vektornak (int[] v) is lekrdezhetjk a dimenzi rtkt. Plda:


int[,] numbers = new int[3, 2] { {1, 2}, {3, 4}, {5, 6} }; string[,] kapocs = new string[2, 2] { {"Miki","Ani"}, {"Mari","Albert"} }; int[,] numbers = new int[,] { {1, 2}, {3, 4}, {5, 6} }; string[,] kapocs = new string[,] { {"Miki","Ani"}, {"Mari","Albert"} }; int[,] szmok = { {1, 2}, {3, 4}, {5, 6} }; string[,] kapocs = { {"Miki", "Ani"}, {"Mari", "Albert"} };

Hasznlat:
numbers[1,1] = 667;

Vektorok vektora:
A ms nyelvekbeli analgit tekintve, a multidimenzis vektorban minden sorban azonos darabszm elem van, ez teht a szablyos, ngyzetes mtrix stb. defincinak felel meg. A vektorok vektora pedig valjban egy mutat vektor definci, ahol elszr megmondjuk, hogy hny elem a mutat vektor, majd ezutn egyenknt meghatrozzuk, hogy az egyes elemek milyen vektorokat jelentenek. Plda:
byte[][] meres = new byte[5][]; for (int x = 0; x < meres.Length; x++) { meres[x] = new byte[4]; } int[][] szamok= new int[2][] { new int[] {3,2,4}, // ez a hrom elem vektor lesz a szamok els vektora new int[] {5,6} // ez a kt elem vektor lesz a szamok msodik vektora }; int[][] numbers = new int[][] { new int[] {2,3,4}, new int[] {5,6,7,8,9} }; int[][] numbers = { new int[] {2,3,4}, new int[] {5,6,7,8,9} };

IV. sszetett adattpusok Hasznlat:


numbers[1][1] = 5;

Termszetesen mindkt esetben multidimenzis, vektorok vektora nem csak ktdimenzis esetrl beszlhetnk, hanem tetszleges mret vektorrl. Plda:
int[,,] harom = new int[4,5,3];

Lehetsgnk van a ktfle vektordefinci kevert hasznlatra is. A kvetkez plda egy olyan egyszer vektort definil, aminek minden eleme 32 dimenzis szablyos mtrix. Plda:
int[][,,][,] mix;

Ezek utn rjunk egy pldaprogramot, amely bemutatja a korbban megbeszlt vektorjellemzk hasznlatt: Plda:
//vektor.cs using System; class vektorpelda { public static void Main() { // Sima vektordefinci, a definci pillanatban // 5 elem vektor lesz // A vektorelemeknek kln nem adtunk kezdrtket, // ezrt azok 0 rtket kapnak. int[] numbers = new int[5]; // Ktdimenzis vektor, sima 5x4-es szveges, //ezen elemek inicializls hinyban null rtket kapnak. string[,] names = new string[5,4]; // Vektorok vektora, ezt az irodalom gyakran //"jagged array", (csipks, szaggatott vektor) nven emlti byte[][] scores = new byte[5][]; // Az egyes vektorok definilsa for (int i = 0; i < scores.Length; i++) { scores[i] = new byte[i+3]; // elemrl elemre n az elemszm. } // Egyes sorok hossznak kirsa

IV. sszetett adattpusok


for (int i = 0; i < scores.Length; i++) { Console.WriteLine("Az {0} sor hossza: {1}", i, scores[i].Length); // A {} jelek kztti szmmal hivatkozhatunk az els paramter // utni tovbbi rtkekre. {0} jelenti az i vltozt. // Hasznlata nagyon hasonlt a C printf hasznlathoz. }

A program futsa utn a kvetkez eredmnyt kapjuk:


Az Az Az Az Az 0 1 2 3 4 sor sor sor sor sor hossza: hossza: hossza: hossza: hossza: 3 4 5 6 7

Plda:
string honapnev(int n) { string[]nv={"Nem ltezik","Janur", "Februr","Mrcius", "prilis","Mjus","Jnius", "Jlius","Augusztus", "Szeptember","Oktber", "November","December"}; return(((n<1)||(n>12)) ? nv[0] : nv[n]); }

Az imnti plda meghatrozza egy tetszleges sorszm hnaphoz annak nevt.

IV.2. Struktra
Gyakran szksgnk van az eddigiektl eltr adatszerkezetekre, amikor a lerni kvnt adatunkat nem tudjuk egy egyszer vltozval jellemezni. Elg, ha a taln legkzenfekvbb feladatot tekintjk: hogyan tudjuk a sk egy pontjt megadni? Egy lehetsges megadsi md, ha a pontot mint a sk egy derkszg koordintarendszernek pontjt tekintem, s megadom az X s Y koordintkat. A struktradefinils az ilyen feladatok megoldsa esetn lehetv teszi, hogy az sszetartoz adatokat egy egysgknt tudjuk kezelni. A struktradefinci formja a kvetkez:

IV. sszetett adattpusok struct nv { hozzfrs tpus meznevek; hozzfrs fggvnydefinci ; }; Hivatkozs egy mezre: vltoznv.meznv A struktrkon azonos tpus esetn az rtkads elvgezhet, gy ha pldul a s b azonos tpus struktra, akkor az a=b rtkads szablyos, s az a minden mezje felveszi b megfelel mezrtkeit. Plda:
struct pont { int x; int y; }; pont a; struct egy { string name; int kor; }; egy[] c=new egy[10];

// 10 elem struktra vektor

A fenti definci teljesen j, csak a hozzfrsi szint megadsnak hinyban minden mez privt, azaz a struktra mindkt adata csak bellrl lthat. A struktra alaprtelmezett mezhozzfrse privt (private). Minden taghoz kln meg kell adni a hozzfrsi szintet. Struktra esetn a megengedett hozzfrsi szintek: private public internal Plda:
struct szemly { public string nv;

csak struktrn bellrl rhet el brki elrheti ezt a mezt programon bellrl (assembly) elrhet

IV. sszetett adattpusok


}; public int kor;

Az egyes mezkre hivatkozs formja: Plda:


szemly st=new szemly(); System.WriteLine( st.kor); // kor kirsa

Struktradefinci esetn a nyelv nem csak adatmez, hanem fggvnymez definilst is megenged. Azt a fggvnymezt, aminek ugyanaz a neve, mint a struktrnak, konstruktornak nevezzk. Paramter nlkli konstruktor nem definilhat, azt mindig a krnyezet biztostja. A struktra rtktpus adat, gy a vermen s nem a dinamikus memriban jn ltre. ltalban elmondhat, hogy a struktra majdnem gy viselkedik, mint egy osztly, de funkcionalitst tekintve megmarad a klnbz tpus adatok trolsnl. A struktrkkal kapcsolatosan rdemes megjegyezni hrom alapvet tulajdonsgot: Egy struktra adatmezt a definils pillanatban nem inicializlhatunk.
struct alma { string nev="jonatn"; // fordtsi hiba }

Plda:

Struktra adatmezket a default konstruktor nem inicializl. A kezdrtk belltsrl, ha szksges, sajt konstruktorral vagy egyb belltsi mddal kell gondoskodni. Plda:
struct pont { public int x,y; } pont p=new pont(); p.x=2; p.y=4;

Br a struktra rtk tpus, azrt a new opertorral kell biztostani a sajt konstruktorral trtn inicializcit. Ez ebben az esetben a vermen fog elhelyezkedni.

IV. sszetett adattpusok Befejezsl a struktra definilsra, hasznlatra, struktra vektorra nzznk egy teljesebb pldt: Plda:
using System; struct struktra_plda { public int kor; public string nv; } class struktra_hasznl { public static void Main() { struktra_plda sp=new struktra_plda(); sp.kor=5; sp.nv="va"; // struktra_plda vektor struktra_plda [] spv=new struktra_plda[5]; int i=0; // beolvass while(i<5) { spv[i]=new struktra_plda(); Console.WriteLine("Krem az {0}. elem nevt!",i); string n=Console.ReadLine(); spv[i].nv=n; Console.WriteLine("Krem az {0}. elem kort!",i); n=Console.ReadLine(); spv[i].kor=Convert.ToInt32(n); i++; } // kirs for(i=0;i<5;i++) { Console.WriteLine(spv[i].nv); Console.WriteLine(spv[i].kor); } } }

IV.3. Feladatok
1. Mit neveznk tmbnek?

IV. sszetett adattpusok 2. Milyen tmbk ltrehozst tmogatja a C# nyelv? 3. Mi a klnbsg a tmb s a struktra kztt? 4. Hatrozzuk meg egy tmb legnagyobb elemt! 5. brzoljuk struktra tpussal az alma legjellemzbb adatait (nv, szn, mret)! Ksztsnk 5 elem alma vektort!

V. Utastsok
A programvezrls menett az utastsok szekvencija szabja meg. Ahogy korbban is lttuk, az opercis rendszer a Main fggvnynek adja t a vezrlst, majd a fggvnytrzs egyms utn kvetkez utastsait (szekvencia) hajtja vgre, ezutn tr vissza a vezrls az opercis rendszerhez. Az utastsok fajti: sszetett utasts kifejezs utasts elgazs utasts ciklus utasts ugr utasts

V.1. sszetett utasts


Ahol utasts elhelyezhet, ott szerepelhet sszetett utasts is. Az sszetett utasts vagy blokk a {} zrjelek kztt felsorolt utastsok listja. Blokkon bell vltozk is deklarlhatk, amelyek a blokkban loklisak lesznek. Blokkok tetszlegesen egymsba gyazhatk.

V.2. Kifejezs utasts


Az utasts formja: kifejezs ; Az utasts specilis formja az, amikor a kifejezs elmarad. Az ilyen utastst (;) res vagy nulla utastsnak nevezzk. Ennek termszetesen ltalban nagyon sok rtelme nincs. Az albbi plda egy vltoz rtkt nveli egyesvel egy ciklusban. Plda:
int k=5; for(i=0; i<10; i++) k++;

56

V. Utastsok

V.3. Elgazs utasts


Az elgazsok kt tpusa hasznlhat, a ktfel s a sokfel elgaz utasts. A ktfel elgaz utasts formja: if (kifejezs) utasts; if (kifejezs) utasts; else utasts; Elszr a kifejezs kirtkeldik, majd annak igaz rtke esetn a kifejezs utni utasts, hamis rtke esetn az else ha van utni utasts hajtdik vgre. Egymsba gyazs esetn az else gat a legutbbi else nlkli ifhez tartoznak tekintjk. Plda:
if (c=='a') Console.WriteLine("Ez az a bet"); else Console.WriteLine("Nem az a bet");

Ha az igaz gon sszetett utastst hasznlunk, akkor utna pontosvessz nem kell, illetve ha mgis van, az az if lezrst jelenten, s hibs lenne az utastsunk az if nlkli else hasznlata miatt. Plda:
if (c=='a') { Console.WriteLine("Ez az a bet");} else Console.WriteLine("Nem az a bet");

A tbbirny elgazs utastsa, a switch utasts formja:

switch (kifejezs) { case rtk1: utasts1 ; case rtk2: utasts2 ; default: utasts ; };

V. Utastsok A switch utni kifejezs nem csak egsz rtk lehet, hanem szveg (string) is. Ha a kifejezs rtke a case utn megadott rtkkel nem egyezik meg, akkor a kvetkez case utni rtk vizsglata kvetkezik. Ha egy case utni rtk azonos a kifejezs rtkvel, akkor az ez utni utasts vgrehajtdik. Ha egy case gban nincs egyrtelm utasts arra vonatkozan, hogy hol folytatdjon a vezrls, akkor fordtsi hibt kapunk. A C++ nyelvet ismerk tudhatjk, hogy abban a nyelvben egy case g vgt nem kellett vezrlstadssal befejezni, s ebbl gyakran addtak hibk. Minden elgazsgat, mg a default gat is, ktelez valamilyen vezrlstadssal befejezni! (break, goto, return) Plda:
switch (parancs) { case "run": Run(); break; case "save": Save(); break; case "quit": Quit(); break; default: Rossz(parancs); break; }

A case belpsi pont utn csak egy rtk adhat meg, intervallum vagy tbb rtk megadsa nem megengedett, hiszen ezek az 'rtkek' gyakorlatilag egy cmke szerept tltik be. Ha kt rtkhez rendeljk ugyanazt a tevkenysget, akkor kt cmkt kell definilni. Plda:
switch (a) { case 1: case 2: Console.WriteLine("Egy s kett esetn"); break; default:Console.WriteLine("Egybknt"); break; };

V. Utastsok

V.4. Ciklus utasts


A ciklus utastsnak ngy formja alkalmazhat a C# nyelvben, ezek a while, a do, a for s a foreach ciklus utastsok.

V.4.1. while utasts


A while ciklus utasts formja: while (kifejezs) utasts; Elszr a zrjelben lv kifejezs kirtkeldik, ha rtke igaz, akkor a zrjeles kifejezst kvet utasts amit szoks ciklusmagnak nevezni , vgrehajtdik. Ezutn jbl a kifejezs kirtkelse kvetkezik, igaz rtk esetn pedig a ciklusmag vgrehajtsa. Ez az ismtls addig folytatdik, amg a kifejezs hamis rtket nem ad. Mivel az utasts elszr kirtkeli a kifejezst s csak utna hajtja vgre a ciklusmagot (ha a kifejezs igaz rtket adott), ezrt a while ciklus utastst elltesztel ciklusnak is szoks nevezni. Plda:
while(true) { Console.Writeline("Vgtelen ciklus!"); Console.WriteLine("Ilyet ne nagyon hasznlj!"); } static void Main() // betnknti kirs { string szveg[]="Szveg!"; int i=0; while(i<szveg.Length) // a string vgig { Console.WriteLine(szveg[i]); i++; } }

A msodik pldban a ciklusmagban hasznlhattam volna egy utastst is, kihasznlva a ++ opertor postfix alakjt az albbi mdon:
while(i<szveg.Length) Console.WriteLine(szveg[i++]);

V. Utastsok

V.4.2. do utasts
Az utasts formja: do utasts; while (kifejezs) ; A ciklusmag a do s a while kztti rsz vgrehajtsa utn kirtkeli a kifejezst, s amg a kifejezs igaz rtket ad, megismtli a ciklusmag vgrehajtst. A do ciklust szoks htultesztel ciklusnak is nevezni. Plda:
string nv; do { Console.WriteLine("Ki vagy?"); nv=Console.ReadLine(); } while (nv!="Zoli"); Console.WriteLine("Szia {0}!",nv); do Console.WriteLine("Biztos egyszer lefut!"); while(false);

V.4.3. for utasts


Az utasts formja: for (kifejezs1; kifejezs2; kifejezs3) utasts; Ez az utasts egyenrtk a kvetkez alakkal:
kifejezs1; while (kifejezs2) { utasts; kifejezs3; };

Mindegyik kifejezs elmaradhat. Ha kifejezs2 is elmarad, akkor while (true)-knt tekinti a ciklust. A kifejezsek kztti pontosvessz nem maradhat el. A kifejezs1 tpusdefincs kifejezs utasts is lehet. Nagyon gyakran lthat forrskdban az albbi forma:

V. Utastsok Plda:
for (int i=0; i<10; i++) Console.WriteLine("Hajr Fradi!");

Ez a fajta ciklus hasznlat felel meg pldul a Basic ForNext ciklusnak.

V.4.4. foreach utasts


Az utasts formja: foreach (azonost in vektor) utasts; Ez az utasts egyenrtk a vektor-elemeken trtn vgiglpdelssel. Az azonost, mint ciklusvltoz felveszi egyenknt e vektor elemeit. Plda:
public static void Main() { int paros = 0, paratlan = 0; int[] v = new int [] {0,1,2,5,7,8,11}; foreach (int i in v) { if (i%2 == 0) paros++; else paratlan++; } Console.WriteLine("Talltam {0} pros, s {1} pratlan szmot.",paros, paratlan); }

A foreach ciklus az ltalunk definilt vektorokon kvl az ehhez hasonl knyvtri adatszerkezeteken is (ArrayList, Queue stb.) jl hasznlhat. Ezzel kapcsolatos pldt a Helyi knyvtrak hasznlata fejezetben lthatunk. A foreach utasts nemcsak kzvetlen vektortpuson, mint pldul a fenti v vektoron alkalmazhat, hanem minden olyan vgigjrhat tpuson, amely az albbi feltteleknek megfelel: A tpus rendelkezzen egy GetEnumerator() fggvnnyel, aminek eredmnyl kell adni azt a tpust, amilyen tpus elemeken lpdelnk vgig. Definiljunk egy MoveNext() fggvnyt, amelyik az indexet aktulisra lltja, s logikai visszatrssel megadja, hogy van-e mg maradk elem. Definiljunk egy Current tulajdonsgot, ami az aktulis index elemt adja eredmnyl.

V. Utastsok Plda:
using System; public class adatsor { int[] elemek; public adatsor() { elemek = new int[5] {12, 44, 33, 2, 50}; } public vektor GetEnumerator() { return new vektor(this); } // Az "enumerator", class definils: public class vektor { int Index; adatsor a; public vektor(adatsor ad) { a = ad; Index = -1; } public bool MoveNext() { Index++; return(Index < a.elemek.GetLength(0)); } public int Current { get { return(a.elemek[Index]); } } } public class MainClass { public static void Main() { adatsor adatok = new adatsor(); }

V. Utastsok
Console.WriteLine("Az adatsor elemei:"); // elemek kirsa foreach (int i in adatok) { Console.WriteLine(i); }

} } /*Eredmny: 12 44 33 2 50*/

V.5. Ugr utastsok


V.5.1. break utasts
Az utasts formja: break; Hatsra befejezdik a legbels while, do, for vagy switch utasts vgrehajtsa. A vezrls a kvetkez utastsra addik. Plda:
int i=1; while(true) // ltszlag vgtelen ciklus { i++; if (i==11) break; // Ciklus vge Console.WriteLine( i); }

A break a tbbirny elgazs (switch) utastsban is gyakran hasznlt, gy kerlhetjk el, hogy a nem kvnt case gak vgrehajtdjanak.

V.5.2. continue utasts


Az utasts formja: continue;

V. Utastsok Hatsra a legbels while, for, do ciklus utastsokat vezrl kifejezsek kerlnek kirtkelsre. (A ciklus a kvetkez ciklusmag vgrehajtshoz kszl.) Plda:
int i=1; while(true) { i++; if (i<=10) continue; // 10 elem ciklus // kvetkez ciklusmag

if (i==11) break; // Ciklus vge Console.WriteLine( i);

A fenti pldban a continue utasts miatt a Console.WriteLine(i) utasts egyszer sem hajtdik vgre.

V.5.3. return utasts


Az utasts formja: return ; return kifejezs; return (kifejezs); A vezrls visszatr a fggvnybl, a kifejezs rtke a visszaadott rtk.

V.5.4. goto utasts


Az utasts formja: goto cmke; A vezrls arra a pontra addik, ahol a cmke: tallhat. Plda:
goto tovbb; Console.WriteLine("Ezt a szveget sohase rja ki!"); tovbb:; int i=1; switch (i) { case 0: nulla();

V. Utastsok
goto case 1; case 1: egy(); goto default; default: valami(); break;

A goto utastsrl zrskppen meg kell jegyezni, hogy a strukturlt programksztsnek nem felttlenl rsze ez az utasts, gy hasznlata sem javasolt. A knyv ksbbi pldaprogramjaiban sem fordul el egyszer sem ez az utasts.

V.5.5. using utasts


A using kulcssz ktfle nyelvi krnyezetben szerepelhet. Egyrszt n. direktva, knyvtri elemek, adott nvtr, osztly hasznlataknt. Ennek formja: using nvtr_vagy_osztly; Plda:
using System; // // // // // a keretrendszer f nvternek hasznlata a C++ #include-hoz hasonlan megmondja a fordtnak, hogy ennek a nvtrnek a tpusait is hasznlja. Ezen tpusokat azrt enlkl is teljes nvvel (System.Console) hasznlhatjuk

A msik eset a using utasts. Egy ideiglenesen hasznlt objektum esetn a using utasts utn a keretrendszer automatikusan meghvja az objektum Dispose metdust. A using utasts alakja a kvetkez: using (objektum) { utastsok;} Plda:
using (Objektumom o = new Objektumom()) { o.ezt_csinald(); }

V. Utastsok Ez a hasznlat az albbi kdrszletnek felel meg, a nem ismert nyelvi elemeket ksbb ismertetjk:
Objektumom o = new Objektumom(); try {o.ezt_csinald();} finally { if (o != null) ((IDisposable)o).Dispose(); }

A Dispose utastst s krnyezett bvebben a destruktorokkal kapcsolatban rszletezzk.

V.5.6. lock utasts


Ha egy kritikus utasts blokk vgrehajtsakor egy referencia blokkolsra van szksg a biztonsgos vgrehajtshoz, akkor ezt a lock utastssal megtehetjk. A lock kulcssz egy referencit vr, ez jellemzen a this, majd utna kvetkezik a kritikus blokk. Ennek formja: lock(ref) utasts; Plda:
lock(this) { a=5; // biztonsgos }

A lock utastsnak, ahogy lttuk, a leggyakrabban hasznlt paramtere a this, ha a vdett vltoz vagy fggvnyutasts nem statikus. (Osztlypldnyok.) Ha statikus vltozkat vagy fggvnyutastsokat szeretnnk biztostani (lockolni), hogy egyszerre csak egy vgrehajtsi szl tudjon hozzfrni, akkor a lock referencinak az osztly tpust kell megadni. Plda:
class adatok { static int szamlalo=0; public void mentes(string s)

V. Utastsok
{ lock(typeof(adatok)) { szamlalo++; Console.WriteLine("Adatments elindul!"); for(int i=0;i<50;i++) { Thread.Sleep(1); Console.Write(s); } Console.WriteLine(""); Console.WriteLine("Adatments {0}.alkalommal befejezdtt!",szamlalo); }

} }

A plda bvebb magyarzata, teljes krnyezetbeli alkalmazsa a IX. rsz Prhuzamos programvgrehajts fejezetben tallhat.

V.6. Feladatok
1. Milyen tpus adat szerint kszthetnk tbbirny (switch) elgazst? 2. Milyen elltesztel s htultesztel ciklusokat hasznlhatunk? 3. Mire hasznlhat a break utasts? 4. rjon rvid programot, amely beolvassa egy focicsapat, adott fordulban szerzett pontszmt (0,1,3) egy egsz tpus vltozba, majd felhasznlva a switch utastst a beolvasott rtk alapjn kirja a kvetkez szvegeket: gyzelem, dntetlen, veresg, hibs adat. 5. rjon programot, amelyik beolvas egy kettvel oszthat, 10 s 100 kz es egsz szmot! (Ha rossz rtket adnak meg, akkor addig folytassa a beolvasst, amg a feltteleknek megfelel szmot nem sikerl megadni!)

VI. Fggvnyek
VI.1. A fggvnyek paramtertadsa
Ha egy fggvnynek adatot adunk t paramterknt, akkor alapveten kt klnbz esetrl beszlhetnk. Egy adat rtk szerint s hivatkozs szerint kerlhet tadsra. Az els esetben valjban az eredeti adatunk rtknek egy msolata kerl a fggvnyhez, mg a msodik esetben az adat cme kerl tadsra.

VI.1.1 rtk szerinti paramtertads


ltalnosan elmondhatjuk, hogyha nem jellnk semmilyen paramtertadsi mdszert, akkor rtk szerinti paramtertadssal dolgozunk. Ekkor a fggvny paramterben, mint formlis paramterben, a fggvny meghvsakor a hvrtk msolata helyezkedik el. Tekintsk meg a kvetkez maximum nev fggvnyt, aminek az a feladata, hogy a kapott kt paramtere kzl a nagyobbat adja vissza eredmnyknt. Plda:
class maxfv { static int maximum(int x,int y) { return (x>y?x:y); } static void Main() { Console.WriteLine(maximum(4,3)); } }

Az gy megvalstott paramtertadst rtk szerinti paramtertadsnak nevezzk, a maximum fggvny kt (x s y) paramtere a hvskor megadott kt paramtert kapja rtkl. rtk szerinti paramtertadsnl, hvskor konstans rtk is megadhat. A fggvny hvsnak egy sajtos esete az, mikor egy fggvnyt sajt maga hv meg. Szoks ezt rekurzv fggvnyhvsnak is nevezni. Erre pldaknt nzzk meg a klasszikus faktorilisszmol fggvnyt.

68

VI. Fggvnyek Plda:


{

class faktor
static int faktorialis(int x) { return (x<=1?1: (x* faktorialis(x-1)); } static void Main() { Console.WriteLine(faktorialis(4)); }

VI.1.2. Referencia (cm) szerinti paramtertads


Amikor egy fggvny paramtere nem a vltoz rtkt, hanem a vltoz trolsi helynek cmt, hivatkozsi helyt kapja meg a fggvny meghvsakor, akkor a paramtertads mdjt cm szerinti paramtertadsnak nevezzk. A cm szerinti paramtertadst gyakran hivatkozs (reference) szerinti paramtertadsnak is szoks nevezni. Ha a paramternv el a ref (hivatkozs) kulcsszt beszrjuk, akkor a hivatkozs szerinti paramtertadst definiljuk. Ezt a kulcsszt be kell szrnunk a fggvnydefinciba s a konkrt hvs helyre is! Pldaknt rjunk olyan fggvnyt, ami a kapott kt paramternek rtkt felcserli. Plda:
// a ref kulcssz jelzi, hogy referencia // paramtereket vr a fggvny void csere(ref int x, ref int y) { int segd=x; x=y; y=segd; } static void Main() { int a=5, b=6; Console.WriteLine("Csere eltt: a={0}, b={1}.", a , b); // fggvnyhvs, a ref kulcssz itt is ktelez csere(ref a,ref b); Console.WriteLine("Csere utn: a={0}, b={1}.", a , b); }

A csere(a,b) hvs megcserli a kt paramter rtkt, gy az a vltoz rtke 6, mg b rtke 5 lesz.

VI. Fggvnyek

VI.1.3. Fggvnyeredmny paramtere


A referencia szerinti paramtertadshoz hasonlan, a fggvnybeli vltoz rtke kerl ki a hv vltozba. A klnbsg csak az, hogy ebben a vltozban a fggvny nem kap rtket. Az eredmny paramtert az out kulcsszval definilhatjuk. A hvskor is a paramter el ki kell rni az out jelzt. A hasznlata akkor lehet hasznos, amikor egy fggvnynek egynl tbb eredmnyt kell adnia. Plda:
using System; public class MyClass { public static int TestOut(out char i) { i = 'b'; return -1; } public static void Main() { char i; // nem kell inicializlni a vltozt Console.WriteLine(TestOut(out i)); Console.WriteLine(i); } } Kperny eredmny: -1 B

VI.1.4. Tmbk paramtertadsa


A nyelv a tmbt annak nevvel, mint referencival azonostja, ezrt egy tmb paramtertadsa nem jelent mst, mint a tmb referencijnak tadst. Egy fggvny termszetesen tmbt is adhat eredmnyl, ami azt jelenti, hogy az eredmny egy tmbreferencia lesz. Egy tmb esetben sincs msrl sz, mint egyszer vltozk esetben, a tmbreferencia egy referenciavltoz , rtk szerinti paramtertadsrl. Az elmondottak illusztrlsra lssuk a kvetkez sematikus pldt.

VI. Fggvnyek Plda:


void mdost(int[] vektor) { // a vektort, mint egy referencit kapjuk paramterl // ez rtk szerint kerl tadsra, azaz ez a referencia //nem vltozik, vltozik viszont a 0. tmbelem, s ez a // vltozs a hv oldalon is ltszik vektor[0]=5; }

Ahogy a fenti pldn is lthat, a vektor paramterknt a referencijval kerl tadsra. Ez rtk szerinti paramtertadst jelent. Ha egy fggvnyben a mutatott rtket (vektorelemet) megvltoztatom, akkor a vltozs a kls, paramterknt tadott vektorban is lthat lesz! A nyelvben a vektor tudja magrl, hogy hny eleme van (Length), ezrt ellenttben a C++ nyelvvel , az elemszmot nem kell tadni. Tmb esetben is alkalmazhatjuk a referencia vagy out paramter tadsnak lehetsgt. Ennek illusztrlsra nzzk a kvetkez pldkat: 1. plda:
using System; class teszt { static public void feltlt(out int[] vektor) { // a vektor ltrehozsa, s inicializlsa vektor = new int[5] {1, 2, 3, 4, 5}; } static public void Main() { int[] vektor; // nem inicializltuk // meghvjuk a feltlt fggvnyt: feltlt(out vektor); // A vektorelemek kirsa: Console.WriteLine("Az elemek:"); for (int i=0; i < vektor.Length; i++) Console.WriteLine(vektor[i]); } }

VI. Fggvnyek 2. plda:


using System; class Refteszt { public static void feltlt(ref int[] arr) { // Ha hv fl mg mg nem ksztette el, //akkor megtesszk itt. if (arr == null) arr = new int[10]; // nhny elem mdosts arr[0] = 123; arr[4] = 1024; // a tbbi elem rtke marad az eredeti } static public void Main () { // Vektor inicializlsa int[] vektor = {1,2,3,4,5}; // Vektor tadsa ref, paramterknt: feltlt(ref vektor); // Kirs: Console.WriteLine("Az elemek:"); for (int i = 0; i < vektor.Length; i++) Console.WriteLine(vektor[i]); } }

VI.2. A Main fggvny paramterei


A parancsok, programok indtsakor gyakori, hogy a parancsot valamilyen paramter(ek)rel indtjuk. Ilyen parancs pldul a DOS echo parancsa, amely paramtereit a kpernyre visszhangozza, vagy a type parancs, mely a paramterl kapott fjl tartalmt rja a kpernyre. Ezeket a paramtereket parancssor-argumentumoknak is szoks nevezni. Amikor elindtunk egy programot (a Main fggvny az opercis rendszertl tveszi a vezrlst), akkor hvskor a Main fggvnynek egy paramtere van. Ez a paramter egy szveges (string) tmb, amelynek elemei az egyes paramterek. A paramtertmbt gyakran args nvre keresztelik.

VI. Fggvnyek A parancssor-argumentumok hasznlatra nzzk az imnt mr emltett echo parancs egy lehetsges megvalstst. Plda:
static void Main(string[] args) { int i=0; while (i<args.Length) { Console.WriteLine(args[i]); i++; } }

Ha a fenti programot lefordtjuk, s a neve parancs.exe lesz, akkor a kvetkezkppen prblhatjuk ki:
c:\parancs.exe fradi vasas jpest

A program futtatsa utn az albbi eredmnyt kapjuk:


fradi vasas jpest

A parancssori paramterek Visual Studio.NET krnyezetet hasznlva a projekt Tulajdonsg ablakban is megadhatk: Configuration Properties \ Debugging \ Command Line Arguments, ahogy az albbi kpen is lthat.

9. bra

VI. Fggvnyek A Main fggvnyt, abban az esetben, ha a parancssori paramtereket nem akarjuk feldolgozni, a paramterei nlkl is deklarlhatjuk: static void Main()
{}

VI.3. Fggvnyek vltoz szm paramterrel


A feladatmegoldsok sorn gyakran elfordulhat, hogy elre nem tudjuk eldnteni, hny elemet kell a fggvnynek feldolgoznia. Teht nem tudjuk, hogy hny paramterrel ksztsk el a kvnt fggvnynket. A params kulcssz segtsgvel egy vektorparamtert definilhatunk a fggvnynek, ami ezeket a paramtereket tartalmazza majd. Nzznk nhny pldt ilyen fggvny definilsra, majd a hasznlatra. Plda:
using System; public class vltparamter { public static void intParamterek(params int[] list) { for ( int i = 0 ; i < list.Length ; i++ ) Console.WriteLine(list[i]); Console.WriteLine(); } public static void objParamterek(params object[] list) { for ( int i = 0 ; i < list.Length ; i++ ) Console.WriteLine(list[i]); Console.WriteLine(); } public static void Main() { intParamterek(1, 2, 3); objParamterek(1, "fradi", "teszt", 3.5); int[] myarray = new int[3] {10,11,12}; intParamterek(myarray); } }

VI. Fggvnyek Az eredmny a kvetkez lesz:


1 2 3 1 fradi teszt 3.5 10 11 12

Egy vltoz paramterszm fggvnynek lehetnek fixen megadott paramterei is. A fixen megadott paramtereknek ktelezen meg kell elznik a vltoz paramtereket. A kvetkez plda egy ilyen fggvnydefincit mutat. Plda:
using System class parameters { public static void valtozo(int x, params object[] list) { Console.WriteLine(x); foreach (object o in list) Console.WriteLine(o); } public static void Main() { valtozo(25, "alma", "barack","szilva"); } }

Eredmnyl kapjuk a fggvny paramtereinek kirst egyms al.

VI.4. Fggvnynevek tdefinilsa


Egy-egy feladat esetn gyakorta elfordul, hogy a megoldst ad fggvnyt klnbz tpus vagy klnbz szm paramterrel jellemezhetjk. Termszetesen az ezt megold fggvnyt azonos nvvel szeretnnk elkszteni minden esetben, hisz ez lenne a legkifejezbb. A lehetsget gyakran fggvny overloading nvvel is megtalljuk az irodalomban, vagy a polimorfizmus kapcsn kerl megemltsre.

VI. Fggvnyek Hatrozzuk meg kt szm maximumt! Ha el szeretnnk kerlni a tpuskonvertlst mondjuk egsz tpusrl valsba s fordtva, akkor kln az egsz s kln a vals szmok esetre is meg kell rnunk a maximum fggvnyt. Knyelmetlen dolog lenne, ha mondjuk egszmax s valsmax nven kellene megrni a kt fggvnyt. Mindkt esetben szeretnnk a maximum fggvnynevet hasznlni, hogy ne neknk kelljen eldnteni azt, hogy az egszek vagy valsak maximumt akarjuk-e meghatrozni, hanem dntse el a fordt a paramterlista alapjn automatikusan, hogy melyik fggvnyt is kell az adott esetben meghvni. Plda:
// vals maximum fggvny double maximum(double x,double y) { if (x>y) return x; else return y; } // egsz maximum fggvny int maximum(int x,int y) { if (x>y) return x; else return y; } int a=2,b=4; double c=3.123, d=2; Console.WriteLine(maximum(4.1,2)); Console.WriteLine(maximum(4,2)); Console.WriteLine(maximum(a,b)); Console.WriteLine(maximum(c,d));

// vals hvs // egsz hvs // egsz hvs

Meg kell jegyezni, hogy ezt a tulajdonsgot sok nyelvben fggvnysablon (template) tulajdonsg segtsgvel elegnsabban oldhatnnk meg, de a jelenlegi C# ezt nem tmogatja.

VI. Fggvnyek

VI.5. Delegltak, esemnyek


Ahogy korbban is sz volt rla, a biztonsgosabb programkd ksztsnek rdekben a mutat aritmetika a C# nyelvben nem engedlyezett. Ebbe beletartozik az is, hogy a fggvnymutatk sem lehetnek kivtelek. Ez utbbi esetben viszont olyan nyelvi tulajdonsgok nem implementlhatk, mint pldul egy menponthoz hozzrendelt fggvny, amit a menpont vlasztsa esetn kell vgrehajtani. Ezen utbbi lehetsget hivatott a deleglt tpus biztostani. Ez mr csak azrt is fontos, mert tbbek kztt a Windows programozs callback jellemz paramtere is ezt hasznlja. A C++ krnyezetben ezt a lehetsget a fggvnymutat biztostja. A deleglt valjban egy fggvnytpus-definci, aminek alakja a kvetkez: delegate tpus delegltnv(tpus paramternv,); A deleglt referencia tpus. Ha paramtert is megadunk, akkor a paramter nevt is meg kell adni. Plda:
delegate int pelda(int x, string s);

Az elbbi pldban teht a pelda deleglt tpust definiltuk. Ez olyan fggvnytpus, amelyiknek egy egsz s egy szveg paramtere van, s eredmnyl egy egsz szmot ad. Egy deleglt objektumnak vagy egy osztly statikus fggvnyt, vagy egy osztly pldnyfggvnyt adjuk rtkl. Deleglt meghvsnl a hagyomnyos fggvnyhvsi formt hasznljuk. Ezek utn nzznk egy konkrt pldt: Plda:
using System; class proba { public static int negyzet(int i) { return i*i; } public int dupla(int i) { return 2*i; } }

VI. Fggvnyek
class foprogram { delegate int emel(int k); // az emel deleglt definilsa public static void Main() { emel f=new emel(proba.negyzet); // statikus fggvny lesz a deleglt Console.WriteLine(f(5)); // eredmny: 25 proba p=new proba(); emel g=new emel(p.dupla); // norml fggvny lesz a deleglt Console.WriteLine(g(5)); // eredmny: 10 }

A delegltakat a krnyezet kt csoportba sorolja. Ha a deleglt visszatrsi tpusa void, akkor egy deleglt tbb vgrehajtand fggvnyt tartalmazhat (multicast, sszetett deleglt), ha nem void a visszatrsi tpus, mint a fenti pldban, akkor egy deleglt csak egy vgrehajtand fggvnyt tud meghvni (single cast, egyszer deleglt). Az egyszer s sszetett delegltakra nzzk a kvetkez pldt: Plda:
using System; class proba { public static int negyzet(int i) { return i*i; } public int dupla(int i) { return 2*i; } public int tripla(int i) { return 3*i; } public void egy(int i) { Console.WriteLine(i); } public void ketto(int i) { Console.WriteLine(2*i); } }

VI. Fggvnyek
class foprogram { delegate int emel(int k); delegate void meghiv(int j); public static void Main() { emel f=new emel(proba.negyzet); Console.WriteLine(f(5)); proba p=new proba(); emel g=new emel(p.dupla); Console.WriteLine(g(5)); emel h=new emel(p.tripla); g+=h; //g single cast, g a tripla lesz Console.WriteLine(g(5)); // eredmny: 15 meghiv m=new meghiv(p.egy); // multicast deleglt m+=new meghiv(p.ketto); m(5); // deleglt hvs, eredmny 5,10 } }

Ha fggvnymutat tpust (deleglt) deklarlunk, akkor rtkads esetn a mutat tpusa hatrozza meg, hogy a fordtnak melyik aktulis fggvnyt is kell az azonos nevek kzl vlasztania.
delegate double vmut(double,double); // vmut olyan deleglt amelyik egy vals rtket visszaad, // s kt vals paramtert vr fggvnyt jelent delegate int emut(int,int); // emut olyan deleglt, amelyik egy egsz rtket visszaad // , s kt egsz paramtert vr fggvnyt jelent vmut mut=new vmut(maximum);// vals hvs Console.WriteLine(mut(3,5));

A multicast deleglt (tpus) definilsi lehetsget, igaztva az ignyeket az esemnyvezrelt programozsi krnyezethez (mind a Windows, mind az X11 ilyen), az egyes objektumokhoz, tpushoz gy kapcsolhatjuk, hogy esemny tpus mezt adunk hozzjuk. Ezt az albbi formban tehetjk meg: public event meghiv esemeny; ahol a meghiv sszetett deleglt. Az esemny objektum kezd rtke null lesz, gy az automatikus meghvs (esemeny()) nem ajnlott!

VI. Fggvnyek Az esemnyhez zrskppen meg kell jegyezni, hogy az egsz keretrendszer a felhasznli tevkenysget ehhez a lehetsghez rendeli akkor, amikor klasszikus Windows alkalmazst akarunk kszteni. Pldaknt nzzk meg egy Windows alkalmazs esetn a form tervez ltal generlt kdot. A form (this) objektuma egy vlasztmez (ComboBox), ampl nvre hallgat. Ennek knyvtri esemnye, a SelectedIndexChanged vgrehajtdik (a keretrendszer hajtja vgre), ha mdostunk a vlasztson. Mikor ehhez az esemnyhez egy esemnykezel fggvnyt definilunk ampl_SelectedIndexChanged nven, akkor az albbi sort adja a programhoz a tervez: Plda:
this.ampl.SelectedIndexChanged += new System.EventHandler(this.ampl_SelectedIndexChanged);

VI.6. Feladatok
1. Milyen paramtertadsi mdokat ismer? 2. Mikor definilhatunk azonos nvvel fggvnyeket egy osztlyban? 3. Hogyan kell vltoz paramterszm fggvnyt hasznlni? 4. rjon egy fggvnyt, amely a paramterknt megadott nhny nv kzl a leghosszabb hosszat adja meg! 5. Definiljon kupafordul esemnyt, melyekre a szurkolk jelentkezhetnek. Kupafordul esetn hvjuk meg a feliratkozott szurkolkat a mrkzsre!

VII. Osztlyok
C#-ban az osztlyok a mr ismert sszetett adatszerkezetek (struktrk) egy termszetes kiterjesztse. Az osztlyok nemcsak adattagokat, hanem opertorokat, fggvnyeket is tartalmazhatnak. Az osztlyok hasznlata esetn ltalban az adatmezk az osztly ltal ppen lerni kvnt esemny llapotjelzi, mg a fggvnymezk az llapotvltozsokat rjk le, felhasznli felletet biztostanak. A fggvnymezket gyakran metdusoknak is nevezi a szakirodalom. Osztlymezket lehetsgnk van zrtt nyilvntani (encapsulation), ezzel biztostva az osztly bels harmnijt. Ezek az osztlymezk ltalban az llapotjelz adatmezk. j ignyek, mdostsok esetn lehetsgnk van az eredeti osztly megtartsa mellett, abbl a tulajdonsgok megrzsvel egy j osztly szrmaztatsra, amely rkli (inheritance) az sosztly tulajdonsgait (az osztlyok elemeit). A C++ nyelvben lehetsgnk van arra, hogy tbb osztlybl szrmaztassunk utdosztlyt (multiple inheritance), esetnkben ezt a jellemzt a CLR nem tmogatja, gy ennek a fejlesztkrnyezetnek egyik nyelve sem tmogatja a tbbszrs rkls lehetsgt. Lehetsgnk van interface defincira, amiket egy osztly implementlhat. Egy osztly tbb interface-t is implementlhat. Az rkls lehetsgnek a gyakorlatban legelszr jelentkez haszna taln az, hogy a programunk forrskdja jelentsen cskkenhet. Egy osztlytpus vltozt, az osztly megjelensi alakjt gyakran objektumnak is szoks nevezni. Az osztlyok hasznlathoz nhny jtancsot, a nyelv jobbkz-szablyt a kvetkez pontokban foglalhatjuk ssze. Ezek a tancsok termszetesen nem a nyelv tanulsi idszakra, hanem a ksbbi, a nyelvben trtn programozsi feladatokra vonatkoznak elssorban. Ha egy programelem nll rtelmezssel, feladattal, tulajdonsgokkal rendelkezik, akkor definiljuk ezt az elemet nll osztlyknt. Ha egy programrsz adata nll objektumknt rtelmezhet, akkor definiljuk t a kvnt osztlytpus objektumaknt. Ha kt osztly kzs tulajdonsgokkal rendelkezik, akkor hasznljuk az rkls lehetsgt. ltalban is elmondhat, hogy ha a programokban az osztlyok kzs vonsokkal rendelkeznek, akkor trekedni kell univerzlis bzisosztly ltrehozsra. Gyakran ezt absztrakt bzisosztlynak is nevezzk. Az osztlyok definilsakor kerljk a nyitott (publikus) adatmezk hasznlatt.

81

VII. Osztlyok

VII.1. Osztlyok definilsa


Az osztlyok deklarcijnak alakja a kvetkezkppen nz ki: osztlykulcssz osztlynv [: szl, ] { osztlytaglista }; Az osztlykulcssz a class, struct sz lehet. Az osztlynv az adott osztly azonost neve. Ha az osztly valamely bzisosztlybl szrmazik, akkor az osztlynv, majd kettspont utn az sosztly felsorolsa trtnik. Az osztlyok tagjainak t elrsi szintje lehet: private public protected internal protected internal.

A private tagokat csak az adott osztlyon bellrl rhetjk el. Az osztlyok publikus mezit brhonnan elrhetjk, mdosthatjuk. A protected mezk az osztlyon kvliek szmra nem elrhetek, mg az utdosztlybl igen. Az internal mezket a kszl program osztlyaibl rhetjk el. A protected internal elrs valjban egy egyszer vagy kapcsolattal megadott hozzfrsi engedly. A mez elrhet a programon bellrl, vagy az osztly utdosztlybl! (Egy osztlybl termszetesen tudunk gy utdosztlyt szrmaztatni, hogy ez nem tartozik az eredeti programhoz.) Ha az osztly definilsakor a struct szt hasznljuk, akkor abban elssorban adatok csoportjt szeretnnk sszefogni, ezrt gyakran tancsknt is olvashatjuk, hogy ha hagyomnyos rtelemben vett struktrt, mint sszetett adatszerkezetet szeretnnk hasznlni, akkor azt struct tpus osztlyknt definiljuk. Az egyes meznevekre val hivatkozs ugyangy trtnik, ahogy korbban a struktrk esetben. Az osztlydefinci alakjnak ismeretben nzznk egy konkrt pldt!

VII. Osztlyok Plda:


class els { private int x; // az x mez privt public void bellt(int mennyi) { x=mennyi;} // fggvnymez public int kiolvas() { return x;} }

Mivel az x az osztly privt mezje, ezrt definiltunk az osztlyba kt fggvnymezt, amelyek segtsgvel be tudjuk lltani, illetve ki tudjuk olvasni az x rtkt. Ahhoz, hogy ezt a kt fggvnyt az osztlyon kvlrl el tudjuk rni, publikusnak kellett ket deklarlni.
static void Main(){ els a = new els(); // legyen egy a nev els tpus // osztlyunk a.x=4; // hiba!!! x privt mez a.bellt(7); // az x mez rtkt 7-re lltjuk Console.WriteLine(a.kiolvas()); }

Osztlyt egy osztlyon vagy egy fggvnyen bell is definilhatunk, ekkor azt bels vagy loklis osztlynak nevezzk. Termszetesen ennek a loklis osztlynak a lthatsga hasonl, mint a loklis vltozk. Mieltt a statikus mezkrl szlnnk, szt kell ejteni a this mutat szereprl. Ez a mutat minden osztlyhoz, struktrhoz automatikusan ltrejn. Ttelezzk fel, hogy definiltunk egy osztlytpust. A programunk sorn van tbb ilyen tpus objektumunk. Felvetdik a krds, hogy amikor az egyes osztlyfggvnyeket meghvjuk, akkor a fggvny vgrehajtsa sorn honnan tudja meg a fggvnynk, hogy most ppen melyik aktulis osztlyobjektumra is kell, hogy hasson? Minden osztlyhoz automatikusan ltrejn egy mutat, aminek a neve this, s az ppen aktulis osztlyra mutat. gy, ha egy osztlyfggvnyt meghvunk, amely valamilyen mdon pldul a privt vltozkra hat, akkor az a fggvny a this mutatn keresztl tudja, hogy mely aktulis privt mezk is tartoznak az objektumhoz. A this mutat konkrtabb hasznlatra a ksbbiek sorn lthatunk pldt. Ttelezzk fel, hogy egy mreszkzt, egy adatgyjtrendszert egy osztlylyal akarunk jellemezni. Ennek az osztlynak az egyes objektumai a mreszkznk meghatrozott tulajdonsgait kpviselik. Viszont az eszkz jelerstsi egytthati azonosak. Ezrt szeretnnk, hogy az osztly erstsmezje kzs legyen, ne objektumhoz, hanem az osztlyhoz ktdjn. Ezt a lehetsget statikus mezk segtsgvel valsthatjuk meg.

VII. Osztlyok Statikus mezket a static jelz kirsval definilhatunk. Ekkor az adott mez minden objektum esetben kzs lesz. A statikus mez kezdrtke inicializls hinyban 0, null, false lesz. Plda:
class teszt { public static int a; // rtke mg 0 public static string s="Katalin"; }; teszt.a=5; // statikus mez rtkadsa, 5 az rtk

Statikus mezk a this mutatra vonatkoz utalst nem tartalmazhatnak, hiszen a statikus mezk minden egyes objektum esetn (azonos osztlybelire vonatkozan) kzsek. Teht pldul statikus fggvnyek nem statikus mezket nem tudnak elrni! Fordtva termszetesen problmamentes az elrs, hiszen egy norml fggvnybl brmely statikus mez, fggvny elrhet.

VII.2. Konstruktor- s destruktor fggvnyek


Adatok, adatszerkezetek hasznlata esetn gyakori igny, hogy bizonyos kezdeti rtkadsi mveleteket, kezdrtk-lltsokat el kell vgezni. A korbban trgyalt tpusoknl lttuk, hogy a defincival egybektve a kezdrtkads elvgezhet. Osztlyok esetn ez a kezdrtkads nem biztos, hogy olyan egyszer, mint volt elemi tpusok esetn, ezrt ebben az esetben egy fggvny kapja meg az osztly inicializlsval jr feladatot. Ez a fggvny az osztly szletsnek pillanatban automatikusan vgrehajtdik, s konstruktornak vagy konstruktor fggvnynek nevezzk. A konstruktor neve mindig az osztly nevvel azonos. Ha ilyet nem definilunk, a keretrendszer egy paramter nlkli automatikus konstruktort definil az osztly szmra. A konstruktor egy szablyos fggvny, gy mint minden fggvnybl, ebbl is tbb lehet, ha msok a paramterei. Az osztly referencia tpus vltoz, egy osztlypldny ltrehozshoz ktelez a new opertort hasznlni, ami egyttal a konstruktor fggvny meghvst vgzi el. Ha a konstruktornak vannak paramterei, akkor azt a tpusnv utn zrjelek kztt kell megadni. A binris fa feladat egyfajta megoldst tekintsk meg pldaknt a konstruktor hasznlatra.

VII. Osztlyok Plda:


using System; class binfa { int x; // elem int db; // elemszm public binfa(int i) // konstruktor { x=i; db=1; bal=jobb=null; } public binfa bal, jobb; public void illeszt(int i) { if (x==i) db++; else if (i<x) if (bal!=null) bal.illeszt(i); else bal= new binfa(i); // bal oldalra illesztettk az elemet else if (jobb!=null) jobb.illeszt(i); else jobb= new binfa(i); // jobb oldalra illesztnk } public void bejar() { // elszr bejrjuk a bal oldali ft if (bal!=null) bal.bejar(); // ezutn jn az aktulis elem Console.WriteLine("Az aktulis elem: {0} darabszm: {1}",x,db); // vgl a jobb oldali fa kvetkezik if (jobb!=null) jobb.bejar(); } } class program { public static void Main() { binfa bf=new binfa(7); Console.WriteLine("Binris fa plda."); bf.illeszt(5); bf.illeszt(9); bf.illeszt(5); bf.bejar(); } }

VII. Osztlyok Futsi eredmnyl az albbit kapjuk:

10. bra

VII.2.1. Statikus konstruktor


Egy osztly, ahogy azt korbban is emltettk, tartalmazhat statikus adat- s fggvnymezket is. Ezen osztlymezk a dinamikusan ltrejv objektum pldnyoktl fggetlenl jnnek ltre. Ezeknek a mezknek az inicializlst vgezheti a statikus konstruktor. Definilsa opcionlis, ha nem definiljuk, a keretrendszer nem hozza ltre. Ha definilunk egy statikus konstruktort, akkor annak meghvsa a program indulsakor megtrtnik, mg azeltt, hogy egyetlen osztlypldnyt is definilnnk. Statikus konstruktor el nem kell hozzfrsi mdostt, visszatrsi tpust rni. Ennek a konstruktornak nem lehet paramtere sem. Plda:
using System; class statikus_osztaly { public static int x; static statikus_osztaly() { x=2; } public int getx() { return x } }

VII. Osztlyok
class program { public static void Main() { // valahol itt a program elejn kerl meghvsra a // statikus_osztly statikus konstruktora, az x rtke 2 lesz!!! Console.WriteLine(statikus_osztaly.x); // 2 statikus_osztaly s=new statikus_osztaly(); // dinamikus pldny Console.WriteLine(s.getx()); // termszetesen ez is 2 lesz } }

VII.2.2. Privt konstruktor


Szksg lehet arra is ha nem is gyakran , hogy egy osztlybl ne tudjunk egyetlen pldnyt se ltrehozni. Termszetesen ebben az esetben nem lteznek a dinamikus mezk sem, gy azok definilsnak nincs is rtelme. Ha nem definilunk konstruktort, akkor a keretrendszer definil egy alaprtelmezettet, ekkor pedig lehet pldnyt kszteni. gy ez nem jrhat t. A problma gy oldhat meg, hogy privt konstruktort definilunk, ami semmit nem csinl (de azt jl), illetve ha formlisan csinl is valamit, nem sok rtelme van, hiszen nem tudja senki kvlrl meghvni! Ebben az esetben termszetesen minden tagja az osztlynak statikus. Plda:
using System; class nincs_peldanya { public static int x=4; public static void fv1() { Console.WriteLine("halih"); } private nincs_peldanya() { // a konstruktortrzs res } }

VII. Osztlyok
class program { public static void Main() { // nem lehet nincs_peldanya tpus vltozt definilni Console.WriteLine(nincs_peldanya.x); // 4 // csak a statikus mezket hasznlhatjuk nincs_peldanya.fv1(); } }

VII.2.3. Sajt destruktor


Ahogy egy osztly definilsakor szksgnk lehet bizonyos inicializl kezdeti lpsekre, gy az osztly vagy objektum elmlsakor is sok esetben bizonyos lpseket kell tennnk. Pldul, ha az osztlyunk dinamikusan foglal magnak memrit, akkor azt hasznlat utn clszer felszabadtani. Azt a fggvnyt, amelyik az osztly megsznsekor szksges feladatokat elvgzi destruktornak vagy destruktor fggvnynek nevezzk. Mr tudjuk, hogy az osztly konstruktornak neve az osztly nevvel egyezik meg. A destruktor neve is az osztly nevvel azonos, csak az elejn ki kell egszteni a ~ karakterrel. A destruktor meghvsa automatikusan trtnik, s miutn az objektumot nem hasznljuk, a keretrendszer automatikusan lefuttatja, s a felszabadul memrit visszaadja az opercis rendszernek. Konstruktornak s destruktornak nem lehet visszaadott rtke. A destruktornak mindig publikus osztlymeznek kell lennie. Ha egy osztlyhoz nem definilunk konstruktort vagy destruktort, akkor a rendszer automatikusan egy alaprtelmezett, paramter nlkli konstruktort, illetve destruktort definil hozz. Ha viszont van sajt konstruktorunk, akkor nem kszl automatikus. A destruktor automatikus meghvsnak a folyamatt szemtgyjtsi algoritmusnak nevezzk (garbage collection, GC). Ez az algoritmus nem azonnal, az objektum blokkjnak, lettartamnak a vgn hvja meg a destruktort, hanem akkor, amikor az algoritmus begyjti ezt a szabad memriaterletet. Ha nem runk sajt destruktor fggvnyt, akkor is a garbage collector minden, az objektum ltal mr nem hasznlt memrit felszabadt az automatikusan definilt destruktor fggvny segtsgvel. Ez azt jelenti, hogy nincs tlzottan nagy knyszer sajt destruktor definilsra. A garbage collector valjban az osztly Finalize fggvnyt hvja meg. Ez azrt lehetsges, mert amikor a programoz formlisan destruktor fggvnyt definil, akkor azt a fordt egy Finalize fggvnyre alaktja az albbiak szerint:

VII. Osztlyok Plda:


class osztly { ~osztly() { . // destruktor fggvnytrzs } }

A fenti osztlydestruktorbl a fordt az albbi kdot generlja:


protected override void Finalize() { try { // destruktor fggvnytrzs } finally { base.Finalize(); } }

A fenti destruktor konstrukcinak egyetlen bizonytalan pontja van, ez pedig a vgrehajts idpontja. Ha szksgnk van olyan megoldsra, ami determinlt destrukcis folyamatot eredmnyez, akkor ezt az n. Dispose metdus implementlsval (ez az IDisposable interface rsze) tehetjk meg. Mieltt ezzel a klasszikus hasznlati formval foglalkoznnk, meg kell ismerkednnk a System nvtr GC osztlynak a szemtgyjtsi algoritmus befolysolsra leggyakrabban hasznlt metdusaival:
void System.GC.Collect();

Kezdemnyezzk a keretrendszer szemtgyjt algoritmusnak indtst:


void System.GC.WaitForPendingFinalizers();

A hv vgrehajtsi szl addig vrakozik, amg a destruktorok hvsnak sora (Finalize fggvnyek hvsi sora) res nem lesz. Semmi garancia nincs arra, hogy ez a fggvnyhvs visszatr, hiszen ettl a szltl fggetlenl ms objektumok is letciklusuk vgre rhetnek.
void System.GC.SupressFinalize(Object o);

VII. Osztlyok Ha egy objektumnak nincs szksge mr semmilyen destrukcira, Finalize fggvnyhvsra, akkor a paramterl adott objektum ilyen lesz:
void System.GC.ReRegisterForFinalize(Object o);

Mris feliratkozunk a destrukcira vrakozk sorba. Termszetesen, ha ezt tbbszr hvjuk meg, akkor az objektum tbbszr a vrakozk sorba kerl. Ahogy korbban emltettk a destruktorral kapcsolatosan, mi nem tudjuk meghvni, a destruktort a keretrendszer szemtgyjt algoritmusa hvja meg. Ha mgis szksgnk lenne olyan hvsra, amit kzvetlenl is vgre tudunk hajtani, akkor a Dispose fggvny definilsra van szksgnk. Ekkor jellemzen egy logikai vltoz mutatja, hogy az aktulis objektum l, s mg nem hvtk meg a Dispose metdust. Ezen fggvny klasszikus hasznlata a kvetkez:
bool disposed=false; protected void Dispose( bool disposing ) { if( !disposed ) { if (disposing) { // ide jn az erforrs felszabadt kd } this.disposed=true; // nem kell tbb hvs // ha van sosztly, akkor annak dispose hvsa base.Dispose( disposing ); // erre az objektumra mr nem kell finalize fggvnyt //hvni a keretrendszernek GC.SupressFinalize(this); } }

Itt kell szt ejtennk arrl, hogy a nyelv using utastsnak segtsgvel (lsd a Nyelvi utastsok fejezetet) tmr kd rhat. A destrukci folyamata lnyegben a hatkony erforrs-gazdlkodshoz nyjt segtsget. Ennek egyik leglnyegesebb eleme a memriagazdlkods. Br a mai szmtgpek vilgban a memria nagysga nem a kritikus paramterek kztt szerepel, azrt elfordulhat, a fejlesztsek sorn az alkalmazsunk memriahinyban szenved. Ekkor segtsget adhatunk a memria-visszanyer szemtgyjtsi algoritmusnak ahhoz, mely terleteket lehet visszaadni a

VII. Osztlyok rendszer rszre. A kritikus esetben visszaadhat objektumok hivatkozsait gyenge referencinak (weak reference) nevezzk. Ezeket az objektumokat erforrs hinyban a keretrendszer felszabadtja. Ilyen objektumot a WeakReference tpus segtsgvel tudunk ltrehozni. Plda:

Object obj = new Object(); // ers referencia WeakReference wr = new WeakReference(obj); obj = null; // az eredeti ers objektumot megszntetjk // obj = (Object) wr.Target; if (obj != null) {//garbage collection mg nem volt // } else {// objektum trlve // }

A destruktorral kapcsolatban zrskppen a kvetkez (a rendszer szolgltatsaibl ered) tancsokat adhatjuk: Az esetek nagy rszben, ellenttben a C++ nyelvbeli hasznlattal, nincs szksg destruktor definilsra. Ha mgis valamilyen rendszererforrst kzi kddal kell lezrni, akkor definiljunk destruktort. Ennek htrnya az, hogy vgrehajtsa nem determinisztikus. Ha programkdbl kell destruktor jelleg hvst kezdemnyezni, a C++ beli delete hvshoz hasonlan, akkor a Dispose fggvny definilsval, majd annak hvsval lhetnk. A feladataink sorn gyakorta elfordul, hogy egy verem-adatszerkezetet kell ltrehoznunk. Definiljuk most a veremosztlyt gy, hogy a rendszerknyvtr Object tpust tudjuk benne trolni. Ennl a feladatnl is, mint ltalban az igaz, hogy nincs szksgnk destruktor definilsra. Plda:
using System; class verem { Object[] x; int mut; public verem(int db) { x=new object[db]; mut=0; }

// elemek trolsi helye // veremmutat // konstruktor // helyet foglalunk a vektornak // az els szabad helyre mutat

VII. Osztlyok
// NEM DEFINILUNK DESTRUKTORT // MERT AZ AUTOMATIKUS SZEMTGYJTSI // ALGORITMUS FELSZABADTJA A MEMRIT public void push(Object i) { if (mut<x.Length) { x[mut++]=i; } // beillesztettk az elemet } public Object pop() { if (mut>0) return x[--mut]; // ha van elem, akkor visszaadjuk a tetejrl else return null; } } class program { public static void Main() { verem v=new verem(6); v.push(5); v.push("alma"); Console.WriteLine(v.pop());// alma kivtele a verembl // az 5 mg bent marad } }

A kpernyn futsi erdemnyknt az alma szt ltjuk. Egy osztly termszetes mdon nemcsak egyszer adatmezket tartalmazhat, hanem osztlymezket is. A tagosztlyok inicializlsa az osztly definciban vagy a konstruktor fggvnyben explicit kijellhet. Az explicit kijellstl fggetlenl egy objektum inicializlsakor az objektum konstruktornak vgrehajtsa eltt, a tagosztlykonstruktorok is meghvsra kerlnek a deklarci sorrendjben.

VII.3. Konstans, csak olvashat mezk


Az adatmezk hozzfrhetsge az egyik legfontosabb krds a tpusaink tervezsekor. Ahogy korbban mr lttuk, az osztlyon belli lthatsgi hozzfrs lltsval (private, public, ) a megfelel adathozzfrsi ignyek kialakthatk. Termszetes ezek mellett az az igny is, hogy a vltozk mdosthatsgt is szablyozni tudjuk.

VII. Osztlyok

VII.3.1 Konstans mezk


Ahogy korbban emltettk, egy vltoz mdosthatsgt a const kulcsszval is befolysolhatjuk. A konstans mez olyan adatot tartalmaz, amelyik rtke fordtsi idben kerl belltsra. Ez azt jelenti, hogy ilyen mezk inicializl rtkadst ktelez a definci sorn jellni. Plda:
using System; class konstansok { public const double pi=3.14159265; // inicializltuk public const double e=2.71828183; } class konstansapp { public static void Main() { Console.WriteLine(konstansok.pi); } }

Egy konstans mez elrshez nincs szksg arra, hogy a tpusbl egy vltozt ksztsnk, ugyanis a konstans mezk egyben statikus mezk is. Ahogy lthat, a konstans mezt helyben inicializlni kell, ebbl pedig az kvetkezik, hogy minden ksbb definiland osztlyvltozban ugyanezen kezdrtkads hajtdik vgre, teht ez a mez minden vltozban ugyanaz az rtk lehet. Ez pedig a statikus mez tulajdonsga.

VII.3.2. Csak olvashat mezk


Ha egy adatmezt a readonly jelzvel ltunk el, akkor ezt a mezt csak olvashat meznek nevezzk. Ezen rtkeket a program sorn csak olvasni, hasznlni tudjuk. Ezen rtkek belltst egyetlen helyen, a konstruktorban vgezhetjk el. Lthat, hogy a konstans s a csak olvashat mezk kzti leglnyegesebb klnbsg az, hogy mg a konstans mez minden pldnyban ugyanaz, addig a csak olvashat mez konstansknt viselkedik miutn ltrehoztuk a vltozt, de minden vltozban ms s ms rtk lehet! Plda:
using System; class csak_olvashato { public readonly double x; public csak_olvashato(double kezd) { x=kezd; } }

VII. Osztlyok
class olvashatosapp { public static void Main() { csak_olvashato o=new csak_olvashato(5); Console.WriteLine(o.x); // rtke 5 csak_olvashato p=new csak_olvashato(6); Console.WriteLine(p.x); // rtke 6 p.x=8; // fordtsi hiba, x csak olvashat!!!! } }

Termszetesen definilhat egy csak olvashat mez statikusknt is, ebben az esetben a mez inicializlst az osztly statikus konstruktorban vgezhetjk el.

VII.4. Tulajdonsg, index fggvny


Egy osztly tervezsekor nagyon fontos szempont az, hogy az osztly adattagjaihoz milyen mdostsi lehetsgeket engedlyezznk, biztostsunk. Hagyomnyos objektumorientlt nyelvekben ehhez semmilyen segtsget nem kaptunk, maradtak az ltalnos fggvnydefinilsi lehetsgeink. Ezeket a fggvnyneveket jellemzen a set illetve a get eltagokkal mdostottk.

VII.4.1. Tulajdonsg, property fggvny


A C# nyelv a tulajdonsg (property) fggvnydefinilsi lehetsgvel knl egyszer s knyelmes adathozzfrsi s mdostsi eszkzt. Ez egy olyan specilis fggvny, amelynek nem jellhetnk paramtereket, mg a zrjeleket sem (), s a fggvny trzsben egy get s set blokkot definilunk. Hasznlata egyszer rtkadsknt jelenik meg. A set blokkban egy value nvvel hivatkozhatunk a belltsi rtkads jobb oldali kifejezs rtkre. Plda:
using System; class Ember { private string nev; private int kor; // a nev adatmez mdostshoz definilt Nev tulajdonsg public string Nev // kis- s nagybet miatt nev!=Nev { get // ez a blokk hajtdik vgre akkor, // amikor a tulajdonsg rtket kiolvassuk {

VII. Osztlyok
} set { } return nev;

nev=value;

} class program { public static void Main() { Ember e=new Ember("Zoli", 16); //a Nev tulajdonsg hvsa Console.WriteLine(e.Nev); // a Nev property get blokk hvsa e.Nev="Pali"; // a Nev property set blokkjnak hv// sa a value vltozba kerl a "Pali" } }

} public Ember(string n, int k) { nev=n; kor=k; }

Ha a tulajdonsg fggvnynek csak get blokkja van, akkor azt csak olvashat tulajdonsgnak (readonly) nevezzk. Ha a tulajdonsg fggvnynek csak set blokkja van, akkor azt csak rhat tulajdonsgnak (writeonly) nevezzk.

VII.4.2. Index fggvny (indexer)


Az indexer fggvny definilsa valjban a vektorhasznlat s a tulajdonsg fggvny kombincija. Gyakran elfordul, hogy egy osztlynak olyan adathoz szeretnnk hozzfrni, aminl egy indexrtk segtsgvel tudjuk megmondani, hogy melyik is a keresett rtk. Az indexer fggvny esetben lnyeges klnbsg, hogy van egy index paramter, amit szgletes zrjelek kztt kell jellni, s nincs neve, pontosabban a this kulcssz a neve, ugyanis az aktulis tpust, mint vektort indexeli. Mivel az indexer az aktulis tpust, a ltez pldnyt indexeli, ezrt az indexer fggvny nem lehet statikus. Lssuk az albbi pldt, ami a jellemz hasznlatot mutatja. Plda:
class valami { int [] v=new int[10];

VII. Osztlyok
public int this[int i] { get { return v[i]; } set { v[i]=value; } }

// mint a property value rtke

} class program { static void Main() { valami a=new valami(); a[2]=5; // az indexer set blokk hvsa Console.WriteLine(a[2]); // 5, indexer get hvsa } }

Az indexer esetben is, hasonlan a tulajdonsgdefinc hasznlathoz, nem felttlenl kell mindkt (get, set) gat definilni. Ha csak a get blokk definilt, akkor csak olvashat, ha csak a set blokk definilt, akkor csak rhat indexer fggvnyrl beszlnk. Az indexerhasznlat ksrtetiesen hasonlt a vektorhasznlathoz, de van nhny olyan klnbsg, amit rdemes megemlteni. Az indexer fggvny, egy fggvnynek pedig nem csak egsz (index) paramtere lehet. Plda:
public int this[string a, int b] { get { return x; } set { x=value; } }

az indexer fggvny az elzekbl kvetkezen jradefinilhat (overloaded). A fenti indexer mellett a kvetkez hagyomnyos is megfr:

VII. Osztlyok Plda:


public string this[int x] { get { return s[x]; } set { s[x]=value; } }

az indexert ref s out paramterknt nem hasznlhatjuk.

VII.5. Osztlyok fggvnyparamterknt


Egy fggvny paramterei ms egyszer adattpushoz hasonlan lehetnek osztlytpusok is. Alaprtelmezs szerint az osztlytpus vltoz is rtk szerint addik t. Tekintsk a kvetkez pldaosztlyt. Legyen az osztlynak destruktora is. Plda:
using System; class plda { private int x; public plda (int a) { Console.WriteLine( "Konstruktorhvs!"); x=a; }; public int X { get { return x; } set { x=value; } }

VII. Osztlyok
class program { static int ngyzet(plda a) { a.X=5; return (a.X*a.X); } static void Main() { plda b=new plda(3); Console.WriteLine(ngyzet(b)); } }

A program futtatsa a kvetkezket rja a kpernyre:


Konstruktorhvs! 25

Mikor egy fggvny paramterknt (rtk szerint) egy osztlyt kap, akkor a fggvnyparamter egy rtkreferencit kap, s nem egy msolata kszl el az eredeti osztlyvltoznak. Teljesen hasonl akkor a helyzet, mikor egy fggvny osztlytpust ad visszatrsi rtkknt.

VII.6. Opertorok jradefinilsa


A mr korbban trgyalt opertoraink az ismert alaptpusok esetben hasznlhatk. Osztlyok (j tpusok) megjelensekor az rtkads opertora automatikusan hasznlhat, mert a nyelv ltrehoz egy szmra alaprtelmezett rtkadst az j osztlyra is. Ezen rtkads opertort fellbrlni, azaz egy jat definilni nem lehet a C# nyelvben (ellenttben pl. a C++ nyelvvel). Hasonlan nem lehet az index opertort [] sem jradefinilni, br az indexer definilsi lehetsg lnyegben ezzel egyenrtk. A legtbb opertor jradefinilhat, melyek egy- vagy ktoperandusak. Az albbi opertorok definilhatk jra: Egyoperandus opertorok: +, -, !, ~, ++, --, true, false Ktoperandus opertorok: +, -, *, /, %, &, |, ^, <<, >>, <=, >=, ==, !=, <, > A fenti hagyomnyosnak mondhat opertorkszlet mellett mg tpuskonverzis opertor fggvny is definilhat.

VII. Osztlyok Az opertor fggvny defincijnak formja: static visszatrsi_rtk operator?(argumentum) { // fggvnytrzs } Az operator kulcssz utni ? jel helyre az jradefinilni kvnt opertor neve kerl. Teht ha pldul az sszeads (+) opertort szeretnnk fellbrlni, akkor a ? helyre a + jel kerl. Az irodalomban az opertor jradefinilst gyakran opertor overloadingnak hvjk. Az opertorok precedencija jradefinils esetn nem vltozik, s az operandusok szmt nem tudjuk megvltoztatni, azaz pldul nem tudunk olyan / (oszts) opertort definilni, amelynek csak egy operandusa van. Az opertor fggvnyek rkldnek, br a szrmaztatott osztlyban az sosztly opertor fggvnyei igny szerint jradefinilhatak. Az opertor fggvny argumentumval kapcsolatosan elmondhatjuk, hogy egyoperandus opertor esetn egy paramtere van, mg ktoperandus opertor esetn kt paramtere van a fggvnynek. Meg kell emlteni, hogy a C++ nyelvhez kpest nem olyan ltalnos az opertor jradefinils lehetsge, de az is igaz, hogy sok, ma npszer programozsi nyelv (Java, Delphi, ) mg ennyit se nyjt. Tekintsk els pldaknt a komplex szmokat megvalst osztlyt, amelyben az sszeads opertort szeretnnk definilni oly mdon, hogy egy komplex szmhoz hozz tudjunk adni egy egsz szmot. Az egsz szmot a komplex szm vals rszhez adjuk hozz, a kpzetes rsz vltozatlan marad. Plda:
using System; class komplex { private float re,im; public komplex(float x,float y) // konstruktor { re=x; im=y; } float Re { get { return re; }

VII. Osztlyok
set { } float Im { get { } set { } } public static komplex operator+(komplex k,int a) { komplex y=new komplex(0,0); y.Re=a+k.Re; y.Im=k.Im; return y; } override public string ToString() { string s="A keresett szm:"+re+":"+im; return s; } } class program { public static void Main() { komplex k=new komplex(3,2); Console.WriteLine("Komplex szm plda."); Console.WriteLine("sszeads eredmnye: {0}",k+4); } } return im; } re=value;

im=value;

Az eredmny a kvetkez lesz:


Komplex szm plda. sszeads eredmnye: A keresett szm:7:2

VII. Osztlyok A k+4 sszeads gy rtelmezend, hogy a k objektum + fggvnyt hvtuk meg a k komplex szm s a 4 egsz szm paramterrel, azaz k.+(k,4) fggvnyhvs trtnt. Abban az esetben, ha a komplex + komplex tpus sszeadst szeretnnk definilni, akkor egy jabb opertor fggvnnyel kell a komplex osztlyt bvteni. Ez a fggvny a kvetkezkppen nzhet ki:
public static komplex operator+(komplex a, komplex b) { komplex temp=new komplex(0,0); temp.re= b.re+a.re; temp.im= b.im+a.im; return temp; }

Ahhoz, hogy az sszeads opertort a korbban (az egyszer tpusoknl) megszokott mdon tudjuk itt is hasznlni, mr csak az kell, hogy az egsz + komplex tpus sszeadst is el tudjuk vgezni. (Az sszeads kommutatv!) Erre az eddigi kt sszeads opertor nem ad lehetsget, hiszen ebben az esetben, a bal oldali operandus mindig maga az aktulis osztly. A mostani esetben viszont a bal oldali operandus egy egsz szm. Ekkor a legkzenfekvbb lehetsg az, hogy az egsz + komplex opertorfggvnyt is definiljuk. Figyelembe vve a Visual Studio szvegszerkesztjnek szolgltatsait, ez gyorsan megy, gy elksztjk ezt a vltozatot is:
public static komplex operator+(int a, komplex k) { komplex y=new komplex(0,0); y.Re=a+k.Re; y.Im=k.Im; return y; }

Ekkor a Console.WriteLine("sszeads eredmnye: {0}",4+k); utasts nem okoz fordtsi hibt. Erre a problmra mg egy megoldst adhatunk. Ez pedig a konverzis opertor definilsnak lehetsge. Ugyanis, ha definilunk olyan konverzis opertort, amely a 4 egsz szmot komplex tpusra konvertlja, akkor kt komplex szm sszeadsra vezettk vissza ezt az sszeadst. A konverzis opertoroknak kszthetnk implicit vagy explicit vltozatt is. Implicitnek nevezzk azt a konverzis opertorhvst, mikor nem jelljk a forrsszvegben a konverzi mvelett, explicitnek pedig azt, amikor jelljk.

VII. Osztlyok Konverzis opertornl az opertor jel helyett azt a tpust rjuk le, amire konvertlunk, mg paramterl azt a tpust adjuk meg, amirl konvertlni akarunk. Visszatrve a fenti komplex szm krdsre, az egsz + komplex opertor helyett az albbi opertort is definilhattuk volna:
public static implicit operator komplex(int a) { komplex y=new komplex(0,0); y.Re=a; return y; }

Ha az opertor sz el az implicit kulcsszt rjuk, akkor az implicit opertor fggvnyt definiljuk, teht 4 + komplex jelleg utastsnl a 4 szmot implicit (nem jellve kln) konvertljuk komplex szmm. Elfordulhat, hogy az implicit s az explicit konverzi mst csinl, ekkor, ha akarjuk, az explicit verzit is definilhatjuk.
public static explicit operator komplex(int a) { komplex y=new komplex(0,0); y.Re=a+1; // mst csinl, mint az elz // nem biztos, hogy matematikailag is helyes!!! return y; }

Az explicit verzi meghvsa a kvetkezkppen trtnik:


komplex k=(komplex) 5; Console.WriteLine(k.Re);

// 6

Termszetesen egy komplex szmhoz rtkads tjn rendelhetnk egy vals szmot is, mondjuk oly mdon, hogy a komplex szm vals rszt adja a vals szm, mg a kpzetes rsz legyen 0. Kt egyoperandus opertor, a ++ s a -- esetben, ahogy az opertorok trgyalsnl is lttuk, ltezik az opertorok postfix illetve prefix formj hasznlata is:
komplex k=new komplex(1,2); k++; // postfix ++ ++k; // prefix forma

VII. Osztlyok Ha definilunk ++ opertor fggvnyt, akkor ezen kt opertor esetben mindkt forma hasznlatnl ugyanaz az opertor fggvny kerl meghvsra.
public static komplex operator++(komplex a) { a.Re=a.Re+1; a.Im=a.Im+1; return a; }

Befejezsl a true, false egyoperandus opertor definilsnak lehetsgrl kell rviden szlni. A C++ nyelvvel ellenttben, ahol egy adott tpust logikainak is tekinthetnk (igaz, ha nem 0, hamis, ha 0), a C# nyelvben a mr korbbrl ismert
if (a) utasts;

alak utastsok akkor fordulnak le, ha az a vltoz logikai. A true s false nyelvi kulcsszavak nemcsak logikai konstansok, hanem olyan logikai egyoperandus opertorok, melyeket jra lehet definilni. A true, false opertor logikai. Megkts, hogy mindkt opertort egyszerre kell jradefinilnunk. A jelentse pedig az, hogy az adott tpust mikor tekinthetjk logikai igaznak vagy hamisnak. Definiljuk jra ezeket az opertorokat a mr megismert komplex osztlyunkhoz:
public static bool operator true(komplex x) { return x.Re > 0; } public static bool operator false(komplex x) { return x.Re <= 0; }

Ez a definci ebben az esetben azt jelenti, hogy egy komplex szm akkor tekinthet logikai igaz rtknek, ha a szm vals rsze pozitv. Plda:
komplex k=new komplex(2,0); if (k) Console.WriteLine("Igaz");

Ekkor a kpernyre kerl eredmny az igaz sz lesz!

VII. Osztlyok Vgl azt kell megemlteni, hogy a logikai true, false opertorok mintjra, azokhoz hasonlan csak prban lehet jradefinilni nhny opertort. Ezek az opertorok a kvetkezk: ==, != <, > <=, >= azonossg, klnbzsg megadsa kisebb, nagyobb kisebb vagy egyenl, nagyobb vagy egyenl

VII.7. Interface definilsa


Egy osztly definilsa sorn a legfontosabb feladat az, hogy a ksztend tpus adatait, metdusait megadjuk. Gyakran felmerl az az igny, hogy egy tovbbi fejleszts, ltalnosabb lers rdekben ne egy osztly keretben fogalmazzuk meg a legjellemzbb tulajdonsgokat, hanem kisebb tulajdonsgcsoportok alapjn definiljunk. A keretrendszer viszont csak egy osztlybl enged meg egy j tpust, egy utdosztlyt definilni. Ez viszont ellentmond annak az elvrsnak, hogy minl rszletesebben fogalmazzuk meg a tpusainkat.

VII.7.1. Interface fogalma


A fenti ellentmonds feloldsra alakult ki az a megolds, hogy engedjnk meg olyan tpust, interface-t definilni, ami nem tartalmaz semmilyen konkrtumot, de rendelkezik a kvnt elrsokkal. Az interfacedefinci formja: interface nv { // deklarcis fejlcek } Plda:
interface IAlma { bool nyri(); double termstlag(); }

VII. Osztlyok A fenti pldban definiltuk az Ialma interface-t, ami mg nem jelent kzvetlenl hasznlhat tpust, hanem csak azt rja el, hogy annak a tpusnak, amelyik majd ennek az IAlma tpusnak a tulajdonsgait is magn viseli, ktelezen definilnia kell a nyri(), s a termstlag() fggvnyeket. Teht errl a tpusrl azt tudhatjuk, hogy az interface ltal elrt tulajdonsgokkal biztosan rendelkezni fog. Ezen ktelez tulajdonsgok mellett termszetesen tetszleges egyb jellemzkkel is felruhzhatjuk majd az osztlyunkat. Amikor knyvtri elrsokat, interface-eket implementlunk, akkor ltalban az elnevezsek az I betvel kezddnek, utalva ezzel a nv ltal jelzett tartalomra. Egy interface elrsai kz nem csak fggvnyek, hanem tulajdonsgok s indexer elrs megadsa s esemny megadsa is beletartozhat. Plda:
interface IPozci { int X { get; set; int Y { get; } int Z { set; } int this[int i] { int this[int i] { int this[int i] { }

} // readonly tulajdonsg // csak rhat tulajdonsg get; set;} // read-write indexer get; } // read-only indexer set;} // write-only indexer

VII.7.2. Interface hasznlata


Az IAlma elrsok figyemlembevtele a kvetkezkppen trtnik. Az osztlynv (tpusnv) utn kettspontot kell tenni, majd utna kvetkezik az implementland nv. Plda:
using System; class jonatn: IAlma { private int kor; public jonatn(int k) { kor=k; } public bool nyri() { return false; } public double termstlag() { if ((kor>5) && (kor<30))

VII. Osztlyok
return 230; else return 0; } }

class program { public static void Main() { jonatn j=new jonatn(8); Console.WriteLine(j.termstlag()); // 230 kg az tlagterms } }

VII.7.3. Interface-ek kompozcija


Az interface egysgek tervezsekor lehetsgnk van egy vagy tbb mr meglv interface felhasznlsval ezekbl egy jabbat definilni. Plda:
using System; public interface IAlma { bool nyri(); double termstlag(); } public interface szllthat { bool szllt(); } public interface szllthat_alma:IAlma,szllthat { string csomagols_mdja(); } public class jonatn: szllthat_alma { public bool nyri() { return false; }

VII. Osztlyok
public double termstlag() { return 250; } public string csomagols_mdja() { return "kontner"; } public bool szllt() { return false; } } class program { public static void Main() { jonatn j=new jonatn(); Console.WriteLine(j.termstlag());// 250 kg az tlagterms Console.WriteLine(j.csomagols_mdja()); // kontner } }

A definilt j tpusra vonatkozan hasznlhatjuk mind az is mind az as opertort. Az imnti pldt tekintve rtelmes, s igaz eredmnyt ad az albbi elgazs: Plda:
if (j is IAlma) Console.WriteLine("Ez bizony alma utd.!"); IAlma a=j as IAlma; a.termstlag(); // IAlma tpusra konvertls // fggvnyvgrehajts

VII.8. Osztlyok rkldse


Az rklds az objektumorientlt programozs elsdleges jellemzje. Egy osztlyt szmaztathatunk egy sosztlybl, s ekkor az utdosztly az sosztly tulajdonsgait (fggvnyeit, ) is sajtjnak tudhatja. Az rklt fggvnyek kzl a vltoztatsra szorulkat jradefinilhatjuk. rkls esetn az osztly defincijnak formja a kvetkez: class utdnv: snv { // }

VII. Osztlyok Hasonlan az osztlyok mezhozzfrsi rendszerhez, tbb nyelvben is lehetsg van arra, hogy rkls esetn az utdosztly az sosztly egyes mezit tbbfle (private, protected , public) mdon rklheti. A C# nyelvben a .NET Frameworknek (Common Type System) ksznheten erre nincs md. Minden mez automatikusan, mintha publikus rkls lenne, megtartja sosztlybeli jelentst. Ekkor az sosztly publikus mezi az utdosztlyban is publikus mezk, s a protected mezk az utdosztlyban is protected mezk lesznek. Egy stpus referencia brmely utdtpusra hivatkozhat. Az sosztly privt mezi az utdosztlyban is privt mezk maradnak az sosztlyra nzve is, gy az sosztly privt mezi kzvetlenl az utdosztlybl sem rhetk el. Az elrsk pldul publikus, n. kzvett fggvny segtsgvel valsthat meg. Az elrsi mdok gyakorlati jelentst nzzk meg egy sematikus pldn keresztl:
class s { private int i; protected int j; public int k; public void f(int j) { i=j; }; } class utd: s { };

// privt mez // protected meztag // publikus mezk

Ekkor az utdosztlynak helybl lesz egy protected mezje, a j egsz vltoz, s lesz kt publikus mezje, a k egsz vltoz s az f fggvny. Osztlyknyvtrak hasznlata mellett (pl. MFC for Windows, Windows NT) gyakran tallkozunk azzal az esettel, mikor a knyvtrosztly protected mezket tartalmaz. Ez azt jelenti, hogy a fggvnyt, mezt olyan hasznlatra szntk, hogy csak szrmaztatott osztlybl tudjuk hasznlni. A C# nyelvben nincs lehetsgnk tbbszrs rkls segtsgvel egyszerre tbb sosztlybl egy utdosztlyt szrmaztatni. Helyette viszont tetszleges szm interface-t implementlhat minden osztly.
class utd: s, interface1, { }; //

VII. Osztlyok Konstruktorok s destruktorok hasznlata rkls esetn is megengedett. Egy tpus definilsakor a konstruktor fggvny kerl meghvsra, s ekkor elszr az sosztly konstruktora, majd utna az utdosztly konstruktora kerl meghvsra, mg destruktor esetn fordtva, elszr az utdosztly majd utna az sosztly destruktort hvja a rendszer. Termszetesen a destruktor hvsra az igaz, hogy a keretrendszer hvja meg valamikor azutn, hogy az objektumok lettartama megsznik. Paramteres konstruktorok esetn az utdkonstruktor alakja:
utd(paramterek): base(paramterek) { } //

Tbbszrs rkls esetn elszr az skonstruktorok kerlnek a definci sorrendjben vgrehajtsra, majd az utdbeli tagosztlyok konstruktorai s legvgl az utdkonstruktor kvetkezik. A destruktorok hvsnak sorrendje a konstruktorsorrendhez kpest fordtott. Ha nincs az utdban direkt shvs, akkor a rendszer a paramter nlkli skonstruktort hvja meg. Ezek utn nzzk a fentieket egy pldn keresztl. Plda:
using System; class a { public a() { Console.WriteLine( "A konstruktor";} ~a() { Console.WriteLine("A destruktor";} } class b: a { public b() { Console.WriteLine("B konstruktor";} ~b() { Console.WriteLine("B destruktor";} } class program { public static void Main() { b x=new b(); // b tpus objektum keletkezik, majd 'kimlik' // Elszr az a majd utna a b konstruktort hvja meg // a fordt

VII. Osztlyok
// Kimlskor fordtva, elszr a b majd az a // destruktora kerl meghvsra } }

VII.9. Vgleges s absztrakt osztlyok


A tpusdefincis lpseink sorn elfordulhat, hogy olyan osztlyt definilunk, amelyikre azt szeretnnk kiktni, hogy az adott tpusbl, mint sbl ne tudjunk egy msik tpust, utdot szrmaztatni. Ahhoz, hogy egy adott osztlyt vglegesnek definiljunk, a sealed jelzvel kell elltni. Plda:
sealed class vgleges { public vgleges() { Console.WriteLine( "A konstruktor" ); } class utd:vgleges // fordtsi hiba { }

Ha protected mezt definilunk egy sealed osztlyban, akkor a fordt figyelmeztet zenetet ad, mivel nincs sok rtelme az utdosztlyban lthat mezt definilni. Interface definils esetben csak elrsokat fggvny, tulajdonsg formban fogalmazhatunk meg az implementl osztly szmra. Gyakran elfordul, hogy olyan tpust szeretnnk ltrehozni, mikor a definilt tpusbl mg nem tudunk pldnyt kszteni, de nemcsak elrsokat, hanem adatmezket, implementlt fggvnyeket is tartalmaz. Ez a lehetsg az abstract osztly definilsval valsthat meg. Ehhez az abstract kulcsszt kell hasznlnunk az osztly neve eltt. Egy absztrakt osztly egy vagy tbb absztrakt fggvnymezt tartalmazhat (nem ktelez!!!). Ilyen fggvnynek nincs trzse, mint az interface fggvnyeknek. Egy absztrakt osztly utdosztlyban az absztrakt fggvnyt ktelez implementlni. Az utdosztlyban ekkor az override kulcsszt kell a fggvny fejlcbe rni.

VII. Osztlyok 1. plda:


abstract class os { private int e; public os() { e=5; } // // } os x= new os(); // //

az osztlynak nincs absztrakt mezje, de ettl az osztly mg lehet absztrakt hiba, mert absztrakt osztlybl nem kszthetnk vltozt

2. plda:
using System; abstract class os { private int e; public os(int i) { e=i; } public abstract int szamol(); public int E { get { return e; } } } class szamolo:os { public szamolo():base(3) { } public override int szamol() { return base.E*base.E; } }

VII. Osztlyok
class program { public static void Main() { szamolo f=new szamolo(); Console.WriteLine(f.szamol()); // eredmny: 9 } }

VII.10. Virtulis tagfggvnyek, fggvnyelfeds


A programkszts sorn, ahogy lttuk, az egyik hatkony fejlesztsi eszkz az osztlyok rklsi lehetsgnek kihasznlsa. Ekkor a fggvnypolimorfizmus alapjn termszetesen lehetsgnk van ugyanazon nvvel mind az sosztlyban, mind az utdosztlyban fggvnyt kszteni. Ha ezen fggvnyeknek klnbzk a paramterei, akkor gyakorlatilag nincs is krds, hiszen fggvnyhvskor a paramterekbl teljesen egyrtelm, hogy melyik kerl meghvsra. Nem ilyen egyrtelm a helyzet, amikor a paramterek is azonosak.

VII.10.1. Virtulis fggvnyek


A helyzet illusztrlsra nzzk a kvetkez pldt. Definiltuk a pont sosztlyt, majd ebbl szrmaztattuk a kor osztlyunkat. Mindkt osztlyban definiltunk egy kiir fggvnyt, amely paramter nlkli s az osztly adattagjait rja ki. Plda:
using System; class pont { private int x,y; public pont() { x=2;y=1; } public void kiir() { Console.WriteLine(x); Console.WriteLine(y); } }

VII. Osztlyok
class kor:pont { private int r; public kor() { r=5; } public void kiir() { Console.WriteLine(r); } } class program { public static void Main() { kor k=new kor(); pont p=new pont(); p.kiir(); //2,1 k.kiir(); //5 } }

A program futsnak eredmnyeknt elszr a p pont adatai (2,1), majd a kor adata (5) kerl kirsra. Bvtsk a programunkat az albbi kt sorral:
public static void Main() { kor k=new kor(); pont p=new pont(); p.kiir(); k.kiir(); p=k; //Egy stpus egy utdra hivatkozik p.kiir(); //Mit r ki? }

A p=k rtkads helyes, hiszen p (pont tpus) tpusa a k tpusnak (kor) az se. Azt is szoktuk mondani, hogy egy stpus referencia tetszleges utdtpusra hivatkozhat. Ekkor a msodik p.kiir() utasts is, a p=k rtkadstl fggetlenl a 2,1 rtkeket rja ki! Mirt? Mert az osztlyreferencik alaprtelmezsben statikus hivatkozsokat tartalmaznak a sajt fggvnyeikre. Mivel a pontban van kiir, ezrt attl fggetlenl, hogy idkzben a program sorn (futs kzbeni dinamikus mdosts utn) a p mr egy kr objektumot azonost, azaz a kr kiir fggvnyt kellene meghvni, mg mindig a fixen, fordtsi idben hozzkapcsolt pont.kiir fggvnyt hajtja vgre.

VII. Osztlyok Ha azt szeretnnk elrni, hogy mindig a dinamikusan hozztartoz fggvnyt hvja meg, akkor az sosztly fggvnyt virtulisnak (virtual), mg az utdosztly fggvnyt felldefiniltnak (override) kell nevezni, ahogy az albbi plda is mutatja. Plda:
using System; class pont { private int x,y; public pont() { x=2;y=1; } virtual public void kiir() { Console.WriteLine(x); Console.WriteLine(y); } } class kor:pont { private int r; public kor() { r=5; } override public void kiir() { Console.WriteLine(r); } } public class MainClass { public static void Main() { kor k=new kor(); pont p=new pont(); p.kiir(); // pont kiir2,1 k.kiir(); // kor kiir 5 p=k; // a pont a korre hivatkozik p.kiir(); // kor kiir 5 a kor kiir kerl // meghvsra, mert a kiir fggvny virtulis, gy a // kiir hvsakor mindig a vltoz aktulis, s nem // pedig az eredeti tpust kell figyelembe venni. } }

VII. Osztlyok Ez a tulajdonsg az osztlyszerkezet rugalmas bvtst teszi lehetv, mg a programkd bonyolultsga jelentsen cskken. Gyakran elfordul, hogy az sosztlyban nincs szksgnk egy fggvnyre, mg a szrmaztatott osztlyokban mr igen, s szeretnnk, ha virtulisknt tudnnk definilni. Ebben az esetben az sosztlyban egy absztrakt fggvnydefincit kell hasznlnunk, ahogy az albbi pldban olvashat. Plda:
abstract class pont // absztrakt osztly, ebbl nem { // lehet pldnyt kszteni protected int x,y; public pont() { x=20;y=10; } abstract public void rajzol(); public void mozgat(int dx, int dy) { x+=dx; y+=dy; // rajzol hvs rajzol(); } } class kor:pont { private int r; public kor() { r=5; } override public void rajzol() { Console.WriteLine("Megrajzoljuk a krt az {0}, {1} pontba, {2} sugrral.",x,y,r); } } public class MainClass { public static void Main() { // pont p=new pont(); utastshibt eredmnyezne kor k=new kor(); k.mozgat(3,4); } }

VII. Osztlyok

VII.10.2. Fggvnyeltakars, sealed fggvny


Az rkls kapcsn az is elfordulhat, hogy a bzisosztly egy adott fggvnyre egyltaln nincs szksg az utdosztlyban. Az albbi pldban a focicsapat osztlynak van nevkiir fggvnye. Az utd kedvenc_focicsapat osztlynak is van ilyen fggvnye. A new hatsra a kedvenc_focicsapat osztly nevkiir fggvnye eltakarja az sosztly hasonl nev fggvnyt. Plda:
{

class focicsapat
protected string csapat; public focicsapat() { csapat="UTE"; } public void nevkiir() { Console.WriteLine("Kedves csapat a lila-fehr {0}",csapat); }

} class kedvenc_csapat:focicsapat { public kedvenc_csapat() { csapat="Fradi"; } new public void nevkiir() { Console.WriteLine("Kedvenc csapatunk a: {0}",csapat); } } public class MainClass { public static void Main() { kedvenc_csapat cs=new kedvenc_csapat(); cs.nevkiir(); } }

A new utasts hatsra egy rklsi sor j bzisfggvnye lesz az gy definilt nevkiir fggvny. Ennek az ellenkezjre is igny lehet, mikor azt akarjuk elrni, hogy az sosztly fggvnyt semmilyen ms formban ne lehessen megjelenteni. Ekkor a fggvnyt, az osztly mintjra, vglegesteni kell, azaz a sealed jelzvel kell megjellni.

VII. Osztlyok

VII.11. Feladatok
1. Mi a klnbsg egy struktra s egy osztly kztt? 2. Milyen szerepe van a konstruktoroknak, destruktoroknak? Milyen konstruktorok definilhatk? 3. Mi a klnbsg az osztly, az absztrakt osztly is az interface kztt? 4. Definiljon btor osztlyt a jellemz tulajdonsgokkal! (Btor neve, alapanyaga, rendeltetse, ra) A megadott tulajdonsgokhoz ksztse el a kezel fggvnyeket! Ksztsen lapraszerelt nvvel interface-t, amiben az sszeszerelsi utastst rjuk el! Mdostsa az elz btor osztlyt lapraszerelt btorra, amelyik implementlja a lapraszerelt interface-t, biztostva azt, hogy ennek a tpusnak biztosan legyen sszeszerelsi utastsa.

VIII. Kivtelkezels
Egy program, programrsz vagy fggvny vgrehajtsa formlis eredmnyessg tekintetben hrom kategriba sorolhat. A fggvny vagy programrsz vgrahajtsa sorn semmilyen rendellenessg nem lp fel. A fggvny vagy programrsz aktulis hvsa nem teljesti a paramterekre vonatkoz elrsainkat, gy ekkor a sajt hibavdelmnk eredmnyeknti hibval fejezdik be a vgrehajts. A fggvny vagy programrsz vgrehajtsa sorn elre nem lthat hibajelensg lp fel. Ezen harmadik esetben fellp hibajelensgek programban trtn kezelsre nyjt lehetsget a kivtelkezels (Exception handling) megvalstsa. Ha a msodik esetet tekintjk, akkor a sajt hibavdelmnk segtsgvel, mondjuk valamilyen nem hasznlt visszatrsi rtkkel tudjuk a hv fl tudomsra hozni, hogy hiba trtnt. Ez nha komoly problmkat tud okozni, hiszen pldul egy egsz rtkkel visszatr fggvny esetben nha elg krlmnyes olyan egsz rtket tallni, amelyik nem egy lehetsges valdi visszatrsi rtk. gy ebben az esetben is, br a fellp hibajelensg valahogy kezelhet, a kivtelkezels lehetsge nyjt elegns megoldst. A kivtelkezels lehetsge hasonl, mint a fordtsi idben trtn hibakeress, hibavdelem azzal a klnbsggel, hogy mindezt futsi idben lehet biztostani. A C# kivtelkezels a hibakezelst tmogatja. Nem tmogatja az n. aszinkron kivtelek kezelst, mint pldul billentyzet- vagy egyb hardvermegszakts (interrupt) kezelse. Ehhez hasonl lehetsggel mr a BASIC nyelvben is tallkozhattunk (ON ERROR GOTO, ON ERROR GOSUB). Ehhez hasonl forma jelenik meg az Object Pascal nyelvben is (ON DO).

VIII.1. Kivtelkezels hasznlata


A kivtelkezels implementlshoz a kvetkez j nyelvi alapszavak kerlnek felhasznlsra:

118

VIII. Kivtelkezels try catch throw finally mely kritikus programrsz kvetkezik ha problma van, mit kell csinlni kifejezs, kivtelkezels tadsa, kivtel(ek) deklarlsa kritikus blokk vgn biztos vgrehajtdik

A kivtelkezels hasznlata a kvetkez formban adhat meg :


try { // azon utastsok kerlnek ide, melyek // hibt okozhatnak, kivtelkezelst ignyelnek } catch( tpus [nv]) { // Adott kivteltpus esetn a vezrls ide kerl // ha nemcsak a hiba tpusa az rdekes, hanem az // is,hogy pldul egy indexhiba esetn milyen // index okozott galibt, akkor megadhatjuk a // tpus nevt is, amin keresztl a hibt okoz // rtket is ismerhetjk. A nv megadsa opcionlis. } finally { // ide jn az a kd, ami mindenkppen vgrehajtdik }

A try blokkot kvetheti legalbb egy catch blokk, de tbb is kvetkezhet. Ha a try blokk utn nincs elkap (catch) blokk, vagy a meglv catch blokk tpusa nem egyezik a keletkezett kivtellel, akkor a keretrendszer kivtelkezel felgyelete veszi t a vezrlst. A C++ nyelv kivtelkezel lehetsge megengedi azt, hogy a catch blokk tetszleges hibatpust kapjon el, mg a C# ezt kicsit korltozza. A C# nyelvben a catch blokk tpusa csak a keretrendszer ltal biztostott Exception osztlytpus, vagy ennek egy utdtpusa lehet. Termszetesen mi is kszthetnk sajt kivtel tpust, mint az Exception osztly utdosztlyt. Ezek utn nzznk egy egyszer pldt a kivtelkezels gyakorlati hasznlatra. Plda:
int i=4; int j=0; try { i=i/j; }

// 0-val osztunk

VIII. Kivtelkezels
catch (Exception ) { Console.WriteLine("Hiba!"); } finally { Console.WriteLine("Vgl ez a Finally blokk is lefut!"); }

A fenti pldban azt lthatjuk, hogy a rendszerknyvtr hasznlatval, pldul a nullval val oszts prblkozsakor, a keretrendszer hibakivtelt generl, amit elkapunk a catch blokkal, majd a finally blokkot is vgrehajtjuk. A plda egsz szmokhoz kapcsoldik, gy meg kell jegyezni, hogy gyakran hasznljk az egsz aritmetikhoz kapcsoldan a checked s az unchecked mdostkat is. Ezek a jelzk egy blokkra vagy egy fggvnyre vonatkozhatnak. Ha az egsz aritmetikai mvelet nem brzolhat, vagy hibs jelentst tartalmaz, akkor a checked blokkban ez a mvelet nem kerl vgrehajtsra. Plda:
int i=System.Int32.MaxValue; checked { i++; // OverflowException kivtel keletkezik } int j=System.Int32.MaxValue; unchecked { j++; // OverflowException kivtel nem keletkezik } Console.WriteLine(i); // -2147483648 lesz a kirt rtk // ez azonos a Syste.Int32.MinValue // rtkvel

Termszetesen nemcsak a keretrendszer lthatja azt, hogy a normlis utastsvgrehajtst nem tudja folytatni, ezrt kivtelt generl, s ezzel adja t a vezrlst, hanem maga a programoz is. Termszetesen az, hogy a programoz mikor ltja szksgesnek a kivtel generlst, az r van bzva. Plda:
int i=4; try

VIII. Kivtelkezels
if (i>3) throw new Exception(); // ha i>3, kivtel indul } catch (Exception ) // mivel az i rtke 4, itt folytatdik a vgrehajts { Console.WriteLine("Hibt dobtl!"); } finally { Console.WriteLine("Vgl ez is lefut!"); } {

A kivtelkezelsek egymsba gyazhatk. Tbbfle abnormlis jelensg miatt lehet szksg kivtelkezelsre, ekkor az egyik kivtelkezel a msiknak adhatja t a kezels lehetsgt, mondvn ez mr nem az n asztalom, menjen a kvetkez szobba, htha ott a cmzett (throw). Ekkor nincs semmilyen paramtere a throw-nak. Ez az eredeti hibajelensg jragenerlst, tovbbadst jelenti. Plda:
int i=4; try { if (i>3) throw new Exception(); // ha i>3, kivtel indul } catch (Exception ) { Console.WriteLine("Hibt dobtl!"); throw; //a hiba tovbbtsa // ennek hatsra , ha a program nem kezel tovbbi kivtel // elkapst, a .NET keretrendszer lesz a kivtel elkapja. // gy szabvny hibazenetet kapunk, majd a // programunk lell }

VIII.2. Sajt hibatpus definilsa


Gyakori megolds, hogy az rklds lehetsgt hasznljuk ki az egyes hibk sztvlasztsra, sajt hibatpust. Pldul ksztnk egy Hiba osztlyt, majd ebbl szrmaztatjuk az Indexhiba osztlyt. Ekkor termszetesen egy hibakezel lekezeli az Indexhibt is, de ha a kezel formlis paramterezse rtk szerinti,

VIII. Kivtelkezels akkor az Indexhibra jellemz plusz informcik nem lesznek elrhetk! Mivel egy stpus egyben dinamikus utdtpusknt is megjelenhet, ezrt a hibakezel blokkokat az rkls fordtott sorrendjben kell definilni. Plda:
using System; public class Hiba:Exception { public Hiba(): base() { } public Hiba(string s): base(s) { } } public class IndexHiba:Hiba { public IndexHiba(): base() { } public IndexHiba(string s): base(s) { } } int i=4; int j=0; try { if (i>3) throw new Hiba("Nagy a szm!"); } catch (IndexHiba h ) { Console.WriteLine(h); } catch (Hiba h ) // csak ez a blokk hajtdik vgre { Console.WriteLine(h); } catch (Exception ) { Console.WriteLine("Hiba trtnt, nem tudom milyen!"); } finally // s termszetesen a finally is { Console.WriteLine("Finally blokk!"); }

VIII. Kivtelkezels Ahogy korbban lttuk, minden objektum a keretrendszer Object utdjnak tekinthet, ennek a tpusnak pedig a ToString fggvny a rsze, gy egy tetszleges objektum kirsa nem jelent mst, mint ezen ToString fggvny meghvst. A fenti plda gy meghvja az Exception osztly ToString fggvnyt, ami szvegparamter mellett kirja mg az osztly nevt s a hiba helyt is. Befejezsl nzzk meg a korbban ltott verem plda megvalstst kivtelkezelssel kiegsztve. Plda:
using System; class verem { Object[] x; int mut; public verem(int db) { x=new object[db]; mut=0;

// elemek trolsi helye // veremmutat // konstruktor // helyet foglalunk a vektornak // az els szabad helyre mutat

} // NEM DEFINILUNK DESTRUKTORT, // MERT AZ AUTOMATIKUS SZEMTGYJTSI // ALGORITMUS FELSZABADTJA A MEMRIT public void push(Object i) { if (mut<x.Length) { x[mut++]=i; // beillesztettk az elemet } else throw new VeremTele("Ez bizony tele van!"); } public Object pop() { if (mut>0) return x[--mut]; // ha van elem, akkor visszaadjuk a tetejrl else throw new VeremUres("res a verem bartom!"); } } public class VeremTele:Exception { public VeremTele(): base("Tele a verem!") { }

VIII. Kivtelkezels
public VeremTele(string s): base(s) { }

} public class VeremUres:Exception { public VeremUres(): base("res a verem!") { } public VeremUres(string s): base(s) { } } class program { public static void Main() { verem v=new verem(6); try { Console.WriteLine(v.pop()); // mivel a verem res, kivtelt fog dobni } catch (VeremUres ve) // amit itt elkapunk { Console.WriteLine(ve); } v.push(5); v.push("alma"); Console.WriteLine(v.pop()); } }

A program futsa az albbi eredmnyt adja:

11. bra

VIII. Kivtelkezels

VIII.3. Feladatok
1. Mikor is hogyan hasznljuk a kivtelkezelseket? 2. Mit jelent a checked, unchecked kulcssz, hogyan tudjuk hasznlni? 3. Hogyan tudunk sajt kivtelt (tpust) definilni? 4. Olvassa be a msodfok egyenlet paramtereit. Szmolja ki a gykket, ha a diszkriminns negatv szm, hasznlja a rendszerknyvtr kivtelkezelsi lehetsgt! 5. Ksztsen Diszkriminns_negatv kivtelt. Oldja meg az elz feladatot ennek segtsgvel!

IX. Input-Output
A be- s kiviteli szolgltatsok nem rszei a nyelvnek. A programok a szabvnyos knyvtrban lv fggvnyek segtsgvel tartjk a krnyezetkkel a kapcsolatot. Ez a fajta kapcsolattarts nem csak a C# nyelvben rt programok sajtossga. A C++-bl szrmaztathat nyelvek hasonlan hasznljk az inputoutput mveleteket, mert gy azok egyszerbben s rugalmasabban kezelhetk.

IX.1. Standard input-output


Minden klasszikus konzolprogram vgrehajtsa esetn automatikusan hasznlhatjuk a System nvtr Console osztlyt, amely a beolvass (standard input, billentyzet), kirs (standard output, kperny) s hibarsi (standard error, kperny) mveleteket nyjtja. Ezek a Console osztly In, Out s Error tulajdonsgaiban vannak hozzrendelve a be- s kiviteli eszkzeinkhez. Az In egy TextReader, mg az Out s az Error TextWriter tpus lesz. (A TextReader, TextWriter a karakteres adatfolyam osztlyai.) Termszetesen lehetsgnk van ezen tulajdonsgok jradefinilsval az alaprtelmezs megvltoztatsra is. Mieltt rviden ttekintjk a legfontosabb lehetsgeket, meg kell jegyezni, hogy Windows alkalmazs ksztsekor ezek a fggvnyek nem hasznlhatk. A grafikus fellet eszkzket a knyv msodik rszben nzzk t. A Console osztly vgleges, nem lehet belle j tpust szrmaztatni. Kirs:
Write(); // a paramtereket kirja WriteLine(); // kirs, majd soremels

Mindkt utasts jradefinilt formj, teht lteznek a Write(int), Write(double) stb. knyvtri utastsok. A kir utastsoknak ltezik egy msik vltozata is:
Write( string, adat, ); WriteLine( string, adat, );

Ez a vltozat a C vilgbl ismert megoldst valstja meg (printf). Az els paramter, mint eredmnyszveg, kapcsos zrjelek { } kztt a msodik stb. paramterek behelyettestst vgzi. A kapcsos zrjelek kztt a szvegek formzsi lehetsgeit hasznlhatjuk. Ezen formzsrt felels karaktersorozat hrom rszbl llhat, ahol a formzs alakja a kvetkez: {sorszm[, szlessg ][:kijelzsi_forma]}

126

IX. Input-Output Az els rsz 0-tl kezdden egy sorszm, azt mondja meg, hogy a szveg utni kirand adatok kzl hnyadikat kell behelyettesteni. Ha van msodik rsz, akkor az vesszvel elvlasztva kvetkezik, s a teljes adatszlessget hatrozza meg. Ha a szlessg pozitv, akkor az jobbra, ha negatv, akkor balra igaztst jelent az adott szlessgen bell. A hinyz karaktereket n. white space (helykz) karakterekkel tlti fel. Ha van harmadik rsz, akkor az a kettspont utn kvetkezik, s meghatrozza az adat tpust, kijelzsi formjt. Az adattpus jelzsre az albbi karakterek hasznltak: c e x pnznembeli (currency) kijelzs tudomnyos, tzes alap hatvnykijelzs hexadecimlis formtum

Ezek mellett a 0 s a # helyirtk karakterek hasznlhatak. A 0 biztosan megjelentend helyirtket, mg a # opcionlisan ha van oda rtk, megjelentend karaktert jelent. Plda:
int i=5; Console.WriteLine("Az {0}. mvelet eredmnye: {1}",i,4*i); Console.WriteLine(" A szm: {0:c}",25); // pnznem : 25,00 Ft. Console.WriteLine("A kapott sszeg: {0,10:c}",25); // 10 karakter szles pnznem formj kijelzs jobbra igaztva Console.WriteLine(" A szm: {0: 0.###e+0}",25); // 2.5E+1 Console.WriteLine("A kapott szm: {0,10:00.#0}",25.1); // 10 szles jobbra igaztott 25.10 lesz a kijelzs Console.WriteLine("A kapott szm: {0,10:x}",25); // 10 szles jobbra igaztott hexa alak (19) kijelzs

A System.String osztly Format fggvnye az imnti forma alapjn tud egy eredmnyszveget kszteni (formzni). Beolvass: int Read(); // egy karaktert olvas be Ha nem sikerl az olvass, akkor 1 az eredmny. Ha egyb hiba jelentkezik, akkor IOException kivtelt dob a Read utasts. Plda:
char c=(char)Console.Read(); string ReadLine();// egy egsz sort olvas

IX. Input-Output Plda:


string s=Console.ReadLine();

Ha nem sikerl az olvass, akkor OutOfMemoryException vagy IOException kivtelt dob a ReadLine utasts. A knyvtr nem tartalmaz tpusos beolvassi lehetsget, viszont rendelkezsre llnak a Convert osztly konvertlsi mezfggvnyei. Plda:
string s=Console.ReadLine(); int j=Convert.ToInt32(s); // egsz konvertls int i=Convert.ToInt32(s,16); //konvertls 16-os szmrendszerbl Console.WriteLine(i);

Ha nem sikerl a konvertls, akkor a konvertlsi hibnak megfelel kivtelt dob a Convert osztlyfggvnye. Ezt a kivtelkezelst hasznlva szmok beolvassra, az albbi pldt, mint egy lehetsges megvalstst tekinthetjk. Nzzk meg a Struktrk fejezet vgn hasznlt pldnkat azzal a kiegsztssel, hogy a kor mez olvasst a konverzi kivtelfigyelsvel egsztjk ki. Plda:
using System; struct struktra_plda { public int kor; public string nv; } class strukra_hasznl { public static void Main() { // struktra_plda vektor struktra_plda [] spv=new struktra_plda[5]; int i=0; // beolvass while(i<5) { spv[i]=new struktra_plda(); Console.WriteLine("Krem az {0}. elem nevt!",i); string n=Console.ReadLine(); spv[i].nv=n; Console.WriteLine("Krem az {0}. elem kort!",i);

IX. Input-Output
while(true) { try { n=Console.ReadLine(); spv[i].kor=Convert.ToInt32(n); } catch(Exception e) { Console.WriteLine("Te kis csibsz, a kor az szm!"); Console.WriteLine("Azt add meg mg egyszer! "); continue; } break; } i++; } // kirs for(i=0;i<5;i++) { Console.WriteLine(spv[i].nv); Console.WriteLine(spv[i].kor); } } }

IX.2. Fjl input output


A fjl input-output szolgltatsokat a System.IO nvtr osztlyai nyjtjk. Ktfle tpust klnbztethetjk meg a fjlok rsnak, olvassnak, ezek a binris, illetve a szveges fjlmveletek. A knyvtri osztlyok jellemz mveletei, tulajdonsgai: Az osztlyok a System.IO.Stream-bl szrmaznak Jellemz utastsok: read (olvass) write (rs) seek (pozci llts). Flush, a bels puffereket rti Close , zrs

IX. Input-Output

IX.2.1. Binris fjl input-output


A binris mveletek kt alaposztlya: BinaryReader olvassra, BinaryWriter rsra. Mindkt osztly konstruktora ha nem akarunk egy ltalnos, semmihez nem kttt objektumot kapni, egy Stream utdot, jellemzen FileStream tpust vr paramterl. A FileStream osztly teremti meg a program objektuma s egy fjl kztt a kapcsolatot. Egy FileStream objektum ltrehozsnl leggyakrabban ngy paramtert szoktak megadni (a fjl nevt s a mdot ktelez): a fjl nevt fjlmd paramtert: FileMode.Open (ltez fjl), FileMode.Append (ltez vgre), FileMode.Create (j fjl) fjlelrst, FileAccess.Read, FileAccess.ReadWrite, FileAccess.Write. megoszts mdja: FileShare.None, FileShare.Read, FileShare.ReadWrite, FileShare.Write. Termszetesen a FileStream konstruktornak sok vltozata van, ezek rszletezst az online dokumentciban lehet olvasni. Binris llomnyoknl lehetsgnk van mg a fjlmutat lltsra is (Seek), ezzel egy llomny klnbz pozciiba vgezhetnk fjlmveleteket. Egy fjlrendszerbeli llomny elrshez a rendszerknyvtr File s Fileinfo osztlyai is lehetsget nyjtanak. A File osztly fggvnyei statikusak, mg a Fileinfo osztlybl pldnyt kell kszteni. A legfontosabb File statikus fggvnyek: FileStream f=File.Create(fjlnv), FileStream f=File.Open(fjlnv), StreamWriter f=File.CreateText(fjlnv), StreamReader f=File.OpenText(fjlnv), File.Exists(fjlnv) //j fjl ltrehozsa //fjl megnyitsa //fjl ltrehozsa //fjl nyits //ltezik-e az adott llomny

IX. Input-Output Knyvtrakkal kapcsolatosan a Directory osztly statikus fggvnyei llnak rendelkezsre. Ha megnyitottunk egy binris llomnyt, akkor rsra a legfontosabb BinaryWriter fggvnyek a kvetkezk: Write(adat) Flush() Close() Seek(mennyit, honnan) // tbb pldnyban ltezik, brmely // alaptpust kir. // pufferek rtse // fjlzrs // fjlmutat pozicionlsa

A legfontosabb BinaryReader fggvnyek: Read() ReadInt32() Close() // tbb pldnyban ltezik, brmely //alaptpust beolvas. // egsz szm beolvassa // ms alaptpusokra is ltezik // fjlzrs

A fjl olvassi mveletek fjl vge esetn EndOfFileException kivtelt dobnak, gy ha nem tudjuk, mennyi adat van egy llomnyban, akkor ennek megfelelen try blokkban kell az olvasst vgezni! Ezek utn nzznk egy rvid pldt:
using System; using System.IO; class fileteszt { private static string nev = "Test.data"; public static void Main(String[] args) { // j llomny ltrehozsa if (File.Exists(nev)) { Console.WriteLine("{0} mr ltezik!", nev); return; } // FileStream ltrehozsa FileStream fs = new FileStream(nev, FileMode.CreateNew); // a filestream hozzrendelse binris rshoz. BinaryWriter w = new BinaryWriter(fs); // adatkirs.

IX. Input-Output
for (int i = 0; i < 5; i++) { w.Write( i); } w.Close(); fs.Close(); // fjlzrs // Create the reader for data. fs = new FileStream(nev, FileMode.Open, FileAccess.Read); BinaryReader r = new BinaryReader(fs); // olvass. for (int i = 0; i < 5; i++) { Console.WriteLine(r.ReadInt32()); } w.Close(); } }

IX.2.2. Szveges fjl input-output


Szveges fjl input-output mveletek alaposztlyai, ahogy mr korbban is volt rla sz, a TextReader s TextWriter osztlyok. Ezek az osztlyok absztraktak, az ezekbl szrmaz StreamReader s StreamWriter osztlyok jelentik a gyakorlatban a szveges llomnyokkal kapcsolatos lehetsgeket. Ha megnyitottunk egy szveges llomnyt, akkor rsra a legfontosabb StreamWriter fggvnyek a kvetkezk: Write(adat) WriteLine(s) Flush() Close() // tbb pldnyban ltezik, brmely // alaptpust kir. // egy sort r ki // pufferek rtse // fjlzrs

A legfontosabb StreamReader fggvnyek: int Read() ReadLine() Close() Peek() // karaktert beolvas. // egsz sort beolvas // ms alaptpusokra is ltezik // fjlzrs // a kvetkez karaktert kapjuk a fjlbl // de nem mdosul a fjlpozci

IX. Input-Output Plda:


using System; using System.IO; class Test { public static void Main() { StreamWriter sw = new StreamWriter("Teszt.txt"); //kirs. sw.Write("Szia"); sw.WriteLine("EZ A FOLYTATS."); sw.WriteLine("jabb sor."); sw.Close(); // fjlolvass. StreamReader sr = new StreamReader("Teszt.txt"); string sor; // olvass soronknt, amg van adat while ((sor = sr.ReadLine()) != null) { Console.WriteLine(sor); } } }

A .NET keretrendszer knyvtra a binris s a szveges fjlok mellett sok egyb tpus fjl i/o mveleteit is tmogatja, ilyenek pldul az XmlTextReader s az XmlTextWriter, amelyek XML llomnyok kezelst segtik el, vagy a HtmlTextWriter, s a HtmlTextReader, amelyek HTML llomnyok rst, olvasst vgzik. A fjl input-output szolgltatsokra is, mint ltalban minden knyvtri szolgltatsra igaz az, hogy a megfelel megoldsi elkpzels kialaktshoz rdemes az online, MSDN segtsg szolgltatst is ignybe venni.

IX.3. Feladatok
1. Mit jelent a standard input-output lehetsge? 2. Milyen formzsi lehetsgeket ismer? 3. Mi a klnbsg a binris s szveges fjl kztt? 4. rja ki a szmot decimlis, hexadecimlis formban balra, majd jobbra igaztva 20 szlessgben! 5. Trolunk egy nevet s egy szmot, rjuk ki ezeket adatok .bin nvvel binris, majd adatok.txt nvvel szveges formban!

X. Prhuzamos programvgrehajts
A feladatok gyorsabb, hatkonyabb elvgzsnek rdekben az utbbi vekben specilis lehetsgknt jelent meg a prhuzamos programvgrehajts. Gondolhatunk a tbbfeladatos opercis rendszerekre, vagyis arra pldul, hogy mikzben a programunkat fejlesztjk, s valamilyen szvegszerkesztt hasznlunk, a produktvabb munkavgzs rdekben, gondolkodsunkat serkentend, kedvenc zennket hallgathatjuk szmtgpnk segtsgvel. A prhuzamos programvgrehajts programjaink szintjn azt jelenti, hogy az opercis rendszer fel tbb vgrehajtsi feladatot tudunk definilni. Pldul egy adatgyjtsi feladatban az egyik szl az adatok gyjtst vgzi, a msik szl pedig a korbban begyjttt adatokat dolgozza fel. A .NET keretrendszer, ahogy tbb ms fejleszteszkz is, lehetsget ad arra, hogy egy program tbb vgrehajtsi szlat definiljon. Ezekrl a vgrehajtsi szlakrl az irodalomban, online dokumentciban threads, threading nven olvashatunk.

X.1. Szlak definilsa


ltalban elmondhatjuk, hogy a prhuzamos vgrehajts sorn az albbi lpseket kell megtenni (ezek a lpsek nem csak ebben a C# krnyezetben jellemzk): Definilunk egy fggvnyt, aminek nincsenek paramterei s a visszatrsi tpusa void. Ez tbb rendszerben ktelezen run nvre hallgat. Ennek a fggvnynek a segtsgvel egy fggvnytpust, delegltat definilunk. Knyvtri szolgltatsknt a ThreadStart ilyen, hasznlhatjuk ez is, ahogy a kvetkez plda mutatja. Az gy kapott delegltat felhasznlva ksztnk egy Thread objektumot. Meghvjuk az gy kapott objektum Start fggvnyt. A prhuzamos vgrehajts tmogatst biztost knyvtri osztlyok a System.Threading nvtrben tallhatk.

134

X. Prhuzamos programvgrehajts Ezek utn az els pldaprogram a kvetkezkppen nzhet ki: Plda:
using System; using System.Threading; class program { public static void szal() { Console.WriteLine("Ez a szlprogram!"); } public static void Main() { Console.WriteLine("A fprogram itt indul!"); ThreadStart szalmutato=new ThreadStart(program.szal); // ltrehoztuk a fonal fggvnymutatt, ami a // szal() fggvnyre mutat Thread fonal=new Thread(szalmutato); // ltrehoztuk a prhuzamos vgrehajtst vgz objektumot // paramterl kapta azt a delegltat (fggvnyt)amit // majd vgre kell hajtani fonal.Start(); // elindtottuk a fonalat, valjban a szal() fggvnyt // a fonal vgrehajtsa akkor fejezdik be amikor // a szal fggvnyhvs befejezdik Console.WriteLine("Program vge!"); } }

X.2. Szlak vezrlse


Ahogy az elz pldban is lthattuk, egy szl vgrehajtst a Start fggvny hvsval indthatjuk el, s amikor a fggvny vgrehajtsa befejezdik, a szl vgrehajtsa is vget r. Termszetesen a szl vgrehajtsa fggetlen a Main fprogramtl. A termszetes vgrehajts mellett szksg lehet a szl vgrehajtsnak befolysolsra is. Ezek kzl a legfontosabbak a kvetkezk: Sleep (millisec): statikus fggvny, az aktulis szl vgrehajtsa vrakozik a paramterben megadott ideig. Join(): az aktulis szl befejezst vrjuk meg

X. Prhuzamos programvgrehajts Interrupt(): az aktulis szl megszaktsa. A szl objektum interrupt hvsa ThreadInterruptedException esemnyt okoz a szl vgrehajtsban. Abort(): az aktulis szl befejezse, valjban a szlban egy AbortThreadException kivtel dobst okozza, s ezzel befejezdik a szl vgrehajtsa. Ha egy szlat abortltunk, nem tudjuk a Start fggvnnyel jraindtani, a start utasts ThreadStateException kivtelt dob. Ezt a kivtelt akr mi is elkaphatjuk, s ekkor, ha gy ltjuk, hogy a szlat mgsem kell abortlni, akkor a Thread.ResetAbort() fggvnyhvssal hatlyon kvl helyezhetjk az Abort() hvst. IsAlive: tulajdonsg, megmondja, hogy a szl l-e Suspend(): a szl vgrehajtsnak felfggesztse Resume(): a felfggeszts befejezse, a szl tovbbindul

Ezek utn nzzk meg a fenti programunk mdostst, illusztrlva ezen fggvnyek hasznlatt. Plda:
using System; using System.Threading; class program { public static void szal() { Console.WriteLine("Ez a szlprogram!"); Thread.Sleep(1000); // egy msodpercet vrunk Console.WriteLine("Letelt az 1 msodperc a szlban!"); Thread.Sleep(5000); Console.WriteLine("Letelt az 5 msodperc a szlban!"); Console.WriteLine("Szl vg!"); } public static void Main() { Console.WriteLine("A fprogram itt indul!"); ThreadStart szalmutato=new ThreadStart(program.szal); // ltrehoztuk a fonal fggvnymutatt, ami a // szal() fggvnyre mutat Thread fonal=new Thread(szalmutato); // ltrehoztuk a prhuzamos vgrehajtst vgz objektumot // paramterl kapta azt a delegltat (fggvnyt), amit // majd vgre kell hajtani fonal.Start(); // elindtottuk a fonalat, valjban a szal() fggvnyt

X. Prhuzamos programvgrehajts
Thread.Sleep(2000); // vrunk 2 msodpercet Console.WriteLine("Letelt a 2 msodperc a fprogramban, a szlat felfggesztjk!"); fonal.Suspend(); // fonal megll Thread.Sleep(2000); Console.WriteLine("Letelt az jabb 2 msodperc a fprogramban, a szl vgrehajtst folytatjuk!"); fonal.Resume(); // fonal jraindul fonal.Join(); // megvrjuk a fonalbefejezdst Console.WriteLine("Program vge!");

} }

A program futsa az albbi eredmnyt adja:

12. bra

Ha tbb szlat is definilunk, vagy akr csak egyet, mint a fenti pldban, szksgnk lehet a vgrehajtsi szl prioritsnak lltsra. Ezt a szlobjektum Priority tulajdonsg lltsval tudjuk megtenni az albbi utastsok valamelyikvel:.
fonal.Priority=ThreadPriority.Highest fonal.Priority=ThreadPriority.AboveNormal fonal.Priority=ThreadPriority.Normal fonal.Priority=ThreadPriority.BelowNormal fonal.Priority=ThreadPriority.Lowest // // // // // legmagasabb alap fltt alaprtelmezett alap alatt legalacsonyabb

A Thread osztly tovbbi tulajdonsgait az online dokumentciban tallhatjuk meg.

X. Prhuzamos programvgrehajts

X.3. Szlak szinkronizlsa


Amg a szlak vgrehajtsnl adatokkal, egyb fggvnyhvssal kapcsolatos feladataink nincsenek, a szlak egymstl nem zavartatva rendben elvgzik feladataikat. Ez az idelis helyzet viszont ritkn fordul el. Tekintsk azt a pldt, mikor egy osztly az adatments feladatt vgzi. (Ezt a pldnkban egyszeren a kpernyre rssal valstjuk meg.) Definiljunk kt szlat, amelyek termszetesen a programosztly adatmentst hasznljk. Az elz forrskdot kicsit talaktva az albbi programot kapjuk: Plda:
using System; using System.Threading; class adatok { public void mentes(string s) { Console.WriteLine("Adatments elindul!"); for(int i=0;i<50;i++) { Thread.Sleep(1); Console.Write(s); } Console.WriteLine(""); Console.WriteLine("Adatments befejezdtt!"); } } class program { public static adatok a=new adatok(); // adatmentsmez a programban // szl1 definils public static void szal1() { Console.WriteLine("Ez a szl1 program induls!"); // egy msodpercet vrunk Console.WriteLine("Adatments meghvsa szl1-bl!"); a.mentes("+"); Console.WriteLine("Szl1 vge!"); }

X. Prhuzamos programvgrehajts
// szl1 definils public static void szal2() { Console.WriteLine("Ez a szl2 programinduls!"); // egy msodpercet vrunk Console.WriteLine("Adatments meghvsa szal2-bl!"); a.mentes("-"); Console.WriteLine("Szl2 vge!"); } public static void Main() { Console.WriteLine("A fprogram itt indul!"); ThreadStart szalmutato1=new ThreadStart(program.szal1); ThreadStart szalmutato2=new ThreadStart(program.szal2); // ltrehoztuk a fonal fggvnymutatt, ami a // Thread fonal1=new Thread(szalmutato1); Thread fonal2=new Thread(szalmutato2); fonal1.Start(); fonal2.Start(); // // Console.WriteLine("Program vge!"); } }

A programot futtatva az albbi eredmnyt kapjuk:

13. bra

X. Prhuzamos programvgrehajts Ebbl a futsi eredmnybl az ltszik, hogy a fonal1 s a fonal2 mentse, azaz ugyanannak a fggvnynek a vgrehajtsa prhuzamosan trtnik! (Csak azrt kerlt egy kis vrakozs a ciklusba, hogy szemlletesebb legyen a prhuzamos fggvnyfuts, a + s karakterek vltott kirsa.) A + s a karakterek vltakoz kirsa, azaz a kt fonal trzsnek vltakoz vgrehajtsa nem jr klnsebb gonddal. De gondoljunk pldul egy olyan esetre, amikor az adatment fggvny soros portra rja a mentsi adatokat archivlsi cllal, vagy vezrel valamilyen eszkzt. Ekkor lnyeges az adatok sorrendje, s ez a fajta futsi eredmny nem kielgt. Teht alapvet igny a tbbszl vgrehajts esetn, hogy biztostani tudjuk egy fggvny, egy utasts megszaktsmentes (ezt gyakran thread safe lehetsgnek nevezik), n. szinkronizlt vgrehajtst. Ha egy adat mdostst, egy fggvny hvst egy idpontban csak egy vgrehajtsi szlnak szeretnnk engedlyezni, akkor erre tbb lehetsgnk is knlkozik. Csak a leggyakrabban hasznlt lehetsgeket emltjk, hiszen nem tudjuk, s nem is clunk az sszes lehetsg referenciaszer felsorolsa. Automatikus szinkronizcinak nevezi a szakirodalom azt a lehetsget, mikor egy egsz osztlyra belltjuk ezt a szolgltatst. Ehhez kt dolgot kell megtennnk: 1. A Synchronization() attribtummal kell jellni az osztlyt. Az attribtumokkal a kvetkez fejezet foglalkozik, gy most egyszeren fogadjuk el ezt az osztlyra, fggvnyre, vltozra llthat informcit. 2. Az osztlyt a ContextBoundObject osztlybl kell szrmaztatni. Plda:
[Syncronization()] class szinkronosztly: ContextBoundObject { int i=5; // egy idbencsak egy szl fr hozz public void Novel() // ezt a fggvnyt is csak egy szl // tudja egyszerre vgrehajtani { i++; } }

Az automatikusan szinkronizlt osztlyoknl a statikus mezket tbben is elrhetik. Ezt orvosolja a fggvnyek, blokkok szinkronizcija, amit gyakran manulis szinkronizcinak is neveznek.

X. Prhuzamos programvgrehajts Egy fggvny szinkronizlt vgrehajtst a legegyszerbben a MethodImplAttribute attribtum belltsval rhetjk el. Ezt mind pldny, mind pedig statikus fggvnyre alkalmazhatjuk.
[MethodImplAttribute(MethodImplOptions.Syncronized)] public void safe_fv() { }

Egy fggvny szinkronizlt vgrehajtsra knl egy msik megoldst a Monitor osztly enter s exit fggvnye. Amg egy monitor a belpssel vd egy vgrehajtsi blokkot, addig egy msik szl azt nem tudja meghvni. Ekkor a kvetkezkppen mdosul az adatments fggvnye:
public void mentes(string s) { Monitor.Enter(this); Console.WriteLine("Adatments elindul!"); for(int i=0;i<50;i++) { Thread.Sleep(1); Console.Write(s); } Console.WriteLine(""); Console.WriteLine("Adatments befejezdtt!"); Monitor.Exit(this); }

Az eredmnyben azt lthatjuk, hogy az a blokk, amit a Monitor vd, megszakts nlkl fut le.

14. bra

X. Prhuzamos programvgrehajts Hasonl eredmnyt kaphatunk, ha a C# nyelv lock utastsval vdjk a kvnt blokkot. Ha a fenti fggvnyt a lock nyelvi utastssal vdjk, azt a fordt a kvetkez alakra alaktja:
Monitor.Enter(this); try { utastsok; } finally { Monitor.Exit(this); }

A teljessg ignye nlkl a Monitor osztly kt fggvnyrl mg szt kell ejtennk. Az egyik a Wait, ami a nevbl sejtheten lelltja a szl vgrehajtst, s a paramterobjektum zrst befejezi. Monitor.Wait(objektum); A fggvny hasznlathoz a Pulse fggvny is hozztartozik, ami az objektumra vrakoz szlat tovbbengedi. Monitor.Pulse(objektum); Hasonl szolgltatst ad a Windows API mutex (mutual exclusive, klcsns kizrs) lehetsgnek megfelel Mutex osztly. Lnyeges klnbsg a monitorhoz kpest, hogy a kizrlagos vgrehajtshoz megadhatjuk azt is, hogy ez mennyi ideig lljon fenn. (WaitOne fggvny)
class adatok { Mutex m=new Mutex(); public void mentes(string s) { m.WaitOne(); Console.WriteLine("Adatments elindul!"); for(int i=0;i<50;i++) { Thread.Sleep(1); Console.Write(s); } Console.WriteLine(""); Console.WriteLine("Adatments befejezdtt!"); m.Release(); } }

X. Prhuzamos programvgrehajts Mg manulisabb adat vagy utasts szinkronizcit biztost a ReadWriterLock, valamint az Interlocked osztly is. Ezek s a tovbbi szinkronizcis lehetsgek ismertetse tlmutat e knyv keretein. Ha knyvtri szolgltatsokat vesznk ignybe, pldul MSDN Help, az egyes hvsok, osztlyok mellett olvashatjuk, hogy thread safe-e vagy nem a hasznlata, attl fggen, hogy a szinkronizlt hozzfrs biztostott-e vagy sem. A szlakkal kapcsolatban befejezsl meg kell emlteni a [STAThread] illetve az [MTAThread] attribtumot, ami azt mondja meg, hogy Single (egy) vagy Multi (tbb) szlat tartalmaz alkalmazsknt definiljuk a programunkat COM komponensknt val egyttmkdsnl. Alaprtelmezs a [STAThread] hasznlata, ami pldul a Windows alkalmazsok Drag and Drop jellemzk hasznlata esetn kvetelmny is.

X.4. Feladatok
1. Mit rtnk prhuzamos programvgrehajts alatt? 2. Hogyan tudunk szlat definilni? 3. Mit jelent a lock utasts? Milyen knyvtri szolgltats felel meg ennek az utastsnak? 4. Ksztsen programot, amely kt sket ember beszlgetst szimullja! Mindketten egy-egy fjlban troljk a mondkjukat! 5. Hasznljunk szinkronizlst, mdostsuk az elz feladatot gy, hogy a mondatvgeknl lehet a msik szereplnek tvenni a beszd fonalt!

XI. Attribtumok
Kpzeljk el, hogy definiltunk egy j tpust (osztlyt), minden adatnak, fggvnymeznek elksztettk a megfelel kezelst, jelentst, hasznlatt, azaz a tpusunk hasznlatra ksz. Mgis, egyes mezk vagy esetleg az egsz tpus mell bizonyos plusz informcikat szeretnnk hozzrendelni. Pldaknt nzznk kt ilyen, a mindennapi programozsi feladataink sorn is elfordul esetet! Els plda: Egy program ltalban tbb tpussal, adattal dolgozik. Ezek kztt az adatok kztt lehet nhny, amelyek rtkre a program kvetkez indulsakor is szksgnk lehet. Ezeket a program vgn elmentjk a registry-be. (A registry a korbbi Windows ini llomnyokat vltja fel, programhoz ktd informcikat tudunk ebben az opercis rendszerbeli adatbzisban trolni.) Termszetesen innen be is olvashatjuk ezeket az adatokat. A programunk elvgzi ezt a mentst is, a visszaolvasst is. Ha viszont felteszi valaki a krdst a programban, hogy jelenleg kik azok, akiket a registry-ben is trolunk, akkor erre nincs ltalnos vlasz! Minden programba bele kell kdolni azt, hogy melyek a mentett adataink! Hasznos lenne, ha nem kellene ezt megtenni, csak jellhetnnk ezeket a mezket, s ezt a jellst ksbb kikereshetnnk. Msodik plda: Ez a plda taln kicsit tvolabb ll az informatiktl, de nem kevsb letszer. Definiljuk vagy nem is kell definilnunk, mert egybknt is lteznek az emberek klnbz csoportjait! Ebbe a definciba rtsk bele a normlis hasznlathoz szksges sszes tulajdonsgot (nem, foglalkozs, letkor, vgzettsg, )! Emellett szksgnk lehet mondjuk egy olyan informcira, hogy pldul az illet fradidrukker-e! Termszetesen az alaptulajdonsgok kz is felvehetnnk ezt a jellemzt, de mivel ennek az adatnak a tpus tnyleges mkdshez semmi kze nincs nem fradidrukker is vgezheti rendesen a dolgt , ezrt ez nem lenne szerencss. Az ilyen plusz informcik elhelyezsre nyjt lehetsget a C# nyelvben az attribtum. Az attribtumok olyan nyelvi elemek, melyekkel fordtsi idben osztlyokhoz, fggvnyekhez vagy adatmezkhz informcikat rendelhetnk. Ezek az informcik aztn futsi idben lekrdezhetk.

144

XI. Attribtumok

XI.1. Attribtumok definilsa


Mivel a nyelvben gyakorlatilag minden osztly, gy ha egy j attribtumot szeretnnk definilni, akkor valjban egy j osztlyt kell definilnunk. Annyi megkts van csak, hogy ezen attribtumot ler osztlynak az Attribute bzisosztlybl kell szrmaznia. Ezek alapjn a fradi_szurkol attribtum definilsa a kvetkezkppen trtnhet: Plda:
class fradi_szurkol:Attribute { }

Egy attribtum, ahogyan egy kivtel is, mr a nevvel informcit hordoz. Termszetesen lehetsgnk van ehhez az osztlyhoz is adatmezket definilni, ha gy tljk meg, hogy a tpusnv, mint attribtum mg kevs informcival br. Ekkor mint egy rendes osztlyhoz adatmezket tudunk definilni. Az adattpusokra annyi megkts van, hogy felhasznli osztlytpus nem lehet. Ellenben lehetnek a rendszerbeli alaptpusok (bool, int, float, char, string, double, long short, object, Type, publikus enum). Adatok inicializlsra konstruktort definilhatunk. Egy attribtum osztlyban ktfle adatot, paramtert klnbztethetnk meg. Pozicionlis s nevestett paramtert. Pozicionlis paramter a teljesen normlis konstruktorparamter. Nevestett paramternek nevezzk a publikus elrs adat- vagy tulajdonsgmezket. A tulajdonsgmeznek rendelkezni kell mind a get, mind a set taggal. A nevestett paramtereknek gy adhatunk rtket, mintha norml pozicionlis konstruktorparamter lenne, csak a konstruktorban nincs semmilyen jellsre szksg. A konstrukci kicsit hasonlt a C++ nyelvben hasznlatos alaprtelmezett (default) paramterek hasznlathoz. Ezek utn nzzk meg a fradi_szurkol attribtumunkat kt adattal kiegsztve. Az egyik legyen az az informci, hogy hny ve ll fenn ez a viszony, mg a msik az, hogy az illet trzsszurkol-e? Plda:
class fradi_szurkol:Attribute { private int v; // hny ve szurkol private bool trzsgrda; // trzsszurkol-e public fradi_szurkol(int e) { v=e; // konstruktor belltja a normal paramtert }

XI. Attribtumok
public bool Trzsgrda { get { return trzsgrda; } set { trzsgrda=value; } }

Ekkor a Trzsgrda tulajdonsgmezt nevestett paramternek hvjuk. Az elnevezst az mutatja, hogy erre a tulajdonsgra a konstruktorhvs kifejezsben tudunk hivatkozni, mintha ez is konstruktorparamter lenne, pedig nem is az! Plda:
[fradi_szurkol(5,Trzsgrda=true)]

XI.2. Attribtumok hasznlata


Az eddig megismert attribtumjellemzk definilst, hasznlatt, majd a beillesztett informci visszanyerst nzzk meg egy pldn keresztl! Mieltt ezt tennnk, meg kell jegyezni, hogy az informcivisszanyersi lehetsgek a tpusinformci lekrdezs lehetsghez illeszkednek. Ennek bzisosztlya a Type. Ezt a knyvtri szolgltatst az irodalom gyakran reflekcinak nevezi. Ezeket a lehetsgeket csak olyan mrtkben nzzk, amennyire a pldaprogram megkvnja. A tpusinformci szolgltats a Reflection nvtrben tallhat, teht a hasznlathoz a
using System.Reflection;

utastst kell a program elejre berni. A tpusinformci visszanyershez jellemzen a Type osztly GetType() statikus fggvnyt kell meghvni, ami egy paramtert vr tlnk, azt az osztlytpust, amit ppen fel szeretnnk dolgozni.
Type t=Type.GetType("program");

XI. Attribtumok Ekkor a programosztlyomat szeretnm a t nev tpusler objektumon keresztl elemezni. A kapott t objektumra megkrdezhetem pldul, hogy osztly-e:
if (t.IsClass()) Console.WriteLine("Igen");

Tovbbi lehetsgekhez a Type osztly online dokumentcijnl nincs jobb forrs. A tpushoz tartoz attribtumok listjt a GetCustomAttributes() fggvnyhvs adja meg. Ez eredmnyl egy Attribute vektort ad. Jellemz mdon, ezen egy foreach ciklussal lpdelnk vgig:
foreach (Attribute at in t.GetCustomAttributes()) { // feldolgozzuk az at attribtumot }

Ez a feldolgozs osztlyokra (pl. program, stb.) vonatkoz attribtumokra megfelel. Elfordulhat viszont olyan is, mikor fggvnyekhez vagy adatmezkhz rendelnk attribtumot. Ekkor elszr az adott tpus fggvnyeit vagy az adatmezit kell megkapnunk, majd ezen informcik attribtumait kell lekrdeznnk. Egy tpus fggvnyeit a GetMethods() hvs szolgltatja, eredmnyl egy MethodInfo tpust ad.
foreach(MethodInfo m in t.GetMethods()) { foreach (Attribute at in m.GetCustomAttributes()) { // feldolgozzuk az m fggvny at attribtumt } }

Egy tpus adatmezit a GetFields() adja, eredmnye FieldInfo tpus.


foreach(FieldInfo f in t.GetFields()) { foreach (Attribute at in f.GetCustomAttributes()) { // feldolgozzuk az f adatmez at attribtumt } }

Ha egy attribtumosztlyt definilunk, rjuk az osztly neve utn az Attribute szt, ahogyan azt gyakran tancsknt is megfogalmazzk a szakirodalomban,

XI. Attribtumok hiszen gy knnyen meg lehet klnbztetni a rendes osztlyoktl. Termszetesen ebben az esetben is elhagyhatjuk az attribute szcskt a hasznlat sorn, mert azt a fordt odarti. Teht ekkor a fradi_szurkol attribtumosztlyt a kvetkezkppen definiljuk:
class fradi_szurkolAttribute:Attribute { }

Ezen definci esetben is hasznlhatjuk a kvetkez alakot:


[fradi_szurkol]

Termszetesen ekkor a teljes nev hivatkozs is helyes:


[fradi_szurkolAttribute]

Ezek utn megnzzk a fradi_szurkol attribtumunk definilst s hasznlatt egy kerek pldn keresztl. A plda nem hasznlja az imnti Attribute kiegsztses defincit. Plda:
using System; using System.Reflection; class fradi_szurkol:Attribute { private int ev; // hny ve szurkol private bool torzsszurkolo; // vajon trzsszurkol-e public fradi_szurkol(int e) // az e rendes, pozicionlis { // paramter ev=e; } public override string ToString() { string s="Ez az ember fradiszurkol! vek szma:"+ev+"Trzsszurkol:"+torzsszurkolo; return s; } // az albbi Torzsszurkol tulajdonsg nevestett // fradi_szurkol paramter, mert publikus s van get s set

XI. Attribtumok
// rsze, amivel az adott torzsszurkolo logikai mezt llthatjuk public bool Trzsszurkol { get { return torzsszurkolo; } set { torzsszurkolo=value; } } } class ember { string nev; public ember(string n) { nev=n; } } class adatok{} //nem fontos, hogy rdemi informcit tartalmazzon class program { // attribtum belltsa [fradi_szurkol(35)] public ember en= new ember("Zoli"); // a norml konstruktort hvtuk meg, azok a mezk, amiket nem // inicializl, alaprtelms szerint kerlnek belltsra // 0, ha szm, false ha bool, illetve null, ha referencia // Egy attribtum csak a kvetkez adat vagy fggvny vagy // osztlyra hat!!! // gy a kvetkez adatok tpus vltoznak nincs kze // a fradi_szurkol attribtumhoz // public adatok a=new adatok(); // [fradi_szurkol(42,Trzsszurkol=true)] public ember te= new ember("Pali"); // Pali mr trzsszurkol public static void Main() {

XI. Attribtumok
program p=new program(); Console.WriteLine("A fprogram itt indul!"); Type t=Type.GetType("program"); foreach( FieldInfo mezo in t.GetFields()) { Console.WriteLine(mezo.FieldType); // meztpus kirsa Console.WriteLine(mezo.Name); // meznv krsa if ((mezo.GetCustomAttributes(true)).Length>0) { foreach (Attribute at in mezo.GetCustomAttributes(true)) { // megnzzk fradiszurkol-e fradi_szurkol f=at as fradi_szurkol; if (f!=null) // igen ez a mez fradiszurkol Console.WriteLine(at.ToString()); } } else Console.WriteLine("Ez az adat nem rendelkezik attribtummal!"); } Console.WriteLine("Program vge!"); } }

Eredmnyl az albbi kp jelenik meg:

15. bra

XI. Attribtumok

XI.3. Knyvtri attribtumok


Hrom knyvtri attribtum ll rendelkezsnkre: System.AttributeUsageAttribute: Segtsgvel megmondhatjuk, hogy a definiland j attribtumunkat milyen tpusra engedjk hasznlni. Ha nem lltjuk be, alaprtelmezs szerint mindenre lehet hasznlni. Az AttributeTargets felsorols tartalmazza a vlasztsi lehetsgeinket:
[AttributeUsage(AttributeTargets.Class)] osztlyattribtum:Attribute { }

Ekkor az osztlyattribtumok csak osztlyok jellsre hasznlhatk. Elfordulhat, hogy egy attribtumot tbbszr is hozz szeretnnk rendelni egy adathoz, akkor ennek az osztlynak az AllowMultiple nevestett paramtert igazra kell lltani.
[AttributeUsage(AttributeTargets.Class, AllowMultiple=true)]

System.ConditionalAttribute: Egy szveg a paramtere. Csak fggvnyhez kapcsolhatjuk, s az a fggvny, amihez kapcsoltuk csak akkor hajtdik vgre, ha a paramterl adott szveg definilt. Plda:
[Conditional("alma")] void almafuggveny() { Console.WriteLine("Alma volt!"); } #define alma almafuggveny(); #undefine alma almafuggveny(); // hvs rendben // hvs elmarad

XI. Attribtumok A feltteles vgrehajts fggvnyek ktelezen void visszatrsek, s nem lehetnek virtulisak, vagy override jelzvel elltottak! Ezeket a kirtkelseket az elfordt nzi vgig. System.ObsoleteAttribute: egy zenet(szveg) a paramtere, ha egy fggvny elavult, s javasolt a mellzse, akkor hasznlhatjuk.

XI.4. Feladatok
1. Mi az attribtum, hogy tudjuk hasznlni? 2. Hogyan definilhatunk sajt attribtumot? 3. Mi a klnbsg a rendes s nevestett attribtum paramter kztt? 4. Ksztsnk Hisz_e_a_mesben attribtumot! Definiljuk az ember osztlyt, majd alkalmazzuk az attribtumot egyes 'pldnyaira'! Mdostsuk az elz attribtumot gy, hogy meg tudjuk adni azt az idt amilyen rgta hisz valaki a mesben!

XII. Szabvnyos adatments


Az termszetes, ahogy korbban mr lttuk is, hogy a rendszerknyvtrak bsges tmogatst nyjtanak az adatok fjlba mentshez illetve visszaolvasshoz. Az alkalmazsok tekintetben ez teljesen termszetes igny. Az alaprtelmezett lehetsgek mellett ltalban a krnyezetek olyan szabvnyos eszkzzel is rendelkeznek, amelyek minden rendszertpusra rendelkezsre llnak, illetve a felhasznli tpusokra egyszeren implementlhatk. Ezzel egy olyan szolgltatst kapnak az alkalmazsok, amelyekkel szabvnyos ki- s bemeneti adatmozgatst vgezhetnek minden erre felksztett tpusra. Ennek a gyakorlati kvetkezmnye az, hogy az gy felksztett rendszerben a programoznak nem kell semmilyen extra mentsi stratgin gondolkodnia, hanem egyszeren csak azokat az objektumokat kell kivlasztania, amelyek rtkeit menteni akarja. Termszetesen ez a szolgltats is megtallhat majd minden mai krnyezetben. Az els klasszikus megvalstsa ennek a szolgltatsnak taln a Visual C++ krnyezetben jelent meg a Microsoft Foundation Classes (MFC) szolgltatsaknt, ahol a dokumentumosztly (az adatok helye) rendelkezsre bocst egy Serialize fggvnyt, amely ezt a szabvnyos alkalmazs adatmentst biztostja. Az MFC-ben minden knyvtri tpus a Serialize fggvnyben hasznlhat, mg a felhasznli tpusok egy egyszer lpssorozat eredmnyeknt kpess tehetk a szerializcira. Taln innen eredeztethet a nvads is, az irodalomban ezt a szolgltatst szerializci (Serialization), szabvnyos ments nvvel tallhatjuk meg.

XII.1. Knyvtri tpusok szabvnyos mentse


A szerializcis szolgltats a C# nyelvben, ahogy a standard input-output is, a rendszer knyvtri szolgltatsnak rsze, s ez a System.Runtime.Serialization nvtrben tallhat. Ha knyvtri tpusok mentsrl van sz, akkor kzvetlenl ennek a nvtrnek a hasznlatra nincs is szksgnk. Mieltt a kzvetlen lehetsgrl beszlnnk, a ki- s bemeneti adatfolyam formzsrl kell nhny szt ejtennk. A jelenlegi rendszerknyvtr ktfle tpus adatfolyam formzst tmogatja. Binris, illetve Soap, XML alap (szveges) formzst. Ezek az adatformz osztlyok vgzik a valdi adatfolyam elksztst. A binris adatfolyam binris eredmnyfjlt, mg a Soap XML formtum szveges llomnyt hoz

153

XII. Szabvnyos adatments ltre. Ha ez a ktfle lehetsg nem elg, akkor egyni formz osztlyok definilhatk. A formz osztlyok a System.Runtime.Serialization.Formatters.Binary s a System.Runtime.Serialization.Formatters.Soap nvterekben tallhatk. A szerializci folyamata az albbi lpsekbl ll: 1. Ki kell jellni egy FileStream objektumot, ami a program kapcsolatt jelenti az llomnnyal. 2. Definilni kell egy formz objektumot, ez jelenleg binris vagy szveges lehet. A szveges formz objektum ltrehozshoz a System.Runtime.Serialization.Formatters.soap.dll referencit a projekthez kell csatolni (Project nzet \ References \ jobb egrgomb \ Add reference).

16. bra

3. A formz objektum Serialize fggvnyvel mentjk az adatokat. 4. Bezrjuk a fjlkapcsolatot. Ezek utn nzzk a lehetsget bemutat pldaprogramot! Plda:
using using using using using System; System.IO; System.Runtime.Serialization; System.Runtime.Serialization.Formatters.Binary; System.Runtime.Serialization.Formatters.Soap;

XII. Szabvnyos adatments


class serprog { // program adatai int i=2; double d=3.5; string s="fradi"; public static void Main() { serprog p=new serprog(); //1.filestream ltrehozsa FileStream fb=File.Create("ser.bin"); // 2.Binaryformatter kszts FileStream fs=File.Create("ser.txt"); BinaryFormatter b=new BinaryFormatter(); SoapFormatter so=new SoapFormatter(); //3.binris ments b.Serialize(fb,p.i); b.Serialize(fb,p.d); b.Serialize(fb,p.s); // 3.Soap ments so.Serialize(fs,p.i); so.Serialize(fs,p.d); so.Serialize(fs,p.s); //4. fjlzrs fb.Close(); fs.Close(); } }

A program magyarzatul csak annyit, hogy miutn lefuttatjuk, a projekt debug knyvtrban (ebbe a knyvtrba kerl a lefordtott program) ltrejn a ser.bin, illetve a ser.txt llomny. Ha ezt megnzzk, lthatjuk, hogy mg az elbbi binris, az utbbi XML formtum. Visszaolvass hasonl mdon, csak a formatter objektum Deserialize fggvnyhvssal vgezhet el.

XII.2. Sajt tpusok szabvnyos mentse


Az elz plda sorn lttuk, mit jelent az alaptpusok mentsi lehetsge. A vals alkalmazsaink sorn azonban biztosan kszteni kell a f programosztlyon kvl egyb felhasznli osztlyokat is.

XII. Szabvnyos adatments Ebben az esetben a mentsi folyamat visszavezeti az adatok mentst a rendszertpusok mentsre. Ahhoz, hogy ezt megtegye neknk, egyetlen dolgot kell tennnk, a sajt tpusunkat a menthet, Serializable attribtummal kell jellnnk. Mdostsuk a pldaprogramunkat gy, hogy definilunk egy ember tpust, amit mg hasznlnia kell a programunknak. A mdostott forrsszveg a kvetkezkppen nz ki: Plda:
using using using using using System; System.IO; System.Runtime.Serialization; System.Runtime.Serialization.Formatters.Binary; System.Runtime.Serialization.Formatters.Soap;

[Serializable] // az attribtum hatsra a formz lekezeli a tpus szerializcijt class ember { string nev; int kor; public ember(string n, int k) { nev=n; kor=k; } } class serprog { // program adatai int i=2; double d=3.5; string s="fradi"; // a sajt tpus hasznlata ember e=new ember("Zoli", 34); public static void Main() { serprog p=new serprog(); //fjlstream ltrehozsa FileStream fb=File.Create("ser.bin"); // Binaryformatter kszts FileStream fs=File.Create("ser.txt"); BinaryFormatter b=new BinaryFormatter(); SoapFormatter so=new SoapFormatter(); //Binris ments b.Serialize(fb,p.i); b.Serialize(fb,p.d);

XII. Szabvnyos adatments


b.Serialize(fb,p.s); b.Serialize(fb,p.e); //Soap ments so.Serialize(fs,p.i); so.Serialize(fs,p.d); so.Serialize(fs,p.s); so.Serialize(fs,p.e); //fjl lezrsa fb.Close(); fs.Close();

} }

A gyakorlati munka sorn elfordulhat pldul az osztly bels szerkezete nem engedi meg , hogy nem bzhatjuk r a formzra a tpusunk vgigelemzst s az elemek mentst. Ebben az esetben a valdi szerializcis szolgltatst vgz fggvnyeket neknk kell az osztlyunkba implementlni. Azon tl, hogy a [Serializable] attribtumot definilni kell, az osztlyunknak mg implementlnia kell az ISerializable interface-t is. Ebben a deszerializci szmra egy specilis konstruktort s egy GetObjectData fggvnyt kell definilni. Az interface s a fggvnyek hosszabb elemzse nlkl nzzk meg az ennek megfelelen mdostott ember osztlyunkat. A program kdja vltozatlan, ezrt azt nem listzzuk ide. Plda:
[Serializable] // az attribtum hatsra a formz lekezeli a tpus szerializcijt class ember:ISerializable // az interface kt plusz fggvnydefincit r el { string nev; int kor; public ember(string n, int k) { nev=n; kor=k; } internal ember(SerializationInfo si, StreamingContext st) { // elemek visszalltsa nev=si.GetString("nev"); kor=si.GetInt32("kor"); }

XII. Szabvnyos adatments


public void GetObjectData(SerializationInfo si, StreamingContext st) { // a szerializls adatait belltja a SerializationInfo si // objektumba si.AddValue("nev",nev); si.AddValue("kor",kor); // tpusinformci belltsa Type t=this.GetType(); si.AddValue("Tpusinfo",t); }

XII.3. Feladatok
1. Mit neveznk szabvnyos mentsnek? 2. Milyen hasonl megvalstsokat ismer ms fejleszt rendszerben? 3. Milyen szabvnyos mentseket tmogat a fejleszt rendszer? 4. A msodfok egyenlet (VIII.3. fejezet 4. feladat) adatait mentsk el binris formban! 5. Definiljunk egy szurkol osztlyt (nv, kedvenc_csapat), s biztostsuk ennek a tpusnak szabvnyos menthetsgt!

XIII. Knyvtrak, tvoli s web knyvtrak


Az alkalmazsok ksztsnek egyik lnyeges eleme a fejlesztk rendelkezsre ll knyvtri szolgltatsok mennyisge, minsge, illetve a hasznlt keretrendszernek az a tulajdonsga, hogy mennyire ad lehetsget osztott alkalmazs ksztsre. Egy alkalmazs kiszolgl fggvnyei vagy a helyi gpen helyezkednek el, vagy valamelyik tvoli kiszolgl gpen.

XIII.1. Helyi knyvtrak hasznlata


XIII.1.1. Rendszerknyvtri elemek hasznlata
A helyi fejlesztrendszer knyvtrairl nyugodtan kijelenthetjk, hogy azok hasznlata nlkl, ahogy a legels rszben is lttuk, mg a legegyszerbb program sem kszthet el. (System nvtr, Console osztly, WriteLine fggvnyhvs.) A .NET keretrendszer egyik, taln leggyakrabban hasznlt knyvtra a System.Collections nvtr. A nvtr sok hasznos osztlydefincit tartalmaz, melyek kzl az albbiak a legfontosabbak: ArrayList: a mrett dinamikusan nvelni kpes objektumvektor. Az IList interface-t implementlja. Az IList hrom jellemz tulajdonsgot r el, ezek: IsFixedSize: IsReadOnly: Item: megvizsgja, fix mret-e a vektor, olvashat-e a vektor, a vektor adott index elemt adja, az ArrayList objek tum indexereknt hasznlhat.

HashTable: olyan vektorilis adatsorozat, ahol egy kulcsindexhez tartozik egy rtk. A kulcs hash rtkhez rendeli az adatot. Gyakran asszociatv vektornak hvjk ezt a szerkezetet.

159

XIII. Knyvtrak, tvoli s webknyvtrak Queue: a sor adatszerkezet megvalstsa. Az az elem megy elsnek ki a sorbl, amely elsnek berkezett. (First in, first out.) SortedList: rendezett lista. Hasonl szerkezet, mint a HashTable, melyek elemei a kulcs alapjn sorba vannak rendezve. Kulcs s index alapjn is az elemekhez lehet frni. Stack: verem adatszerkezet. Az utoljra betett elemet tudjuk mindig kivenni. (Last in, first out) Pldaknt tekintsk a kvetkez ArrayList s Queue hasznlatt bemutat mintaprogramot: Plda:
using System; using System.Collections; public class mintacol { public static void Main() { // j ArrayList objektum ltrehozsa. ArrayList elemek = new ArrayList(); elemek.Add( "Hajr" ); // alaprtelmezsben a mret nvelhet (IsFixedSize==false) elemek.Add( "Fradi" ); elemek.Add(25); for (int i=0;i<elemek.Count;i++) Console.WriteLine(elemek[i]); // j sor (Queue) objektum ltrehozsa. Queue sor = new Queue(); // adat sorba rsa sor.Enqueue( "mzes" ); sor.Enqueue( "maci" ); sor.Enqueue( 3.1415 ); // mind az Arraylist, mind a sor implementlja az IEnumerable // interface-t, gy a foreach hasznlhat foreach(object o in sor) Console.WriteLine(o); // ArrayList objektumhoz hozzadjuk a sort. elemek.AddRange( sor ); // elem kivtele a sorbl Console.WriteLine(sor.Dequeue()); Console.WriteLine(sor.Dequeue()); Console.WriteLine(sor.Dequeue());

XIII. Knyvtrak, tvoli s webknyvtrak


// Kirjuk az elemeket Console.WriteLine( "A bvtett ArrayList a kvetkez elemeket tartalmazza:" ); PrintValues( elemek );

// az IEnumerable alapjn vgiglpdelnk az elemeken public static void PrintValues( IEnumerable adatok) { IEnumerator adat = adatok.GetEnumerator(); while ( adat.MoveNext() ) Console.WriteLine( adat.Current ); } }

XIII.1.2. Sajt knyvtri elemek hasznlata


A keretrendszer kzs nyelvi specifikcijnak ksznheten tetszleges nyelvi knyvtrat hasznlhatunk azonos mdon, tetszleges alkalmazsban. A pldban VB fggvnyt definilunk, amit egy msik alkalmazs hasznl:
Public Class Demo Shared Function legjobb_csapat() As String legjobb_csapat = "Fradi!" End Function End Class

A fenti forrskdot teszleges szvegszerkesztbe berva, az albbi parancssor segtsgvel lefordthat. (A keretrendszer mindegyik fordtja indthat parancssorbl.)
vbc /target: library /out:DllDemo Demo.vb

Termszetesen j projektet ksztve, az osztlyknyvtr tpust vlasztva a Visual Studio.NET krnyezetbe is berhatjuk ezt a pr sort, majd a Build menpont segtsgvel lefordthatjuk. Az elkszlt DllDemo.dll llomny egy tipikus knyvtri llomny lesz, amit brmely msik alkalmazs hasznlhat, pontosan gy, ahogy a rendszerknyvtrakat. Ksztsnk most egy C# nyelv alkalmazst, amely szeretn hasznlni a DllDemo knyvtri szolgltatst. A hasznlathoz az alkalmazshoz kell csatolni (add reference) ezt a knyvtrllomnyt, majd a using DllDemo utastssal a DllDemo nvtr elrhetsgt is biztostani kell.

XIII. Knyvtrak, tvoli s webknyvtrak Plda:


using System; using DllDemo; public class minta { public static void Main() { // j demo objektum ltrehozsa. // ezt ksztettk Visual Basic nyelvben Demo d = new Demo(); //kvncsiak vagyunk arra, hogy ki a legjobb csapat // meghvjuk a dll fggvnyt Console.WriteLine(d.legjobb_csapat()); Console.WriteLine("Program vge"); } }

XIII.2. Tvoli knyvtrhvs


A tvoli knyvtrhvs szerkezete, lehetsgei nmagban egy teljes knyvet is megrdemelnnek, de a jelen trgyalsi menetbe, a knyvtri szolgltatsok tpusai kz is beletartozik, ezrt egy rvid bevezetst meg kell emlteni errl a terletrl. Egy alkalmazs opercis rendszerbeli krnyezett application domainnek nevezzk. Az elz DLL ksztsi lehetsg egy application domaint alkot. A fggetlen alkalmazsok kzti kommunikcit, tvoli alkalmazshvs lehetsgt a .NET krnyezetben REMOTING nvvel emlti az irodalom. Valjban hasonl lehetsgrl van sz, amit a korbbi fejlesztsi krnyezetek, COM (Component Object Model) nven emltenek. Az alapproblma valjban ugyanaz, mint a DLL knyvtr esetben, egy valahol meglv szolgltatst szeretnnk ignybe venni. Ez DLL formban most nincs jelen, viszont az a tpus objektum, aminek ez a szolgltatsa van, egy msik gp nll alkalmazsaknt van jelen. gy a legfontosabb krds az, hogy nll alkalmazsi krnyezetek kztt, melyek termszetesen vagy azonos szmtgpen helyezkednek el, vagy nem, a legfontosabb krds az, hogyan tudunk informcit tadni. Ennek a kommunikcinak legfontosabb elemei a kvetkezk: Kommunikcis csatorna kialaktsa, regisztrlsa. Az adatok szabvnyos formzsa a kommunikcis csatornba rs eltt.

XIII. Knyvtrak, tvoli s webknyvtrak tmeneti, proxy objektum ltrehozsa, mely az adatcsert elvgzi a tvoli objektum (pontosabban annak proxy objektuma) s a helyi alkalmazs kztt. Tvoli objektum aktivlsa, lettartama Kommunikcis csatornt Tcp vagy Http alapon alakthatunk ki. Hasznlat eltt regisztrlni kell egy csatornt, ami egy kommunikcis porthoz kttt. Egy alkalmazs nem hasznlhat ms alkalmazs ltal lefoglalt csatornt. A ktfle kommunikci hasznlata kztt a legfontosabb klnbsg az adatok tovbbtsban van. A Http protokoll a SOAP szabvnyt hasznlja az adatok tovbbtsra XML formban. A Tcp csatorna binris formban tovbbtja az adatokat. A proxy objektum reprezentlja a tvoli objektumot, tovbbtja a hvsokat, visszaadja a hvsi eredmnyt. A tvoli objektumok a szerver oldalon automatikusan, vagy kliens oldali aktivlssal jhetnek ltre. Az automatikus objektumok esetben megklnbztetnk egy krst kiszolgl objektumot (Single call) vagy tbb krst kiszolgl (Singleton) objektumot. Meg kell termszetesen jegyezni, hogy a szolgltatst, a programot magt el kell indtani, hiszen a klienshvs hatsra csak az alkalmazs egy kiszolgl tpusa jn automatikusan ltre! Ezt vagy gy rjk el, hogy az alkalmazsunkat futtatjuk egy konzolsori parancs kiadsval, vagy mint regisztrlt szervzt az opercis rendszer futtatja! Mieltt egy konkrt pldt nznnk, beszlni kell a paramter tads lehetsgrl. Egy alkalmazson bell a keretrendszer biztostja az adatok paramterknti tadst, tvtelt. Esetnkben nem egy alkalmazsrl van sz, hanem egy kliensrl s egy (vagy tbb) szerverrl, melyek klnbz krnyezetben (app. domainben) futnak. Emiatt az adatok tadsa sem lehet ugyanaz, mint egy alkalmazson bell. A klnbz alkalmazsi krnyezetben fut programok kztti adatcsere folyamatt Marshaling kifejezssel illet az irodalom, utalva arra, hogy ez a fajta alkalmazsi hatron tvezet adatforgalom mst jelent, mint egy alkalmazsi krnyezet esetben. Egy adatot hrom kategriba sorolhatunk a .NET keretrendszerben, a tvoli adattads (Marshaling) szempontjbl: 1. rtk szerint tadott adatok. Ezen tpusok a szabvnyos szerializcit (ments) tmogat objektumok. (Marshal-by-value). Ekkor a tpus a [Serializable] attribtummal jellt. A krnyezet alaptpusai (int, stb.) menthetek, gy rtk szerint tadhat adatok. 2. Referencia szerint tadott adatok. Ezek a tpusok ktelezen a MarshalByRefObject tpusbl szrmaznak.

XIII. Knyvtrak, tvoli s webknyvtrak 3. Alkalmazsdomainek kztt nem tadhat tpusok. Ebbe a kategriba esik minden olyan tpus, amelyik nem MarshalByRefObject utd, vagy rendelkezik a [Serializable] attribtummal. A legfontosabb tulajdonsgok ismertetse utn nzznk egy egyszer pldt. Manulisan fogjuk a szerverkiszolglkat is futtatni az egyszersg kedvrt. A pldnkban kt szerverszolgltatst ksztnk, az egyik http, mg a msik tcp hlzati kommunikcit folytat. A forrskdot mind parancssorbl, mind a krnyezetbl tudjuk fordtani. Ez utbbi esetben a Project referencia ablakban a projekthez kell adni a System.Runtime.Remoting nvteret. Az albbi plda egy bajnokszerver tpust definil, regisztrlja magt, s ms feladata nincs. Enterre a Main program azrt vrakozik, mert ha engedjk befejezdni, mivel nem rendszerrsz-szolgltats, nem lehet elrni. Plda:
using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; public class BajnokSzerver : MarshalByRefObject { public string foci; public static int Main(string [] args) { TcpChannel chan1 = new TcpChannel(8085); // 8085 tcp port lefoglalva ChannelServices.RegisterChannel(chan1); // regisztrci rendben RemotingConfiguration.RegisterWellKnownServiceType( typeof(BajnokSzerver), "bajnok", // kliens oldalon elrhet // szolgltats neve WellKnownObjectMode.Singleton); System.Console.WriteLine("Program vge, nyomjon entert"); System.Console.ReadLine(); return 0; } public BajnokSzerver() { foci="Magyar bajnoksg"; Console.WriteLine("Remote szerver aktivlva!"); }

XIII. Knyvtrak, tvoli s webknyvtrak


public string Ki_a_bajnok(int ev) { string nev="Nem tudom!"; switch (ev) { case 2002: nev="Dunaferr"; break; case 2003: nev="MTK"; break; case 2004: nev="Ferencvros"; break; } Console.WriteLine("A krt bajnocsapat: {0} ",nev); return nev; } }

A msik szerver lnyegben abban klnbzik, hogy http csatornt hasznl:


using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; public class golkiraly : MarshalByRefObject { public string sportag ; public static int Main(string [] args) { HttpChannel chan1 = new HttpChannel(8086); // http csatorna foglalsa ChannelServices.RegisterChannel(chan1); // regisztrci RemotingConfiguration.RegisterWellKnownServiceType( typeof(golkiraly),// tpus nevnek regisztrlsa "golkiraly", // kliens oldali http szolgltatsnv WellKnownObjectMode.Singleton); // szervermd System.Console.WriteLine("Program vge!"); System.Console.ReadLine(); return 0;

public golkiraly() { sportag = "foci"; Console.WriteLine("Glkirly szerver aktivlva"); }

XIII. Knyvtrak, tvoli s webknyvtrak


public string ki_a_golkiraly(int ev) { Console.WriteLine("Glkirly szolgltats az albbi sportgban: {0}", sportag); return "Sajnos mg nem tudom!"; }

A kliens programunk, amelyik mindkt kiszolglprogramot hasznlja a kvetkez formj:


using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Remoting.Channels.Http; using System.IO; public class kliens { public static int Main(string [] args) { HttpChannel chan1 = new HttpChannel(); // kliens csatorna portot nem adunk meg ChannelServices.RegisterChannel(chan1); golkiraly g =(golkiraly)Activator.GetObject( typeof(golkiraly), "http://localhost:8086/golkiraly"); TcpChannel chan2 = new TcpChannel(); ChannelServices.RegisterChannel(chan2); BajnokSzerver b = (BajnokSzerver)Activator.GetObject( typeof(BajnokSzerver), "tcp://localhost:8085/bajnok"); try { string bajnok = b.Ki_a_bajnok(2004); Console.WriteLine("2004 bajnokcsapata: {0}",bajnok ); string golkiraly= g.ki_a_golkiraly(2004); Console.WriteLine( "Glkirly Szerver vlasz: {0}",golkiraly ); } catch (Exception ioExcep) { Console.WriteLine("Remote IO Error" + "\nException:\n" + ioExcep.ToString()); return 1; } return 0; } }

XIII. Knyvtrak, tvoli s webknyvtrak A kliens fordtsa parancssorbl knyelmesebb:


csc /r:remoteserver1.exe,remoteserver2.exe kliens.cs

Indtsuk el egy-egy ablakban elszr a szerver-, majd a kliensprogramot, ahogy a kvetkez kpen is ltszik.

17. bra

Termszetesen a szerverablakban lthat eredmny a szemlletessget szolglja, a vals alkalmazsok (mivel nem is futnak nll ablakban) nem rogatnak semmit a kpernyre. A korbbi feladathoz hasonl kliens-szerver alkalmazsksztsi lehetsget is biztost a keretrendszer, gynevezett WebRequest, WebResponse modellt hasznlva, vagy a klasszikus TCP, UDP protokollok hasznlatval (TcpListener, TcpClient, UdpClient). Az osztlyok a System.Net nvtrben tallhatk. A System.Net sszes szolgltatsa a System.Net.Sockets nvtr szolgltatsaira pl. A System.Net.Sockets nvtr a WinSock32 API megvalstsa. Ezen hlzati alkalmazsok ksztsnek lehetsge tlmutat e knyv keretein, gy nem is rszletezzk azokat.

XIII. Knyvtrak, tvoli s webknyvtrak

XIII.3. Webknyvtrak hasznlata


A webknyvtrak hasznlata (Web Services, webszolgltatsok) valjban a tvoli knyvtrhvs http alap alkalmazsnak webkiszolgln keresztli megvalstshoz hasonlt, a webszerver tlti be a kiszolgl rendszerbe integrlst s biztostja a tvoli elrhetsget. Ekkor azon a kiszolgln, ahol webknyvtrat akarunk elhelyezni, ott MS IIS webszervernek kell futni. Ebben az esetben is legalbb kt alkalmazs ksztsrl beszlhetnk, a szerveroldali alkalmazs ksztshez egy kln sablont tallunk (ASP.NET Web Service nvvel), mg a kliensalkalmazs tetszleges C# alkalmazs lehet, pldul a klasszikus konzol. Szerveralkalmazs ksztshez kezdjnk j ASP.NET Web Service alkalmazst. Ebben az alkalmazsban egyszeren a [Webmethod] attribtummal elltott fggvnyek rhetk el a kls kliensek szmra Nzzk ezek alapjn a bajnokra vonatkoz pldnk webknyvtrral megvalstott forrst: Plda:
using using using using using using using System; System.Collections; System.ComponentModel; System.Data; System.Diagnostics; System.Web; System.Web.Services;

namespace WebService1 { /// <summary> /// Summary description for Service1. /// </summary> public class Service1 : System.Web.Services.WebService { public Service1() { InitializeComponent(); } //Component Designer generated code [WebMethod] public string Ki_a_bajnok(int ev) {

XIII. Knyvtrak, tvoli s webknyvtrak


string nev="Nem tudom!"; switch (ev) { case 2002: nev="Dunaferr"; break; case 2003: nev="MTK"; break; case 2004: nev="Ferencvros"; break; } return nev;

} } }

A forrskd service1.asmx.cs nven tallhat. Fordts utn az IIS kiszolgl webservice1 virtulis knyvtrba kerl service1.asmx llomnyra hivatkozva tudjuk futtatni a feladatot. A fenti kiszolgl hasznlathoz webreferencit kell a ksztend projekthez adni, ahol meg kell adni a Web Service cmt a kvetkez mdon: http://localhost/webservice1/service1.asmx Ezt legegyszerbben az Add Web Reference menpontban tehetjk meg:

18. bra

XIII. Knyvtrak, tvoli s webknyvtrak A hasznlatt az albbi forrskd mutatja:


using System; namespace webhasznal { /// <summary> /// Summary description for Class1. /// </summary> class Class1 { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main(string[] args) { // // a webreferencia neve localhost // localhost.Service1 s=new localhost.Service1(); Console.WriteLine(s.Ki_a_bajnok(2004)); } } }

A futsi eredmny megadja a vrt csapatnevet. Termszetesen a using nvtr hasznlattal az s objektumdefincit egyszerbben rhatjuk.
using webhasznal.localhost; // projekt neve utn jn a webreferencia neve Service1 s=new Service1(); // A hasznlatban mr nincs vltozs

A webkiszolgl szolgltatst, nemcsak egy kliens programbl, hanem a legltalnosabban hasznlt webes kliens programunkbl, pldul az Internet Explorerbl is kiprblhatjuk (19. bra). A szolgltatsokat ltalnosan ler nyelv (Web Service Description Language, WSDL) termszetesen XML formban adja meg, ezt az albbi krssel tudjuk megnzni: http://localhost/webservice1/service1.asmx?WSDL

XIII. Knyvtrak, tvoli s webknyvtrak

19. bra

A webszolgltatsnak ezt a hasznlatt gyakran szinkronhvsnak nevezzk. Ugyanis ebben az esetben a Ki_a_bajnok hvsa az eredmny visszarkezsig nem tr vissza. Ez webes kiszolgls esetn gyakran hosszabb idt is ignybe vehet. St az sem kizrt, hogy adott idn bell vissza sem tr. Ha figyelmesen megnzzk a projekt knyvtrunkat, akkor ebben megjelent egy Web References knyvtr is. Ebben aztn annyi knyvtrt tallunk, ahny webreferencit csatoltunk a projektnkhz. Esetnkben tallunk egy localhost knyvtrat (localhost a neve a http://localhost/webservice1 URL ltal megadott webknyvtrnak), ebben egy References.cs llomnyt. Ha ezt megnzzk, ltjuk, hogy nem csak a megrt fggvnynk van lerva benne, hanem egy BeginKi_a_bajnok s egy EndKi_a_bajnok hvs is. Ezek a fggvnyek adnak lehetsget arra, hogy egy ilyen webkiszolgln elhelyezett szolgltatst ne csak a sajt nevvel, gynevezett szinkronhvssal tudjunk elrni, hanem aszinkron mdon is. A Begin-nel kezdd fggvny mindig azonnal visszatr, eredmnyl egy IAsyncResult objektumot kapunk. Ezen az objektumon keresztl krdezhetjk meg, hogy befejezdtt-e a vgrehajts. Esetnkben a msodik paramter s a harmadik is a null, jelezve azt, hogy az aszinkron hvs eredmnyt az IAsyncResult objektumon keresztl akarjuk lekrdezni. Egybknt a msodik paramter egy deleglt (callback) fggvny, ami ltal adott fggvny kerl vgrehajtsra akkor, amikor megrkezik az eredmny. A harmadik paramter

XIII. Knyvtrak, tvoli s webknyvtrak egy krs llapotot jelz objektum, amiben a callback fggvny meg tudja nzni az eredmnyparamtereket. Az albbi plda nem hasznlja ezeket a paramtereket, hanem az IAsyncResult IsCompleted tulajdonsgt figyelve vrakozik az eredmnyre. Plda:
static void Main(string[] args) { // // TODO: Add code to start application here // localhost.Service1 s=new localhost.Service1(); Console.WriteLine("Szinkronhvs eredmnye: {0}",s.Ki_a_bajnok(2004)); IAsyncResult e=s.BeginKi_a_bajnok(2004,null,null); // elindtottuk a fggvnyhvst, majd addig //vrakozunk, amig az eredmny meg nem rkezik while(e.IsCompleted!=true) Console.WriteLine("Vrjuk az eredmnyt!"); // megjtt az eredmny // kiolvassuk azt string eredmeny=s.EndKi_a_bajnok(e); Console.WriteLine("Az aszinkronhvs eredmnye: {0}",eredmeny); }

Esemnyvezrelt krnyezetben, grafikus alkalmazs ksztsekor ez a mdszer kzenfekv lehet. A program futsnak eredmnye jl illusztrlja az aszinkron vgrehajts jellegzetessgt, amit az albbi futsi kp is jl szemlltet:

20. bra

XIII. Knyvtrak, tvoli s webknyvtrak

XIII.4. Feladatok
1. Milyen rendszer knyvtri tpusokat ismer? 2. Mi a klnbsg a rendszer knyvtri s a web knyvtr szolgltats kztt? 3. Mit neveznk szinkron, illetve aszinkron knyvtri hvsnak? 4. rjon programot, amely egy listban trolja a kifizetett telefonszmlk sszegt! Valstsa meg a beolvasst, kirst fggvnyknt! 5. Ksztsen WebService-t, amely egy adott nvrl eldnti, hogy olimpiai bajnok neve-e!

XIV. Az elfeldolgoz
XIV.1. Szimblumdefinci hasznlata

Az elfeldolgoznak vagy elfordtnak szl utastsok mindig a # karakterrel kezddnek. Az elfordtnak szl makr definilsi lehetsgnek a formja:

#define nv Plda:
#define menu_h // menu_h szimblum definilva

A defincik hatsa az adott modul vgig tart. Egy azonost definilsnak gyakori formja a kvetkez: Plda: #define ALMA Ekkor nem definilunk helyettestsi rtket, gy ez csak annyit mond meg az elfordtnak, hogy ettl kezdve az ALMA sz legyen ismert. Ez gyakran hasznlt md a feltteles fordts azonostinak definilsra. Ha mr nincs szksgnk egy korbban definilt azonostra, s meg szeretnnk krni az elfordtt, hogy felejtse azt el, akkor a kvetkez elfordtnak ezt az utastst adhatjuk:

#undef nv Pldul az imnt definilt ALMA azonost esetben: Plda:


#undef ALMA

174

XIV. Az elfeldolgoz

XIV.2. Terleti jells


A fejlesztrendszer szvegszerkesztje nyjtja alaprtelmezsben azt a knyelmi szolgltatst, hogy egy fggvny vagy osztlydefinci trzst a szvegszerkeszt bal oldaln tallhat + vagy gombokkal elrejthetjk vagy megtekinthetjk.

21. bra

A fenti kpen az ember osztly tartalmt ltjuk, mg a tbbi egysgt (adatok, program) nem, azokat csak jelli a szvegszerkeszt, hogy lteznek, de pillanatnyilag nem rdekesek. Ez a segtsg nagyobb llomnyok szerkesztsnl hasznos, hiszen a szerkesztablakban jobban a lnyegre tudunk figyelni. Ezt a szolgltatst egszti ki a
#region alma osztlyok, fggvnyek helye #endregion alma

rgi, terletdefinci. Ekkor az alma blokkban, rgiban definilt osztlyok, fggvnyek egyszerre hzhatk ssze vagy nyithatk ki.

XIV. Az elfeldolgoz

XIV.3. Feltteles fordts


#if konstans kif #ifdef azonost #ifndef azonost Igaz-e konstans kif. Van-e ilyen makr Nincs-e ilyen makr

Mindhrom alakot kvetheti a #else direktva, majd ktelezen zrja: #endif #line sorszm A fordt gy viselkedik, mintha a kvetkez sor a sorszmmal megadott sor lenne. #line default eredeti sorszm visszalltsa

XIV.4. Hibazenet
Ha mr az elfordt felfedez valamilyen hibt, akkor hibazenetet ad, s befejezi az elfordtst. A vezrldirektva formja: #error hibaszveg Plda:
#ifndef c# #error Sajnos nem a megfelel fordtt hasznlja! #endif

XIV.5. Feladatok
1. Mik az elfordt jellemz szolgltatsai? 2. Hogy definilhatunk s szntethetnk meg egy azonostt? 3. Mit jelent a rgi definci? 4. Az eddig elksztett programjait mdostsa rgi defincikkal! Figyelje meg, hogy mennyivel ttekinthetbb vlt a programjnak a kdja! 5. Definilja gy a msodfok egyenletet megold fggvnyt, hogy csak akkor fordtsuk le, ha szksges!

XV. Nem felgyelt kd hasznlata


A C# nyelv program fordtsa egy felgyelt eredmnyprogramot ad, amin a felgyeletet a .NET keretrendszer biztostja. Szksg lehet azonban arra, hogy a rendelkezsre ll nem felgyelt, rendes Win32 API knyvtrak szolgltatsait elrjk, s az ezekkel kapcsolatos adatainkat tudjuk hasznlni, a knyvtrhoz hasonl nem felgyelt kdrszletet tudjunk rni.

XV.1. Nem felgyelt knyvtr elrse


Taln leggyakrabban ez az igny merl fel, hiszen ha megvan egy jl megrt szolgltats a korbbi Windows API knyvtrban, akkor azok hasznlata mindenkppen kifizetdbb, mint helyettk megrni azok menedzselt vltozatt. Erre ad lehetsget a DllImport attribtum hasznlata. Egy knyvtri fggvny hasznlathoz hrom lpst kell megtenni: 1. A DllImport attribtumnak meg kell mondani a Dll llomny nevt, amit hasznlni akarunk. 2. A knyvtrban lv fggvnyt a fordt szmra deklarlni kell, ebben az extern kulcssz segt. Ezeket a fggvnyeket egyttal statikusnak is kell jellni. 3. A System.Runtime.InteropServices nvteret kell hasznlni. Ezek utn nzzk meg pldaknt a MessageBox API fggvny hasznlatt. Plda:
using System; using System.Runtime.InteropServices; class dllhasznl { [DllImport("user32.dll")] static extern int MessageBox(int hwnd,string msg, string caption, int type); public static void Main() { MessageBox(0,"Hajr Fradi !","Ez az ablakfelirat!",0); } }

177

XV. Nem felgyelt kd hasznlata A program futtatsa utn az albbi rendszer-zenetablak jelenik meg:

22. bra

XV.2. Mutatk hasznlata


Ahogy korbban is volt sz rla, a keretrendszer a C++ jelleg mutatk hasznlatt nem tmogatja. Elfordulhat viszont az, hogy kls erforrsok elrshez, illetve azok adatai miatt szksg lehet nem menedzselt, nem biztonsgos krnyezet engedlyezsre. Ebben a krnyezetben aztn a C++ nyelvben hasznlt mutatfogalom hasznlhat. A nyelv egy fggvnyt vagy egy utastsblokkot tud nem biztonsgoss, nem felgyelt kdrszlett nyilvntani az unsafe kulcssz hasznlatval. Emellett egy menedzselt adatot fixed jelzvel tudunk elltni, ha azt akarjuk, hogy a GC ltal felgyelt terletbl egy tpushoz (menedzselt tpus) nem biztonsgos mutat hozzfrst kapjunk. Ez termszetesen vatos hasznlatot kvn, hiszen knnyen elfordulhat, hogy az objektumunk a Garbage Collection eredmnyeknt mr rgen nincs, mikor mi mg mindig a mutatjval bvszkednnk! A mutatkat csak unsafe blokkban hasznlhatjuk. Ahhoz, hogy a fordt engedlyezze az unsafe blokkot, a projekttulajdonsgok kztt be kell lltani az Allow Unsafe Code Blocks opcit igazra, ahogy az a kvetkez Tulajdonsg ablakban is ltszik.

23. bra

XV. Nem felgyelt kd hasznlata Ezt a belltst parancssori krnyezetben a csc fordtnak az /unsafe kapcsolja hasznlatval rhetjk el. Ezek utn nzznk egy klasszikus C++ nyelvszer maximumrtk meghatrozst. Az albbi pldban a max fggvny egy egsz vektor legnagyobb rtkt hatrozza meg. Plda:
using System; class unmanaged { unsafe int max(int* v, int db) { int i=0; int m=v[i++]; while(i<db) { if (m<v[i]) m=v[i]; i++; } return m; } int[] s=new int[10]{1,2,3,4,5,0,21,11,1,15}; unsafe public static void Main() { int h=0; unmanaged u=new unmanaged(); fixed (int* m= &u.s[0]) { h=u.max(m,10); } Console.WriteLine(h); } }

XV.3. Feladatok
1. Mit jelent a nem felgyelt kd (unsafe)? 2. Hogyan tudunk Win32 API fggvnyt meghvni? 3. Mi a fixed vltoz? 4. Hogyan hasznlhatunk mutatkat egy C# programban? 5. Ksztsen unsafe fggvnyt, amelyik a paramter vektort nagysg szerint sorbarendezi!

XVI. Grafikus alkalmazsok alapjai


A mai grafikus felhasznli felleteken az egyik leginkbb kedvelt vagy elvrt alkalmazsksztsi lehetsg a grafikus programok ksztse. Emellett az is elmondhat, hogy egy program futtatst nem biztos, hogy a helyi gpen szeretnnk vgezni. Az internet jelenlegi elterjedst figyelembe vve, egyre gyakrabban merl fel az az igny, hogy az alkalmazst brki elrhesse egy szabvnyos internetbngsz program (Internet Explorer, Netscape, Opera stb.) segtsgvel. Miutn megismertk a korbbi fejezetekben a C# nyelvi s legfontosabb keretrendszeri szolgltatsait, befejezskppen nzznk meg egy-egy pldt Windows alap s Webes alap alkalmazsok ksztsre.

XVI.1. Windows alkalmazsok alapjai


Ahogy eddig is lttuk, a legfontosabb alkalmazsi tpusok ksztshez a fejlesztkrnyezet ksz sablont bocst a fejlesztk rendelkezsre. gy van ez ebben az esetben is. j alkalmazs (project) ksztsekor a Windows Application sablont vlasztva kapjuk a kicsit preparlt forrskdot. Ez az llomny form1.cs nvre hallgat, s valjban a programot ad Main fggvny trzse ki van tltve:
static void Main() { Application.Run(new Form1()); }

Ez a kdsor azt jelenti, hogy a form utdosztlyunk (Form1) ltal kpviselt grafikus fellet illeszkedjen az opercis rendszer felgyeletbe, s az ablak jelenjen meg. Ez az ablak elszr termszetesen res, a f feladat ppen az, hogy megfelel tartalommal lssuk el, ezltal elksztve a kvnt programot. A program elksztsben a legnagyobb segtsget a grafikus knyvtri elemek, a Windows Forms nvtr objektumai (form ablak, cmke, nyomgomb stb.) adjk. Ezt a lehetsghalmazt a Toolbox ablak mutatja, amit a rajzszg segtsgvel gyakran a kpernyre helyeznk. Ksztsnk a legjellemzbb tulajdonsgok bemutatsra egy msodfok egyenletet megold programot. Az j projekt nevnek adjuk meg a masodfok nevet, vlasszuk ki a Windows Application sablont, majd a kapott felletre rajzszgezzk ki a Toolbox ablakot.

180

XVI. Grafikus alkalmazsok alapjai Az gy kapott kperny a kvetkezkppen nz ki:

24. bra

A forrsllomnyt megnzve azt lthatjuk, hogy ebben az llapotban a programunk valjban egy form (ablak) objektumbl ll (new Form1()). Ezt a Tulajdonsgok (Properties) ablak lenyl mezjbl is megllapthatjuk, hiszen nem tudunk msik objektumot kivlasztani. A Tulajdonsgok (Properties) ablakban tervezskor llthatjuk be a kivlasztott komponensnk legjellemzbb tulajdonsgait, kezd adatait. Ezek a tulajdonsgok futs kzben is hasonl mdon megvltoztathatk. Az egyszer adatok mellett ez az ablak ad lehetsget egyes objektumok esemnykezel paramternek belltsra. Ez azrt lnyeges, mert ebben a krnyezetben a programok valdi tevkenysgt ezek a fggvnyek vgzik. gy valjban programkszts cmn kicsit egyszerstve nincs msrl sz, mint hogy olyan grafikus elemekkel ptsk fel a programablakot, amelyek esemnykezeli ppen a kvnt feladatot oldjk meg. Ezek utn nzzk a clul kitztt egyszer feladatot, a msodfok egyenlet megoldst, amin keresztl a legjellemzbb lpseket szemlltetni tudjuk. Mieltt nekifognnk a megoldsnak, le kell szgeznnk, hogy a karakteres felleten hasznlt beolvassi s krsi lehetsgek nem hasznlhatak. Erre a

XVI. Grafikus alkalmazsok alapjai clra a Toolbox ablak elemeit tudjuk hasznlni. A leggyakrabban hasznlt elem kirsra a cmke (Label), mg beolvassra a szvegdoboz (TextBox). Ezen elemek segtsgvel alaktsuk ezutn ki a program felhasznli fellett, ahol a cmkkkel informcit runk ki, mg a szveges beolvas elemek a paramterek beolvasst biztostjk. A formra tegynk cmkket, s a cmke Text tulajdonsg mezjbe a megjelenteni kvnt szveget rjuk bele. A szvegmezk alaprtelmezett Text mez rtkt pedig trljk ki. Ezek alapjn egy kevs munkval az albbi fellet alakthat ki:

25. bra

Azt termszetesen nem lltom, hogy ez a legszebb kialakts, de a clnak megfelel. A fenti grafikus tervezs utn lthatjuk a Tulajdonsg ablak objektum kivlasztmezjben, hogy minden egyes nll vezrl (label, textbox) egy-egy vltoz nvvel jelenik meg. Ezeket a neveket (label1, label2, stb.) a keretrendszer automatikusan adja, s ha szksgnk van ezek ksbbi hasznlatra, akkor a programtervezsi szempontok figyelembevtelvel adjunk beszdes nevet ezen vltozknak. Ezt a Tulajdonsg ablak Name mezjnek mdostsval tehetjk meg. A hrom egytthat beolvasst biztost textmeznek rendre az a, b, c neveket adtam, mg a megoldst megjelent cmknek a megoldas nevet. Az ablakot reprezentl C# nyelvi forrskd az albbiak szerint mdosul.

XVI. Grafikus alkalmazsok alapjai


namespace masodfok { /// <summary> /// Summary description for Form1. /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label3; private System.Windows.Forms.Label label4; private System.Windows.Forms.Button button1; private System.Windows.Forms.TextBox a; private System.Windows.Forms.TextBox b; private System.Windows.Forms.TextBox c; private System.Windows.Forms.Label megoldas;

Ezeket a bejegyzseket a keretrendszer automatikusan elvgzi. Azonban meg kell jegyezni, hogy a vezrlink elnevezst csak ebben a kdrszben vgzi el a keretrendszer, gy ha utlag neveznk t vezrlket, akkor a programkdbeli vltozsokrl magunknak kell gondoskodnunk. A program tnyleges megoldst az egyetlen nyomgomb esemnykezel fggvnye fogja elvgezni. A vezrlelem esemnyeit az albbi Tulajdonsg ablakban lthatjuk.

26. bra

XVI. Grafikus alkalmazsok alapjai Kettt kattintva a nyomgombra, a keretrendszer belltja a nyomgomb Click esemnykezeljt, a forrskdba berja ennek a fggvnynek a kerett, s szmunkra nem marad ms htra, mint a valdi programkdot a fggvny trzsbe berni. A feladat ismertsge megengedi, hogy klnsebb magyarzat nlkl lssuk az esemnykezel fggvny trzst:
private void button1_Click(object sender, System.EventArgs e) { double a1=Convert.ToDouble(a.Text); double b1=Convert.ToDouble(b.Text); double c1=Convert.ToDouble(c.Text); double m1,m2; double d=b1*b1-4*a1*c1; // diszkriminns if (d<0) megoldas.Text="Nincs megolds, a diszkriminns negatv."; else { m1=(-b1+Math.Sqrt(d))/2*a1; m2=(-b1-Math.Sqrt(d))/2*a1; megoldas.Text=String.Format("A megolds x1={0} s x2={1}",m1,m2); } }

A programot futtatva, miutn berjuk a megfelel egytthatkat, az albbi formban kapjuk meg az eredmnyt. (Termszetesen tovbbi finomts rfrne erre a programra, de ennek elvgzst a kedves Olvasra bzom.)

27. bra

XVI. Grafikus alkalmazsok alapjai

XVI.2. Webes alkalmazsok alapjai


Napjainkban az internetes elrhetsg, rendelkezsre lls mr-mr szinte alapkvetelmny. Ennek a felhasznli ignynek a kielgtsre a keretrendszer lehetsget ad Web alap alkalmazsok ksztsre. Az ilyen jelleg alkalmazs ksztsnek alapfelttele az, hogy egy web kiszolgl elrshez megfelel jogosultsggal rendelkezznk. Ez a gyakorlatban az albbiakat jelenti: Azon a gpen ahol fejleszteni szeretnnk, elszr fel kell installlni az Internet Information Service (IIS) szolgltatst. Fel kell installlni a Visual Studio.NET alkalmazst. Ez ltrehoz kt felhasznli csoportot a szmtgpen, Debugger Users s VS Developers nvvel. Azokat a fejlesztket rakjuk bele ezekbe a csoportokba, amelyektl ilyen alkalmazsok fejlesztst vrjuk. (A Debugger Users csoportba minden fejlesztt bele kell rakni, klnben az opercis rendszer a nyomkvetsi mdban fordtott llomnyt nem engedi a keretrendszerbl futtatni!) Ha a fenti felttelek megvannak, akkor ASP.NET Web Application sablont vlasztva kszthetnk webes alkalmazst. Ezek alapjn ksztsnk egy webmasodfok projektet a fejlesztkrnyezetben, ahogyan az a kvetkez kpen ltszik, az elz masodfok projekt mellett elhelyezve. (A keretrendszer Solution fogalma tbb projektet enged egy keretbe foglalni, hiszen gyakran elfordul, hogy egy feladatmegoldst nem egy projekttel clszer megadni. Pldnk esetben nincs errl sz.)

28. bra

XVI. Grafikus alkalmazsok alapjai Miutn megadtuk a nevet, elkszl a kvetkez res weboldal. A ltrehozott Webform1.aspx az res HTML oldal (ezrt is van HTML nzete) s a htterben meghzd programfjl (Webform1.aspx.cs). Lthat, hogy a Toolbox ablakban a korbbi Windows Forms felirat helyett Web Forms olvashat, mutatva, hogy ezek a vezrlk web alap alkalmazsokhoz hasznlhatak. A Tulajdonsg ablak egyetlen objektuma a DOCUMENT objektum lesz, ami termszetesen magnak a HTML dokumentumnak felel meg. Ezek tulajdonsgrtkeit mdosthatjuk, pldul a Title mez rtkt, megadva ezzel a weboldal cmkjt, vagy a bgColor paramterrel belltva a kvnt httrsznt. A kapott kperny a kvetkez alak lesz:

29. bra

A Windows Form megoldshoz hasonlan ksztsk el a msodfok egyenlet megoldst ebben a krnyezetben is. Ehhez els lpsknt alaktsuk ki a programunk fellett az elz pldhoz hasonlan, majd a nyomgomb esemnykezel fggvnyt definiljuk.

XVI. Grafikus alkalmazsok alapjai A kapott forrskd (Webform1.aspx.cs) a kvetkez lesz:


using using using using using using using using using using System; System.Collections; System.ComponentModel; System.Data; System.Drawing; System.Web; System.Web.SessionState; System.Web.UI; System.Web.UI.WebControls; System.Web.UI.HtmlControls;

namespace webmasodfok { /// <summary> /// Summary description for WebForm1. /// </summary> public class WebForm1 : System.Web.UI.Page { protected System.Web.UI.WebControls.Label Label1; protected System.Web.UI.WebControls.Label Label2; protected System.Web.UI.WebControls.Label Label3; protected System.Web.UI.WebControls.Label Label4; protected System.Web.UI.WebControls.TextBox a; protected System.Web.UI.WebControls.TextBox b; protected System.Web.UI.WebControls.TextBox c; protected System.Web.UI.WebControls.Label megoldas; protected System.Web.UI.WebControls.Button Button1; private void Page_Load(object sender, System.EventArgs e) { // Put user code to initialize the page here } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); }

XVI. Grafikus alkalmazsok alapjai


/// /// /// /// <summary> Required method for Designer support - do not modify the contents of this method with the code editor. </summary>

private void InitializeComponent() { this.Button1.Click += new System.EventHandler(this.Button1_Click); this.Load += new System.EventHandler(this.Page_Load); } #endregion private void Button1_Click(object sender, System.EventArgs e) { double a1=Convert.ToDouble(a.Text); double b1=Convert.ToDouble(b.Text); double c1=Convert.ToDouble(c.Text); double m1,m2; double d=b1*b1-4*a1*c1; // diszkriminns if (d<0) megoldas.Text="Nincs megolds, a diszkriminns negatv."; else { m1=(-b1+Math.Sqrt(d))/2*a1; m2=(-b1-Math.Sqrt(d))/2*a1; megoldas.Text=String.Format("A megolds x1={0} s x2={1}",m1,m2); } } } }

A program fordtsa s futtatsa utn a 30. brn lthat Internet Explorer bngszben fut alkalmazst kapjuk, vagyis a clunkat elrtk. Ebben a fejezetben kitekintsknt csak a legfontosabb krnyezeti belltsokrl, fogalmakrl tudtunk szlni. A grafikus alkalmazsok lehetsgeit, a segtsgnkre lv grafikus vezrlelemek tulajdonsgait, webes, mobil s/vagy adatbzis kapcsolattal rendelkez alkalmazsok ksztst egy kvetkez ktet keretben szeretnnk megmutatni.

XVI. Grafikus alkalmazsok alapjai

30. bra

XVI.3. Feladatok
1. Mi a feladata a grafikus alkalmazs Main fggvnynek? 2. Mi a klnbsg a Windows s az ASP.NET alkalmazs kztt? 3. Milyen feltteleknek kell teljeslni ahhoz, hogy ASP.NET alkalmazst tudjunk kszteni? 4. Ksztsen alkalmazst, amely egy tglatest 3 oldalt beolvasva meghatrozza a trfogatt s felsznt! (Hasznljon cmkket s szvegmezket!) 5. Ksztse el az elz feladatot webes alkalmazsknt is.

Irodalomjegyzk
1. 2. 3. 4. 5. 6. 7. 8. 9. Brian W. Kernigham, Dennis M. Ritchie : A C programozsi nyelv Mszaki Knyvkiad, Budapest 1985, 1988 Bjarne Stroustrup: C++ programming language AT&T Bell Lab, 1986 Tom Archer : Inside C# MS Press, 2001 Microsoft C# language specifications MS Press, 2001 John Sharp, Jon Jagger: Microsoft Visual C#.NET MS Press, 2002 Ills Zoltn: A C++ programozsi nyelv ELTE IK, Mikrolgia jegyzet, 1995- David S.Platt: Bemutatkozik a Microsoft.NET Szak Kiad, 2001 Ills Zoltn: A C# programozsi nyelv s krnyezete Informatika a felsoktatsban 2002, Debrecen David Chappell: Understanding .NET Addison-Wesley, 2002

190

A Jedlik Oktatsi Stdi informatikai knyvei:


1212 Budapest, Tncsics M. u. 92 Tel/fax: 276-5335 Internet: www.jos.hu E-mail: jos@jos.hu Farkas Csaba: Bevezets a Windows s Office XP hasznlatba, ISBN: 963 00 8822 3 A Bevezets a Windows s Office XP hasznlatba c. knyv olvasja nemcsak megismerheti az Office csomag szolgltatsait, hanem a knyv didaktikus felptse s szmtalan pldja, feladata alapjn el is sajtthatja, be is gyakorolhatja annak hasznlatt. Kvnjuk, hogy Olvasnk hasznos tagja legyen az alkalmazk tbornak, s sikeresen feleljen meg az eurpai (ECDL) elvrsoknak Holczer Jzsef: Levelezs s csoportmunka Outlookkal, ISBN: 963 20 4374 X Az Outlook komplex informci-kezel szoftver, mely az elektronikus levelezsen tl lehetsget ad arra, hogy az egytt dolgoz emberek sszehangolhassk idbeosztsukat (naptr), kezelhessk egyms s kzs partnereik adatait (nvjegyalbumok). Megknnyti az rtekezletek sszehvst, a feladatok kiosztst s nyomon kvetst (feladatkezel), valamint a klnbz esemnyek naplzst, gy hatkonyabban s fleg egyszerbben szervezhet a mindennapos munka. Farkas Csaba: Windows XP s Office 2003 felhasznlknak, ISBN: 963 214 548 8 Knyvnk bevezeti az Olvast a Windows XP s az Office 2003 (Word, Excel, PowerPoint, Publisher, Outlook, Access, InfoPath, SharePoint, XML tmogats) hasznlatba, de tartalmazza az OKJ s ECDL vizsgkhoz szksges elmleti ismereteket is. Holczer-Telek: Csoportmunka Office 2003-mal, ISBN: 963 865 140 7 Az Office 2003-ban fleg az Outlook s a SharePoint tmogatja a kzs szmtgpes munkt. Ezek alapos ismertetsn tl knyvnkben kitrnk a tbbi Office komponensre, a digitlis alrsra, titkostsra, a BCM-re, s a PDA-k csoportmunkt segt felhasznlsra is.

XVI. Grafikus alkalmazsok alapjai

Fodor Gbor Antal: Eszttikus dokumentumok Worddel, ISBN 963 210 971 6 A knyv ttekinti a kiadvnyok ksztsnek vszzadok alatt kialakult sajtossgait, majd tpusonknt trgyalja azokat. Rszletesen megismerkedhetnk a hivatalos dokumentumok, a tanulmnyok, a marketing jelleg kiadvnyok ksztsnek szablyaival, de a szerz kitr a knyv s az jsg jelleg kiadvnyok ksztsre is. Eszkzknt mindvgig a Word szvegszerkesztt hasznlja. Szentirmai Rbert: Bevezets a Microsoft Office Project 2003 hasznlatba, ISBN: 963 86514 4 X A knyv rszletesen trgyalja a projectmenedzsment s nyomon kvets elmleti alapjait s megvalstst a Microsoft Project 2003 segtsgvel. Holczer Jzsef: Webszerkeszts egyszeren, ISBN: 963 86514 9 0 Knyvnk az nll webszerkesztsbe vezeti be az Olvast. Trgyalja a FrontPage 2003 hasznlatt, a HTML nyelv alapjait s a dinamikus elemek kezelst. Kezdknek, kzphaladknak s rettsgizknek egyarnt ajnljuk. Farkas Csaba Szab Marcell: A programozs alapjai Visual Basicben, ISBN 963 214 293 4 Knyvnkben szeretnnk egyfell az Olvast bevezetni programozs vilgba, msfell egy olyan hatkony programozsi nyelvet bemutatni, mellyel knnyedn tud j programokat kszteni (VB 6), automatizlhatja a Windows folyamatait (VB Script) s j funkcikkal bvtheti az Office programcsomagot (VB makrk). Figyelembe vettk az emelt szint rettsgi vonatkoz kvetelmnyeit is. Farkas Csaba: Programozsi ismeretek halad felhasznlknak, ISBN: 963 86514 2 3 Knyvnkbl az emelt szint rettsgire kszlk megismerkedhetnek az elvrt webszerkesztsi, SQL s programozsi ismeretekkel, illetve a VB.NET-tel. Bdy Bence: Az SQL pldkon keresztl, ISBN: 963 210 860 4 Az SQL megismersnek leghatkonyabb eszkze kidolgozott mintapldk tanulmnyozsa. A knyv ezrt 30 feladatcsoportba rendezve tbb mint 80

fokozatosan nehezed, valsgh feladat kidolgozsval vezeti be az Olvast az SQL alkalmazsba. Egy-egy feladat megoldsra tbb megoldst is kzl, s az nll gyakorls rdekben a fejezetek s a knyv vgn kzel 100, tovbbi feladatot is tallhatunk. Holczer-Benkovics: Windows Server 2003 hlzatok kezelse, ISBN: 963 214 693 X A knyv a Windows Server 2003 alap hlzatok zemeltetsbe (hardver ismeretek, TCP/IP protokoll, Windows Server 2003, ISA Server 2000, Exchange Server 2003 zemeltetse, teleptsi ismeretek) tanknyvszeren vezeti be a kezd rendszergazdkat.

XVI. Grafikus alkalmazsok alapjai

XVI. Grafikus alkalmazsok alapjai

XVI. Grafikus alkalmazsok alapjai

XVI. Grafikus alkalmazsok alapjai

XVI. Grafikus alkalmazsok alapjai

XVI. Grafikus alkalmazsok alapjai

You might also like