Reiter István - C# (2009, 350 oldal)

Embed Size (px)

Citation preview

Forrs: http://www.doksi.hu

Reiter Istvn

C#2009, 0.91 verzi

Forrs: http://www.doksi.hu

2

Tartalomjegyzk1. Bevezet .......8 1.1. A jegyzet jellsei8 1.2. Jogi felttelek8 2. Microsoft .NET Framework...9 2.1. A .NET platform.9 2.1.1. MSIL/CIL...9 2.1.2. Fordts/futtats.9 2.1.3. BCL. 10 2.2. A C# programozsi nyelv.10 2.3. Alternatv megoldsok10 2.3.1. SSCLI10 2.3.2. Mono10 2.3.3. DotGNU..10 3. Fejleszt i krnyezetek..12 3.1. Microsoft Visual Studio12 3.2. SharpDevelop.13 3.3. MonoDevelop..14 4. Hello C#!..16 4.1. A C# szintaktikja..17 4.1.1. Kulcsszavak.17 4.1.2. Megjegyzsek..18 4.2. Nvterek...18 5. Vltozk...20 5.1. Tpusok.20 5.2. Loklis vltozk.21 5.3. Referencia- s rtktpusok21 5.4. Boxing s Unboxing.22 5.5. Konstansok.23 5.6. A felsorolt tpus..23 5.7. Null tpusok..24 6. Opertorok..25 6.1. Opertor precedencia...25 6.2. rtkad opertor..25 6.3. Matematikai opertorok26 6.4. Relcis opertorok..26 6.5. Logikai/feltteles opertorok..27 6.6. Bit opertorok.30 6.7. Rvid forma.32 6.8. Egyb opertorok..33 7. Vezrlsi szerkezetek...34 7.1. Szekvencia...34 7.2. Elgazs34 7.3. Ciklus.36 7.3.1. Yield.39 7.4. Gyakorl feladatok.39 8. Tmbk.41 8.1. Tbbdimenzis tmbk42

Forrs: http://www.doksi.hu

3 8.2. ArrayList...44 8.3. Gyakorl feladatok.46 9. Stringek47 9.1. Metdusok47 9.2. StringBuilder49 10. Tpuskonverzik.51 10.1. Ellen rztt konverzik51 10.2. Is s as.52 10.3. Karakterkonverzik..52 11. Gyakorl feladatok I...54 12. Objektum-orientlt programozs elmlet.54 12.1. UML..56 12.2. Osztly.56 12.3. Adattag s metdus.56 12.4. Lthatsg..57 12.5. Egysgbezrs..57 12.6. rkl ds...58 13. Osztlyok..58 13.1. Konstruktorok.......59 13.2. Adattagok62 13.3. Lthatsgi mdostk...62 13.4. Parcilis osztlyok...62 13.5. Begyazott osztlyok..63 13.6. Objektum inicializlk.64 13.7. Destruktorok..64 14. Metdusok67 14.1. Paramterek...68 14.2. Parancssori paramterek...71 14.3. Kiterjesztett metdusok..71 14.3.1. Gyakorl feladatok72 15. Statikus tagok.73 15.1. Statikus adattagok73 15.2. Statikus metdusok.73 15.3. Statikus tulajdonsgok...74 15.4. Statikus konstruktor74 15.5. Statikus osztlyok74 15.6. Gyakorl feladatok...75 16. Tulajdonsgok76 17. Indexel k..79 18. Gyakorl feladatok II.80 19. rkl ds.81 19.1. Konstruktorok...82 19.2. Polimorfizmus...82 19.3. Virtulis metdusok.83 19.4. Lezrt osztlyok85 19.5. Absztrakt osztlyok.86 20. Interfszek88 20.1. Explicit interfszimplementci...90 20.2. Virtulis tagok91 20.3. Gyakorlati plda 1.92

Forrs: http://www.doksi.hu

4 20.4. Gyakorlati plda 2.94 21. Opertor tlterhels...96 21.1. Egyenl sg opertorok..97 21.2. Relcis opertorok.98 21.3. Konverzis opertorok98 21.4. Kompatibilits ms nyelvekkel.99 21.5. Gyakorlati plda..100 22. Struktrk...102 23. Kivtelkezels103 23.1. Kivtel hierarchia104 23.2. Sajt kivtel ksztse...105 23.3. Kivtel tovbbadsa..105 23.4. Finally blokk.105 24. Generikusok..107 24.1. Generikus metdusok...107 24.2. Generikus osztlyok..108 24.3. Generikus megszortsok110 24.4. rkl ds.111 24.5. Statikus tagok.....111 24.6. Generikus gy jtemnyek.112 24.7. Generikus interfszek...113 25. Delegate ek..114 25.1. Tbbszrs delegate ek.115 25.2. Paramter s visszatrsi rtk.116 25.3. Nvtelen metdusok..117 26. Esemnyek.118 26.1. Gyakorl feladatok.119 27. Lambda kifejezsek.120 27.1. Generikus kifejezsek...120 27.2. Kifejezsfk..121 27.3. Lambda kifejezsek vltozinak hatkre..121 27.4. Esemnykezel k....122 28. Attribtumok..123 29. Az el fordt..125 30. Unsafe kd.126 30.1. Fix objektumok...127 31. Tbbszl alkalmazsok...128 31.1. Application Domain ek130 31.2. Szlak131 31.3. Aszinkron delegate ek131 31.4. Szlak ltrehozsa.135 31.5. Foreground s background szlak...136 31.6. Szinkronizci.136 32. Reflection142 33. llomnykezels..144 33.1. Olvass/rs file bl/file ba..144 33.2. Knyvtrstruktra kezelse147 33.3. In memory streamek..149 34. Grafikus fellet alkalmazsok ksztse.151 34.1. Windows Forms Bevezet ...151

Forrs: http://www.doksi.hu

5 34.2. Windows Presentation Foundation - Bevezet .....153 35. Windows Forms...156 36. Windows Forms Vezrl k..........................................160 36.1. Form.........................................160 36.2. Button.......................................161 36.3. Label.........................................162 36.4. TextBox....162 36.5. ListBox..164 36.6. CheckBox.167 36.7. CheckedListBox.168 36.8. RadioButton....169 36.9. ComboBox...171 36.10. TreeView....172 36.11. DomainUpDown...175 36.12. NumericUpDown..176 36.13. ProgressBar..176 36.14. TrackBar.177 36.15. PictureBox.177 36.16. RichTextBox.178 36.17. DateTimePicker....181 36.18. MenuStrip..183 36.19. ltalnos prbeszdablakok186 36.20. TabControl.192 36.21. ContextMenuStrip192 36.22. Gyakorl feladatok..192 37. Windows Forms Komponensek....193 37.1. Timer..193 37.2. ErrorProvider...193 37.3. BackGroundWorker...194 37.4. Process.196 37.5. ImageList..196 37.6. Gyakorl feladatok.197 38. Windows Forms - j vezrl k ltrehozsa....198 38.1. Szrmaztats...198 38.2. UserControl -ok..200 39. Rajzols: GDI+..203 39.1. Kpek kezelse...205 40. Drag and Drop...206 41. Windows Presentation Foundation.208 41.1. A WPF Architektra...209 41.2. A WPF osztlyhierarchija...209 41.3. XAML.210 41.3.1. Fordts211 41.3.2. Logikai- s Vizulis fa..211 41.3.3. Felpts...212 42. WPF Esemnyek s tulajdonsgok215 43. WPF Vezrl k elrendezse221 43.1. StackPanel...221 43.2. WrapPanel223 43.3. DockPanel224

Forrs: http://www.doksi.hu

6 43.4. Canvas..225 43.5. UniformGrid.226 43.6. Grid.227 44. WPF Vezrl k231 44.1. Megjelens s szvegformzs.231 44.2. Vezrl k....236 44.2.1. TextBlock s Label.236 44.2.2. CheckBox s Radiobutton...238 44.2.3. TextBox, PasswordBox s RichTextBox.240 44.2.4. ProgressBar, ScrollBar s Slider...243 44.2.5. ComboBox s ListBox..247 44.2.6. TreeView...250 44.2.7. Menu..251 44.2.8. Expander s TabControl..252 44.2.9. Image s MediaElement...254 45. Er forrsok...256 45.1. Assembly resource256 45.2. Object resource..256 46. Stlusok..260 46.1. Triggerek262 46.1.1. Trigger...262 46.1.2. MultiTrigger..263 46.1.3. EventTrigger263 47. Sablonok265 48. Commanding....267 49. Animcik s transzformcik272 49.1. Transzformcik.272 49.1.1. MatrixTransform.273 49.1.2. RotateTransform.277 49.1.3. TranslateTransform...279 49.1.4. ScaleTransform..280 49.1.5. SkewTransform...282 49.1.6. TransformGroup.283 49.2. Animcik.285 49.2.1. From-to-by animcik...286 49.2.2. Key Frame animcik290 49.2.3. Spline animcik291 49.2.4. Animcik s transzformcik...292 50. Vezrl k ksztse.294 50.1. UserControl.295 51. ADO.NET.305 51.1. MS SQL Server 2005/2008 Express...305 52. SQL Alapok...307 52.1. Adatbzis ltrehozsa...307 52.2. Tblk ltrehozsa.308 52.3. Adatok beszrsa tblba...309 52.4. Oszlop trlse tblbl.309 52.5. Kivlaszts...309 52.6. Sz rs...310 52.7. Rendezs..311

Forrs: http://www.doksi.hu

7 52.8. Adatok mdostsa312 52.9. Relcik312 52.10. Join.314 53. Kapcsolds az adatbzishoz.314 53.1. Kapcsolds Access adatbzishoz..315 53.2. Kapcsolds Oracle adatbzishoz....316 54. Kapcsolat nkli rteg...317 54.1. DataTable..317 54.2. DataGridView...321 54.3. DataView...329 54.4. DataSet..330 54.4.1. Relcik tblk kztt331 54.4.2. Tpusos DataSet -ek...333 55. Adatbzis adatainak lekrdezse s mdostsa..335 55.1. Connected s Disconnected kzti kapcsolat.. ..336 56. XML.342 56.1. XML file ok kezelse343 56.2. XML DOM..346 56.3. XML szerializci347 56.4. XML s a kapcsolat nlkli rteg. .349

Forrs: http://www.doksi.hu

8

1. BevezetNapjainkban egyre nagyobb teret nyer a .NET Framework s egyik f nyelve a C#. Ez a jegyzet abbl a clbl szletett, hogy megismertesse az olvasval ezt a nagyszer technolgit. A jegyzet a C# 2.0 s 3.0 verzijval is foglalkozik, ha nincs kln feltntetve akkor az adott nyelvi elem gond nlkl hasznlhat a korbbi verziban. Nhny fejezet felttelez olyan tudst amely alapjt egy ks bbi fejezet kpezi, ezrt ne essen ktsgbe a kedves olvas, ha valamit nem rt, egyszer en olvasson tovbb s trjen vissza a krdses fejezethez, ha rtallt a vlaszra. Brmilyen krst, javaslatot illetve hibajavtst szvesen vrok a [email protected] email cmre.

1.1 A jegyzet jellseiForrskd: szrke alapon, kerettel Megjegyzs: fehr alap, kerettel

1.2 Jogi felttelek

A jegyzet teljes tartalma a Creative Commons Nevezd meg!-Ne add el! 2.5 Magyarorszg liszensze al tartozik. Szabadon mdosthat s terjeszthet , a forrs feltntetsvel. A jegyzet ingyenes, mindennem rtkestsi ksrlet tiltott s a szerz beleegyezse nlkl trtnik. A mindenkori legfrissebb vltozat letlthet a kvetkez oldalakrl: http://people.inf.elte.hu/reiter_i/sharp.html http://devportal.hu/groups/fejlesztk/media/p/1122.aspx

A kvetkez frissts id pontja: 2009. prilis 12.

Forrs: http://www.doksi.hu

9

2. Microsoft .NET FrameworkA kilencvenes vek kzepn a Sun MicroSystems kiadta a Java platform els nyilvnos vltozatt. Az addigi programnyelvek/platformok klnbz okokbl nem tudtk felvenni a Java val a versenyt, gy szmtalan fejleszt dnttt gy, hogy a knyelmesebb s sokoldalbb Java t vlasztja. Rszben a piac visszaszerzsnek rdekben a Microsoft a kilencvenes vek vgn elindtotta a Next Generation Windows Services fed nev projektet, amelyb l aztn megszletett a .NET.

2.1 A .NET platformMaga a .NET platform a Microsoft, a Hewlett Packard, az Intel s msok kzrem kdsvel megfogalmazott CLI (Common Language Infrastructure) egy implementcija. A CLI egy szablyrendszer, amely maga is tbb rszre oszlik: A CTS (Common Type System) az adatok kezelst, a memriban val megjelenst, az egymssal val interakcit, stb. rja le. A CLS (Common Language Specification) a CLI kompatibilis nyelvekkel kapcsolatos elvrsokat tartalmazza. A VES (Virtual Execution System) a futsi krnyezetet specifiklja, nevezik CLR -nek (Common Language Runtime) is. A .NET nem egy programozsi nyelv, hanem egy krnyezet. Gyakorlatilag brmilyen programozsi nyelvnek lehet .NET implementcija. Jelenleg kb. 50 nyelvnek ltezik hivatalosan .NET megfelel je, nem beszlve a szmtalan hobbifejlesztsr l.

2.1.1 MSIL/CILA hagyomnyos programnyelveken mint pl. a C++ - megrt programok n. natv kdra fordulnak le, vagyis a processzor szmra kis tlzssal azonnal rtelmezhet ek. Ezeknek a nyelveknek az el nye a htrnya is egyben. Br gyorsak, de rengeteg hibalehet sg rejt zik a felgyelet nlkli (unmanaged) vgrehajtsban. A .NET (akrcsak a Java) ms ton jr, a fordt egy kztes nyelvre (Intermediate Language) fordtja le a forrskdot. Ez a nyelv a .NET vilgban az MSIL illetve a szabvnyosts utn CIL (Microsoft/Common IL) klnbsg csak az elnevezsben van.

2.1.2 Fordts/futtatsA natv programok n. gpi kdra fordulnak le, mg a .NET forrskdokbl egy CIL nyelv futtathat llomny keletkezik. Ez a kd a felteleptett .NET Framework nek szl utastsokat tartalmaz. Amikor futtatjuk ezeket az llomnyokat el szr az n. JIT (justintime) fordt veszi kezelsbe s lefordtja ket gpi kdra, amit a processzor mr kpes kezelni. Amikor el szr lefordtjuk a programunkat akkor egy n. Assembly (vagy szerelvny) keletkezik. Ez tartalmazza a felhasznlt illetve megvalstott tpusok adatait (ez az n. Metadata) amelyeket a futtat krnyezet fel tud hasznlni a futtatshoz (az osztlyok neve, metdusai, stb). Egy Assembly egy vagy tbb file bl is llhat.

Forrs: http://www.doksi.hu

10

2.1.3 BCLA .NET Framework teleptsvel a szmtgpre kerl tbbek kzt a BCL (Base Class Library), ami az alapvet feladatok (file olvass/ rs, adatbzis kezels, adatszerkezetek, stb) elvgzshez szksges eszkzket tartalmazza. Az sszes tbbi knyvtr (ADO.NET, WCF, stb) ezekre a knyvtrakra pl.

2.2 A C# programozsi nyelvA C# (ejtsd: Sz-srp) a Visual Basic mellett a .NET f programozsi nyelve. 1999 ben Anders Hejlsberg vezetsvel kezdtk meg a fejlesztst. A C# tisztn objektumorientlt, tpusbiztos, ltalnos felhasznls nyelv. A tervezsnl a lehet legnagyobb produktivits elrst tartottk szem el tt. A nyelv elmletileg platformfggetlen (ltezik Linux s Mac fordt is), de napjainkban a legnagyobb hatkonysgot a Microsoft implementcija biztostja.

2.3 Alternatv megoldsokA Microsoft .NET Framework jelen pillanatban csak s kizrlag Microsoft Windows opercis rendszerek alatt elrhet . Ugyanakkor a szabvnyosts utn a CLI specifikci nyilvnos s brki szmra elrhet lett, ezen ismeretek birtokban pedig tbb fggetlen csapat vagy cg is ltrehozta a sajt CLI implementcijt, br eddig mg nem sikerlt teljes mrtkben reproduklni az eredetit. Ezt a clt nehezti, hogy a Microsoft id kzben szmos a specifikciban nem szerepl vltoztatst vgzett a keretrendszeren.

2.3.1 SSCLIAz SSCLI (Shared Source Common Language Infrastructure) vagy korbbi nevn Rotor a Microsoft ltal fejlesztett nylt forrs, keresztplatformos vltozata a .NET Frameworknek (teht nem az eredeti lebuttott vltozata). Az SSCLI Windows, FreeBSD s Mac OSX rendszereken fut. Az SSCLI t kimondottan tanulsi clra ksztette a Microsoft, ezrt a liszensze engedlyez mindenfajta mdostst, egyedl a piaci rtkestst tiltja meg. Ez a rendszer nem szolgltatja az eredeti keretrendszer teljes funkcionalitst, jelen pillanatban valamivel a .NET 2.0 mgtt jr. Az SSCLI project jelen pillanatban megsz nni vagy legalbbis id legesen lellni ltszik. Ett l fggetlenl a forrskd s a hozz tartoz dokumentcik rendelkezsre llnak, letlthet ek a kvetkez webhelyr l: http://www.microsoft.com/downloads/details.aspx?FamilyId=8C09FD61-3F264555-AE17-3121B4F51D4D&displaylang=en

2.3.2 MonoA Mono projekt szl atyja Miguel de Icaza 2000 ben kezdte meg a fejlesztst s egy vvel ks bb mutatta be ez els kezdetleges C# fordtt. A Ximian (amelyet Icaza s Nat Friedman alaptott) felkarolta az tletet s 2001 jliusban hivatalosan

Forrs: http://www.doksi.hu

11 is elkezd dtt a Mono fejlesztse. 2003 ban a Novell felvsrolta a Ximian t, az 1.0 verzi mr Novell termkknt kszlt el, egy vvel ks bb. A legutols verzi (2.0.1) amely 2008 oktberben ltott napvilgot. Ez a vltozat mr a teljes .NET 2.0 t magba foglalja, illetve a C# 3.0 kpessgeit is rszlegesen tmogatja (pl. van LINQ to XML illetve LINQ to Objects). Ugyanez a verzi tartalmazza a Novell SilverLight alternatvjt, amit MoonLight ra kereszteltek, ennek fejlesztsben a Novell segtsgre van a Microsoft is. A Mono sajt fejleszt eszkzzel is rendelkezik a MonoDeveloppal. Ezzel a vltozattal prhuzamosan fejleszts alatt ll a .NET 3.0 t is tmogat rendszer, a project kdneve Olive (http://www.mono-project.com/Olive). A Mono Windows, Linux, UNIX, BSD, Mac OSX s Solaris rendszereken elrhet . Napjainkban a Mono mutatja a leggretesebb fejl dst, mint a Microsoft .NET jv beli ellenfele illetve keresztplatformos trsa. A Mono emblmja egy majmot brzol, a sz ugyanis spanyolul majmot jelent. A Mono hivatalos oldala: http://www.mono-project.com/Main_Page

2.3.3 DotGNUA DotGNU a GNU projekt rsze, amelynek clja egy ingyenes s nylt alternatvt nyjtani a Microsoft implementci helyett. Ez a projekt szemben a Mono val nem a Microsoft BCL el val kompatibilitst helyezi el trbe, hanem az eredeti szabvny pontos s tkletes implementcijnak a ltrehozst. A DotGNU sajt CLI megvalstsnak a Portable .NET nevet adta. A jegyzet rsnak idejn a projekt lellni ltszik. A DotGNU hivatalos oldala: http://www.gnu.org/software/dotgnu/

Forrs: http://www.doksi.hu

12

3. Fejleszt i krnyezetekEbben a fejezetben nhny IDE t (Integrated Development Environment), azaz Integrlt Fejleszt i Krnyezetet vizsgluk meg. Termszetesen ezek nlkl is lehetsges fejleszteni, azonban egy j fejleszt eszkz hinya jelent sen meggtolja a gyors s produktv programozst. Ugyanakkor a jegyzet els felben egy hagyomnyos szvegszerkeszt vel s a parancssorral is lehet gond nlkl haladni.

3.1 Microsoft Visual StudioValszn leg a legelterjedtebb IDE a .NET programozshoz. A Visual Studio termkcsald rsze az Express sorozat, amely teljesen ingyenes mindenki szmra, egy Express eszkzzel ksztett program el is adhat, anlkl, hogy brmifle liszenszet vsrolnnk. Ez a termkvonal nmileg kevesebb funkcionalitssal rendelkezik, mint nagyobb testvre, ugyanakkor kivlan alkalmas hobbifejlesztsre (de akr rendes kereskedelmi program ksztsre is). A jegyzet a grafikus fellet alkalmazsok ksztsnl Visual Studio t hasznl majd, ezrt rdemes tjkozdni az egyes fejleszt eszkzk klnbsgeir l. A kpen a Visual Studio 2008 fellete lthat:

Jobb oldalon fll a Solution Explorer lthat, ez a projektnk file jait tartalmazza. Alatta a Properties ablak, ez f knt a grafikus designer ablaknl hasznlhat, az egyes vezrl elemek tulajdonsgait (nv, szlessg, magasssg, stb) llthatjuk be. Vgl a legnagyobb terletet a kdszerkeszt ablak foglalja el.

Forrs: http://www.doksi.hu

13 A Visual Studio tartalmazza az n. IntelliSense rendszert, amely automatikusan felajnlja az elkezdett metdusok/vltozk/osztlyok/stb. nevnek kiegsztst. j projekt ltrehozshoz Kattintsunk a File menre, vlasszuk ki a New menpontot azon bell pedig a Projekt et (vagy hasznljuk a Ctrl+Shift+N billenty kombincit). Ha nem az lenne megnyitva, akkor kattintsunk a bal oldali listban a C# elemre. Grafikus fellet alkalmazs ksztshez vlasszuk ki a Windows Application vagy a WPF Application sablont. Konzolalkalmazs ksztshez (a jegyzet els rszben f knt ilyet runk majd) a Console Application sablonra lesz szksgnk. Miel tt lefordtjuk a programunkat, kivlaszthatjuk, hogy Debug vagy Release mdban fordtsunk, el bbi tartalmaz nhny plusz informcit a hibakeress el segtshez (gy egy kicsit lassabb), utbbi a mr ksz programot jelenti. Lefordtani a programot a Build menpont Build Solution parancsval (vagy az F6 gyorsbillenty vel) tudjuk, futtatni pedig a Debug men Start Debugging (vagy az F5 billenty lenyomsval illetve a kis zld hromszgre val kattintssal) parancsval. Ez utbbi automatikusan lefordtja a projektet, ha a legutols fordts utn megvltozott valamelyik file.

3.2 SharpDevelopA SharpDevelop egy nylt forrskd ingyenes alternatva Windows opercis rendszer alatti .NET fejlesztshez.

A legfrisebb verzit idn februrban adtk ki, ez mr tmogatja a C# 3.0 verzijt, valamint a Visual Basic.NET, Boo, IronPython s F# programozsi nyelveket is.

Forrs: http://www.doksi.hu

14 A SharpDevelop hivatalos oldala: http://www.sharpdevelop.com/OpenSource/SD/ rdekessg, hogy a fejleszt k egy knyvet is rtak a fejleszts menetr l s ez a knyv ingyenesen letlthet . Eredetileg a Wrox kiad oldalrl lehetett letlteni, de annak megsz nse utn tkerlt az Apress kiadhoz. Sajnos gy t nik, hogy az Apress nem kvnja nylvnossgra hozni a knyvet, de termszetesen az interneten brmit meg lehet tallni, gy a kvetkez webhelyr l ez is letlthet : http://www.mediafire.com/?thnognidwyj A knyv letltse nem szmt illeglis cselekmnynek!

3.3 MonoDevelopA MonoDevelop els sorban a Mono hoz kszlt nylt forrskd s ingyenes fejleszt eszkz. Eredetileg Linux oprcis rendszer al szntk, de van mr Windows, Mac OSX, OpenSolaris s FreeBSD alatt fut vltozata is.

A MonoDevelop a kvetkez programozsi nyelveket tmogatja: C#, Java, Visual Basic.NET, Nemerle, Boo, CIL, C, C++. A MD eredetileg a SharpDevelop bl szrmazott el, de a mai vltozatok mr kevss hasonltanak az sre. A MonoDevelop ot akrcsak a Mono t a Novell (is) fejleszti.

Forrs: http://www.doksi.hu

15 A MonoDevelop hivatalos oldala: http://www.monodevelop.com/ A MonoDevelop egyetlen nagy htult vel rendelkezik: Windows opercis rendszer al nem ltezik hozz telept szoftver, a felhasznlnak magnak kell lefordtania a forrskdot.

Forrs: http://www.doksi.hu

16

4. Hello C#!A hres-hrhedt Hello World! program els knt Dennis Ritchie s Brian Kerningham A C programozsi nyelv cm knyvben jelent meg, s azta szinte hagyomny, hogy egy programozsi nyelv bevezet jeknt ezt a programot mutatjk be. Semmi mst nem csinl, mint kirja a kperny re az dvzletet. Mi itt most nem a vilgot, hanem a C# nyelvet dvzljk, ezrt ennek megfelel en mdostsuk a forrskdot:using System; class HelloWorld { static public void Main() { Console.WriteLine("Hello C#!"); Console.ReadKey(); } }

Miel tt lefordtjuk tegynk pr lpst a parancssorbl val fordts el segtsre. Ahhoz, hogy gy is le tudjunk fordtani egy forrsfile t, vagy meg kell adnunk a fordtprogram teljes elrsi tjt (ez a mi esetnkben elg hossz) vagy a fordtprogram knyvtrt fel kell venni a PATH krnyezeti vltozba. Ez utbbihoz Vezrl pult/Rendszer -> Specilis fl/Krnyezeti vltozk. A rendszervltozk listjbl keressk ki a Path t s kattintsunk a Szerkeszts gombra. Most nyissuk meg a Sajtgpet, C meghajt, Windows mappa, azon bell Microsoft.NET/Framework. Nyissuk meg vagy a v2.0 vagy a v3.5.. kezdet mappt (attl fgg en, hogy C# 2.0 vagy 3.0 kell). Msoljuk ki a cmsorbl ezt a szp hossz elrst. Vissza a Path hoz. A vltoz rtke sorban navigljunk el a vgre, rjunk egy pontosvessz t (;) s illesszk be az elrsi utat. Mindent OK zunk le s ksz. Ha van megnyitva konzol vagy PowerShell azt indtsuk jra, utna rjuk be, hogy csc. Azt kell ltnunk, hogy Microsoft Visual C# 2008 Compiler Version 3.5 Itt az vszm s verzi vltozhat, ez a C# 3.0 zenete. Most mr fordthatunk a csc filenev.cs paranccsal (termszetesen a szveges file kiterjesztse .txt, gy nevezzk t mivel a C# forrskdot tartalmaz file -ok kiterjesztse .cs). Az els sor megmondja a fordtnak, hogy hasznlja a System nvteret. Ezutn ltrehozunk egy osztlyt, mivel a C# teljesen objektumorientlt ezrt utastst csakis osztlyon bell adhatunk. A HelloWorld osztlyon bell definilunk egy Main nev statikus fggvnyt, ami a programunk belpsi pontja lesz. Minden egyes C# program a Main fggvnnyel kezd dik, ezt mindenkppen ltre kell hoznunk. Vgl meghvjuk a Console osztlyban lv WriteLine() s ReadKey() fggvnyeket. El bbi kirja a kperny re a paramtert, utbbi vr egy billenty letst.

Forrs: http://www.doksi.hu

17 Ebben a bekezdsben szerepel nhny (sok) kifejezs ami ismeretlen lehet, a jegyzet ks bbi fejezeteiben mindenre fny derl majd.

4.1 A C# szintaktikjaAmikor egy programozsi nyelv szintaktikjrl beszlnk, akkor azokra a szablyokra gondolunk, amelyek megszabjk a forrskd felptst. Ez azrt fontos, mert az egyes fordtprogramok az ezekkel a szablyokkal ltrehozott kdot tudjk rtelmezni. A C# C-stlus szintaxissal rendelkezik (azaz a C programozsi nyelv szintaxishoz hasonlt), ez hrom fontos kittelt von maga utn: - Az egyes utastsok vgn pontosvessz (;) ll - A kis- s nagybet k klnbz jelent sggel brnak, azaz a program s Program azonostk klnbznek. Ha a fenti kdban Console.WriteLine() helyett console.writeline() t rnnk a program nem fordulna le. - A program egysgeit (osztlyok, metdusok, stb.) n. blokkokkal jelljk ki, a kapcsos zrjelek ({, }) segtsgvel.

4.1.1 KulcsszavakSzinte minden programnyelv definil kulcsszavakat, amelyek specilis jelent sggel brnak a fordt szmra. Ezeket az azonostkat a sajt meghatrozott jelentskn kv l nem lehet msra hasznlni, ellenkez esetben a fordt hibt jelez. Vegynk pldul egy vltozt, aminek az int nevet akarjuk adni. Az int egy beptett tpus neve is, azaz kulcssz, ezrt nem fog lefordulni a program:int int; //hiba

A legtbb fejleszt eszkz megsznezi a kulcsszavakat (is), ezrt knny elkerlni a fenti hibt. A C# 77 darab kulcsszt ismer: 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 readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while

Forrs: http://www.doksi.hu

18 Ezeken kv l ltezik mg 23 darab azonost, amelyeket a nyelv nem tart fenn specilis hasznlatra, de klnleges jelentssel brnak. Amennyiben lehetsges kerljk a hasznlatukat hagyomnyos vltozk, metdusok, osztlyok ltrehozsnl: add ascending by descending equals from get global group in into join let on orderby partial remove var select where set yield value

Nhnyuk a krnyezett l fgg en ms-ms jelentssel is brhat, a megfelel fejezet b vebb informcit ad majd ezekr l az esetekr l.

4.1.2 MegjegyzsekA forrskdba megjegyzseket tehetnk. Ezzel egyrszt zeneteket hagyhatunk (pl. egy metdus lersa) magunknak, vagy a tbbi fejleszt nek, msrszt a kommentek segtsgvel dokumentcit tudunk generlni, ami szintn az els clt szolglja csak ppen lvezhet bb formban. Megjegyzseket a kvetkez kppen hagyhatunk:using System; class HelloWorld { static public void Main() { Console.WriteLine("Hello C#"); // Ez egy egysoros komment Console.ReadKey();/* Ez egy tbbsoros komment */

} }

Az egysoros komment a sajt sora legvgig tart, mg a tbbsoros a kt /* on bell rvnyes. Utbiakat nem lehet egymsba gyazni:/* /* */

*/

Ez a kd nem fordul le. A kommenteket a fordt nem veszi figyelembe, tulajdonkppen a fordtprogram els lpse, hogy a forrskdbl eltvolt minden megjegyzst.

4.2 NvterekA .NET Framework osztlyknyvtrai szerny becsls szerint is legalbb tzezer nevet, azonostt tartalmaznak. Ilyen nagysgrenddel elkerlhetetlen, hogy a nevek ismtl djenek. Ekkor egyrszt nehz eligazodni kztk, msrszt a fordt is

Forrs: http://www.doksi.hu

19 megzavarodhat. Ennek a problmnak a kikszblsre hoztk ltre a nvterek fogalmt. Egy nvtr tulajdonkppen egy virtulis doboz, amelyben a logikailag sszefgg osztlyok, metdusok, stb vannak. Nylvn knyebb megtallni az adatbziskezelshez szksges osztlyokat, ha valamilyen kifejez nev nvtrtben vannak (System.Data). Nvteret magunk is definilhatunk, a namespace kulcsszval:namespace MyNameSpace { }

Ezutn a nvterre vagy a program elejn a using al, vagy az azonost el rt teljes elrssel hivatkozhatunk:using MyNameSpace;//vagy

MyNameSpace.Valami

A jegyzet els felben f leg a System nvteret fogjuk hasznlni, ahol ms is kell ott jelezni fogom.

Forrs: http://www.doksi.hu

20

5. VltozkAmikor programot runk, akkor szksg lehet trolkra, ahov az adatainkat ideiglenesen eltroljuk. Ezeket a trolkat vltozknak nevezzk. A vltozk a memria egy(vagy tbb) celljra hivatkoz lerk. Egy vltozt a kvetkez mdon hozhatunk ltre C# nyelven: Tpus vltoznv; A vltoznv els karaktere csak bet vagy alulvons jel (_) lehet, a tbbi karakter szm is. Lehet leg kerljk az kezetes karakterek hasznlatt.

5.1 TpusokA C# er sen (statikusan) tpusos nyelv, ami azt jelenti, hogy minden egyes vltoz tpusnak ismertnek kell lennie fordtsi id ben. A tpus hatrozza meg, hogy egy vltoz milyen rtkeket tartalmazhat illetve mekkora helyet foglal a memriban. A kvetkez tblzat a C# beptett tpusait tartalmazza, mellettk ott a .NET megfelel jk, a mretk s egy rvid lers: C# tpus byte char bool sbyte short ushort int uint float double decimal long ulong string object .NET tpus Mret (byte) System.Byte 1 System.Char 1 System.Boolean 1 System.SByte System.Int16 System.Uint16 System.Int32 System.Uint32 System.Single System.Double System.Decimal System.Int64 System.Uint64 System.String System.Object 1 2 2 4 4 4 8 8 8 8 NA NA Lers El jel nlkli 8 bites egsz szm (0..255) Egy Unicode karakter Logikai tpus, rtke igaz(1) vagy hamis(0) El jeles 8 bites egsz szm (-128..127) El jeles 16 bites egsz szm (32768..32767 El jel nlkli 16 bites egsz szm (0..65535) El jeles 32 bites egsz szm ( 2147483647.. 2147483647). El jel nlli 32 bites egsz szm (0..4294967295) Egyszeres pontossg lebeg pontos szm Ktszeres pontossg lebeg pontos szm Fix pontossg 28+1 jegy szm El jeles 64 bites egsz szm El jel nlkli 64 bites egsz szm Unicode karakterek szekvencija Minden ms tpus se

A forrskdban teljesen mindegy, hogy a rendes vagy a .NET nven hivatkozunk egy tpusra.

Forrs: http://www.doksi.hu

21 Alaktsuk t a Hello C# programot gy, hogy a kirand szveget egy vltozba tesszk:using System; class HelloWorld { static public void Main() {//string tpusu vltoz deklarcija, benne a kirand szveg

string message = "Hello C#"; Console.WriteLine(message); Console.ReadKey(); } }

A C# 3.0 lehet v teszi, hogy egy metdus hatkrben deklarlt vltoz tpusnak meghatrozst a fordtra bzzuk. Ezt az akcit a var szval kivitelezhetjk. Ez termszetesen nem jelenti azt, hogy gy hasznlhatjuk a nyelvet, mint egy tpustalan krnyezetet, abban a pillanatban, hogy rtket rendeltnk a vltozhoz (ezt azonnal meg kell tennnk), az gy fog viselkedni mint az ekvivalens tpus. A ilyen vltozk tpusa nem vltoztathat meg, de a megfelel tpuskonverzik vgrehajthatak.int x = 10; // int tpus vltoz var z = 10; // int tpus vltoz z = "string"; // fordtsi hiba var w; //fordtsi hiba

Nhny specilis esett l eltekintve a var hasznlata nem ajnlott, mivel nehezen olvashatv teszi a forrskdot. A kt leggyakoribb felhasznlsi terlete a nvtelen tpusok s a lekrdezs-kifejezsek.

5.2 Loklis vltozkEgy blokkon bell deklarlt vltoz loklis lesz a blokkra nzve, vagyis a program tbbi rszb l nem lthat (gy is mondhatjuk, hogy a vltoz hatkre a blokkra terjed ki). A fenti pldban a message egy loklis vltoz, ha egy msik fggvnyb l vagy osztlybl prblnnk meg elrni, akkor a program nem fordulna le.

5.3 Referencia- s rtktpusokA .NET minden tpusa a System.Object nev tpusbl szrmazik, s ezen bell sztoszlik rtk- s referenciatpusokra. A kett kzti klnbsg leginkbb a memriban val elhelyezkedsben jelenik meg. A CLR kt helyre tud adatokat pakolni, az egyik a verem (stack) a msik a halom (heap). A verem egy n. LIFO (last-in-first-out) adattr, vagyis az az elem amit utljra berakunk az lesz a tetejn, kivenni pedig csak a legfels elemet tudjuk. A halom nem adatszerkezet, hanem a program ltal lefoglalt nyers memria, amit a CLR tetszs szerint hasznlhat. Minden m velet a vermet hasznlja, pl. ha ssze akarunk adni kt szmot akkor a CLR lerakja mindkett t a verembe s meghvja a

Forrs: http://www.doksi.hu

22 megfelel utastst ami kiveszi a verem legfels vgeredmnyt pedig visszateszi a verembe:int x = 10; int y = 11; x+y A verem: |11| |10| -- sszeads m velet-- |21|

kt elemt sszeadja

ket, a

Ez azt is jelenti egyben, hogy fggetlenl attl, hogy rtkr l vagy referencirl van sz, valamilyen mdon mindkett t be kell tudnunk rakni a verembe. Az rtktpusok teljes valjukban a veremben vannak, mg a referencik a halomban jnnek ltre s a verembe egy rjuk hivatkoz referencia kerl. De mirt van ez gy? ltalban egy rtktpus csak egy-ngy bytenyi helyet foglal el, ezrt knyelmesen kezelhetjk a vermen keresztl. Ezzel szemben egy referenciatpus sokkal nagyobb szokott lenni s a memriban val megjelense is sszetettebb, ezrt hatkonyabb a halomban eltrolni. A forrskdban jl megklnbztethet a kett , mg referenciatpust a new opertor segtsgvel hozunk ltre, addig egy rtktpusnl erre nincs felttlenl szksg. Ez all a szably all kivtelt kpez a string tpus.

5.4 Boxing s unboxingBoxing nak (bedobozols) azt a folyamatot nevezzk, amely megengedi egy rtktpusnak, hogy gy viselkedjen, mint egy referenciatpus. Mivel minden tpus (rtk s referencia is) a System.Object tpusbl szrmazik, ezrt egy rtktpust rtkl adhatunk egy object tpusnak. Csakhogy az object maga is referenciatpus, ezrt az rtkadskor ltrejn a memriban (a halomban, nem a veremben) egy referenciatpus karakterisztikjval rendelkez rtktpus. Ennek el nye, hogy olyan helyen is hasznlhatunk rtktpust, ahol egybknt nem lehetne. Vegyk a kvetkez pldt:int x = 10; Console.WriteLine("X erteke: {0}", x);

Els re semmi klns, de elrulom, hogy a Console.WriteLine() metdus ebben a formjban msodik paramter l egy object tpus vltozt vr. Vagyis ebben a pillanatban a CLR automatikusan bedobozolja az x vltozt. A kvetkez forrskd megmutatja, hogyan tudunk kzzel dobozolni:int x = 10; object boxObject = x; //bedobozolva Console.WriteLine("X erteke: {0}", boxObject);

Most nem volt szksg a CLR re.

Forrs: http://www.doksi.hu

23 Az unboxing (vagy kidobozols) a boxing ellentte, vagyis a bedobozolt rtktpusunkbl kivarzsoljuk az eredeti rtkt:int x = 0; object obj = x; //bedobozolva int y = (int)obj; //kidobozolva

Az object tpuson egy explicit tpuskonverzit hajtottunk vgre (err l hamarosan), gy visszanyertk az eredeti rtket.

5.5 KonstansokA const tpusmdost segtsgvel egy vltozt konstanss tehetnk. A konstansoknak egyetlen egyszer adhatunk (s ekkor kell is adnunk) rtket, mgpedig a deklarcinl. Brmely ks bbi prblkozs fordtsi hibt okoz.const int x; //Hiba const int x = 10; //Ez j x = 11; //Hiba

A konstans vltozknak adott rtket/kifejezst fordtsi id ben ki kell tudnia rtkelni a fordtnak.Console.WriteLine("Adjon meg egy szamot: "); int x = int.Parse(Console.ReadLine()); const y = x; //Ez nem j, x nem ismert fordtsi id ben

5.6 A felsorolt tpusA felsorolt tpus olyan adatszerkezet, amely meghatrozott rtkek nvvel elltott halmazt kpviseli. Felsorolt tpust az enum kulcssz segtsgvel deklarlunk:enum Animal { Cat, Dog, Tiger, Wolf };

Ezutn gy hasznlhatjuk:Animal a = Animal.Tiger; if(a == Animal.Tiger) //Ha a egy tigris { Console.WriteLine("a egy tigris..."); }

A felsorols minden tagjnak megfeleltethetnk egy egsz rtket. Ha mst nem adunk meg, akkor az alaprelmezs szerint a szmozs nulltl kezd dik s deklarci szerinti sorrendben (rtsd: balrl jobbra) eggyel nvekszik.

Forrs: http://www.doksi.hu

24enum Animal { Cat, Dog, Tiger, Wolf } Animal a = Animal.Cat; int x = (int)a; //x == 0 a = Animal.Wolf; x = (int)a; //x == 3

Magunk is megadhatjuk az rtkeket:enum Animal { Cat = 1, Dog = 3, Tiger, Wolf }

Azok a nevek amelyekhez nem rendeltnk rtket explicit mdon az ket megel z nv rtkt l szmtva kapjk meg azt. gy a a fenti pldban Tiger rtke ngy lesz.

5.7 Null tpusokA referenciatpusok az inicializls el tt nullrtket vesznek fel, illetve mi magunk is jellhetjk ket belltatlannak:class RefType { } RefType rt = null;

Ugyanez az rtktpusoknl mr nem m kdik:int vt = null; //ez le sem fordul

Ez azrt van, mert a referenciatpusok rengeteg plusz informcit tartalmaznak, mg az inicializls el tt is, mg az rtktpusok memriban elfoglalt helye a deklarci pillanatban automatikusan feltlt dik nulla rtkekkel. Ahhoz, hogy meg tudjuk llaptani, hogy egy rtktpus mg nem inicializlt egy specilis tpust a nullable tpust kell hasznlnunk, amit a rendes tpus utn rt krd jellel (?) jelznk:int? i = null; //ez mr m kdik

Egy nullable tpusra val konverzi implicit (kln krs nlkl) megy vgbe, mg az ellenkez irnyba explicit konverzira lesz szksgnk (vagyis ezt tudatnunk kell a fordtval):int y = 10; int? x = y; //implicit konverzi y = (int)x; //explicit konverzi

Forrs: http://www.doksi.hu

25

6. OpertorokAmikor programozunk utastsokat adunk a szmtgpnek. Ezek az utastsok kifejezsekb l llnak, a kifejezsek pedig opertorokbl s operandusokbl illetve ezek kombincijbl jnnek ltre: i = x + y; Ebben a pldban egy utastst adunk, mgpedig azt, hogy i nek rtkl adjuk x s y sszegt. Kt kifejezs is van az utastsban: 1. x + y > ezt az rtket jelljk * -al 2. i = * -> i nek rtkl adjuk a * -ot Az els esetben x s y operandusok, a + jel pedig az sszeads m velet opertora. Ugyangy a msodik pontban i s * (vagyis x+y) az operandusok az rtkads m velet (=) pedig az opertor. Egy opertornak nem csak kt operandusa lehet. A C# nyelv egy- (unris) s hromoperandusu (ternris) opertorokkal is rendelkezik. A kvetkez nhny fejezetben tvessznk nhny opertort, de nem az sszeset. Ennek oka, hogy bizonyos opertorok nmagukban nem hordoznak jelentst, egy specilis rszterlet kapcsoldik hozzjuk, ezrt ezeket az opertorokat majd a megfelel helyen ismerjk meg. (Pl. az indexel opertor most kimarad, els knt a tmbknl tallkozhat vele az olvas.)

6.1 Opertor precedenciaAmikor tbb opertor is szerepel egy kifejezsben a fordtnak muszj valamilyen sorrendet (precedencit) fllltani kztk, hiszen az eredmny ett l is fgg. Pl.: 10 * 5 + 1 Sorrendt l fgg en az eredmny lehet 51, vagy 60. A j megolds az elbbi, az opertorok vgrehajtsnak sorrendjben a szorzs s oszts el nyt lvez. A legels helyen szerepelnek pl. a zrjeles kifejezsek, utolsn pedig az rtkad opertor. Ha bizonytalanok vagyunk a vgrehajts sorrendjben mindig hasznljunk zrjeleket, ez a vgleges programra semmilyen hatssal sincs. A fenti kifejezs teht gy nzzen ki: (10 * 5) + 1

6.2 rtkad opertorAz egyik legltalnosabb m velet amit elvgezhetnk az az, hogy egy vltoznak rtket adunk. A C# nyelvben ezt az egyenl sgjel segtsgvel tehetjk meg:int x = 10;

Forrs: http://www.doksi.hu

26 Ltrehoztunk egy int tpus vltozt, elneveztk x nek s kezd rtknek 10 et adtunk. Termszetesen nem ktelez a deklarcinl (amikor tjkoztatjuk a fordtt, hogy van egy valamilyen tpus, adott nev vltoz) megadni a defincit (amikor meghatrozzuk, hogy a vltoz milyen rtket kapjon), ezt el lehet halasztani:int x; x = 10;

Ett l fggetlenl a legtbb esetben ajnlott akkor rtket adni egy vltoznak amikor deklarljuk. Egy vltoznak nem csak konstans rtket, de egy msik vltozt is rtkl adhatunk, de csak abban az esetben, ha a kt vltoz azonos tpus, illetve ha ltezik a megfelel konverzi (a tpuskonverzikkal egy ks bbi fejezet foglalkozik).int x = 10; int y = x; //y rtke most 10

6.3 Matematikai opertorokA kvetkez pldban a matematikai opertorok hasznlatt mutatjuk meg:using System; public class Operators { static public void Main() { int x = 10; int y = 3; int z = x + y; //sszeads: z = 10 + 3 Console.WriteLine(z); //Kirja az eredmnyt: 13 z = x - y; //Kivons: z = 10 - 3 Console.WriteLine(z); // 7 z = x * y; //Szorzs: z = 10 * 3 Console.WriteLine(z); //30 z = x / y; //Maradk nlkli oszts: z = 10 / 3; Console.WriteLine(z); // 3 z = x % y; //Maradkos oszts: z = 10 % 3 Console.WriteLine(z); // Az oszts maradkt rja ki: 1 Console.ReadKey(); //Vr egy billenty letst } }

6.4 Relcis opertorokA relcis opertorok segtsgvel egy adott rtkszlet elemei kzti viszonyt tudjuk lekrdezni. A numerikus tpusokon rtelmezve van egy rendezs relci:

Forrs: http://www.doksi.hu

27using System; public class RelOp { static public void Main() { int x = 10; int y = 23; Console.WriteLine(x > y); //Kirja az eredmnyt: false Console.WriteLine(x == y); //false Console.WriteLine(x != y); //x nem egyenl y al: true Console.WriteLine(x y x >= y x 0 || x < 0) { Console.WriteLine("A ket string nem egyenlo..."); } x = String.CompareOrdinal(s, c); x = s.CompareTo(c);

Mindhrom metdus nullt ad vissza, ha a kt string egyenl s nullnl kisebbet/nagyobbat, ha nem (pontosabban ha lexikografikusan kisebb/nagyobb). Az els vltozat nagysg szerint sorbarendezi a karaktereket s gyhasonltja ssze a kt karaktersorozatot, a msodik az azonos indexen lv karaktereket nzi, mg a harmadik az els hz hasonl, de ez nem statikus hanem pldnymetdus. Keress:using System; class Program { static public void Main() { string s = "verylonglongstring"; char[] chs = new char[]{ 'y', 'z', '0' }; Console.WriteLine(s.IndexOf('r')); //2 Console.WriteLine(s.IndexOfAny(chs)); //3 Console.WriteLine(s.LastIndexOf('n')); //16 Console.WriteLine(s.LastIndexOfAny(chs)); //3 Console.WriteLine(s.Contains("long")); //true Console.ReadKey(); } }

Az IndexOf() s LastIndexOf() metdusok egy string vagy karakter els illetve utols el fordulsi indext (stringek esetn a kezds helyt) adjk vissza. Ha nincs tallat, akkor a visszaadott rtk -1 lesz. A kt metdus Any re vgz d vltozata egy karaktertmbt fogad paramtereknt. A Contains() metdus igaz rtkkel tr vissza, ha a paramtereknt megadott karakter(sorozat) benne van a stringben.

Forrs: http://www.doksi.hu

49

Mdosts:

using System; class Program { static public void Main() { string s = "smallstring"; char[] chs = new char[]{ 's', 'g' }; Console.WriteLine(s.Replace('s', 'l')); //lmallltring Console.WriteLine(s.Trim(chs)); //mallstrin Console.WriteLine(s.Insert(0, "one")); //onesmallstring Console.WriteLine(s.Remove(0, 2)); //allstring Console.WriteLine(s.Substring(0, 3)); //sma string c = s.ToUpper(); Console.WriteLine(s); //SMALLSTRING Console.WriteLine(c.ToLower()); //smallstring Console.ReadKey(); } }

A Replace() metdus az els paramternek megfelel karaktert lecserli a msodik paramterre. A Trim() metdus a string elejn s vgn lv karaktereket vgja le, a Substring() kivg egy karaktersorozatot, paramterei a kezd s vgindexek (van egyparamteres vltozata is, ekkor a csak a kezd indexet adjuk meg s a vgig megy). Az Insert()/Remove() metdusok hozzadnak illetve elvesznek a stringb l. Vgl a ToLower() s ToUpper() metdusok pedig kis- illetve nagybet ss alaktjk az eredeti stringet. Fontos megjegyezni, hogy ezek a metdusok soha nem az eredeti stringen vgzik a mdostsokat, hanem egy j pldnyt hoznak ltre s azt adjk vissza.

9.2 StringBuilderAmikor mdostunk egy stringet akkor automatikusan egy j pldny jn ltre a memriban, hiszen az eredeti vltozat nem biztos, hogy ugyanakkora mint az j. Ha sokszor van szksgnk erre, akkor hasznljuk inkbb a StringBuilder tpust, ez automatikusan lefoglal egy nagyobb darab memrit s ha ez sem elg, akkor allokl egy nagyobb terletet s tmsolja magt oda. A StringBuilder a System.Text nvtrben tallhat.using System; using System.Text; class Program { static public void Main() { StringBuilder builder = new StringBuilder(50);

Forrs: http://www.doksi.hu

50for(char ch = 'a';ch false, referenciatpusok -> null). A C++ nyelvet ismer k vigyzzanak, mivel itt csak alaprtelmezett konstruktort kapunk automatikusan, rtkad opertort illetve msol konstruktort nem. Ugyanakkor minden osztly a System.Object b l szrmazik (mg akkor is ha erre nem utal semmi), ezrt nhny metdust (pldul a tpus lekrdezshez) a konstruktorhoz hasonlan azonnal hasznlhatunk.

Forrs: http://www.doksi.hu

60 Jelen pillanatban az osztlyunkat semmire nem tudjuk hasznlni, ezrt ksztsnk hozz nhny adattagot s egy konstruktort:using System; class Dog { private string name; private int age; public Dog(string n, int a) { this.name = n; this.age = a; } } class Program { static public void Main() { Dog d = new Dog("Rex", 2); } }

A konstruktor neve meg kell egyezzen az osztly nevvel s semmilyen visszatrsi rtke sem lehet. A mi konstruktorunk kt paramtert vr, a nevet s a kort (metdusokkal s paramtereikkel a kvetkez rsz foglalkozik b vebben). Ezeket a pldnyostsnl muszj megadni, egybknt nem fordul le a program. Egy osztlynak paramterlisttl fgg en brmennyi konstruktora lehet s egy konstruktorbl hvhatunk egy msikat a this el:class MyClass { public MyClass() : this(10) //A msik konstruktort hvtuk { } public MyClass(int x) { } }

Ilyen esetekben a paramter tpushoz leginkbb illeszked konstruktor kerl majd hvsra. A pldban a konstruktor trzsben rtket adtunk a mez knek this hivatkozssal, amely mindig arra a pldnyra mutat, amelyen meghvtk. Nem ktelez hasznlni, ugyanakkor hasznos lehet, ha sok adattag/metdus van, illetve ha a paramterek neve megegyezik az adattagokval. A fordtprogram automatikusan odakpzeli magnak a fordts sorn, gy mindig tudja mivel dolgozik. Az adattagok private elrs ek (ld. elmleti rsz), azaz most csakis az osztlyon bell hasznlhatjuk ket, pldul a konstruktorban, ami viszont publikus.

Forrs: http://www.doksi.hu

61 Nem csak a konstruktorban adhatunk rtket a mez knek, hanem hasznlhatunk n. inicializlkat is:class Dog { private string name = "Rex"; private int age = 5; public Dog(string n, int a) { this.name = n; this.age = a; } }

Az inicializls mindig a konstruktor el tt fut le, ez egyben azt is jelenti, hogy az fellbrlhatja. Ha a Dog osztlynak ezt a mdostott vltozatt hasznltuk volna fentebb, akkor a pldnyosts sorn fellrnnk az alaprtelmezettnek megadott kort. Az inicializls sorrendje megegyezik a deklarls sorrendjvel (fl lr l lefel halad). A konstruktorok egy specilis vltozata az n. msol- vagy copy konstruktor. Ez paramtereknt egy sajt magval megegyez tpus objektumot kap s annak rtkeivel inicializlja magt. Msol konstruktort ltalban az rtkad opertorral szoktak implementlni, de az opertortlterhels egy msik fejezet tmja gy most egyszer bben oldjuk meg:class Dog { private string name = "Rex"; private int age = 5; public Dog(string n, int a) { this.name = n; this.age = a; } public Dog(Dog otherDog) { this.name = otherDog.Name; this.age = otherDog.Age; } public int Age { get { return age; } } public string Name { get { return name; } } }

Forrs: http://www.doksi.hu

62 n. tulajdonsgokat hasznltunk fel (err l hamarosan). Most mr felhasznlhajuk az j konstruktort:Dog d = new Dog("Rex", 6); Dog newDog = new Dog(d);

13.2 AdattagokAz adattagok vagy mez k olyan vltozk, amelyeket egy osztlyon (vagy struktrn) bell deklarltunk. Az eddigi pldinkban is hasznltunk mr adattagokat, ilyenek voltak a Dog osztlyon belli name s age vltozk. Az adattagokon hasznlhatjuk a const tpusmdostt is, ekkor a deklarcinl rtket kell adnunk a mez nek, hasonlan az el z fejezetben emltett inicializlshoz. Ezek a mez k pontosan ugyangy viselkednek mint a hagyomnyos konstansok. Egy konstans mez t nem lehet explicite statikusnak jellni, mivel a fordt egybknt is gy fogka kezelni (ha egy adat minden objektumban vltozatlan, felesleges minden alkalommal kln pldnyt kszteni bel le). A mez kn alkalmazhat a readonly mdost is, ez kt dologban klnbzik a konstansoktl: az rtkads elhalaszthat a konstruktorig s az rtkl adott kifejezs rtknek nem kell ismertnek lennie fordtsi id ben.

13.3 Lthatsgi mdostkA C# nyelv tfle mdostt ismer: public: az osztlyon/struktrn kv l s bell teljes mrtkben hozzfrhet . private: csakis a tartalmaz osztlyon bell lthat, a leszrmazottak sem lthatjk, osztlyok/struktrk esetben az alaprtelmezs. protected: csakis a tartalmaz osztlyon s leszrmazottain bell lthat. internal: csakis a tartalmaz (s a bart) assembly(ke) n bell lthat. protected internal: a protected s internal keverke.

13.4 Parcilis osztlyokC# nyelven ltrehozhatunk n. parcilis osztlyokat (partial class). Egy parcilis osztly definicija tbb rszb l (tipikusan tbb forrsfile bl) is llhat.//file1.cs

partial class PClass { public PClass() {/*...*/

} }//file2.cs

partial class PClass { public void DoSomeThing(){ /*...*/ } }

Forrs: http://www.doksi.hu

63

Az osztly sszes darabjnl ktelez kitenni a partial kulcsszt. A C# a parcilis osztlyokat f knt olyan esetekben hasznlja, amikor az osztly egy rszt a fordt generlja (pl. a grafikus fellet alkalmazsoknl a kezdeti belltsokat az InitializeComponent() metdus vgzi, ezt teljes egszben a fordt kszti el).A kvetkez tma megrtst el segtheti a kvetkez Metdusok cm rsz elolvassa

A C# 3.0 mr engedlyezi parcilis metdusok hasznlatt is, ekkor a metdus deklarcija s defincija sztoszlik://file1.cs

partial class PMClass {//deklarci

partial public void PartialMethod(string param); }//file2.cs

partial class PMClass {//definci

partial public void PartialMethod(string param) {/*...*/

} }

A partial kulcsszt ilyenkor is ki kell tenni minden el fordulsnl. Csakis parcilis osztly tartalmazhat parcilis metdust.

13.5 Begyazott osztlyokEgy osztly tartalmazhat metdusokat, adattagokat s ms osztlyokat is. Ezeket a bels osztlyokat begyazott (nested) osztlynak nevezzk. Egy begyazott osztly hozzfr az t tartalmaz osztly minden tagjhoz (belertve a private elrs tagokat s ms begyazott osztlyokat is). Egy ilyen osztlyt ltalban elrejtnk, de ha mgis publikus elrs nek deklarljuk, akkor a kls osztlyon kereszt l rhetjk el.//a begyazott osztly nem lthat

class Outer { private class Inner { } }//de most mr igen

class Outer {

Forrs: http://www.doksi.hu

64public class Inner { } }//plnyosts:

Outer.Inner innerClass = new Outer.Inner();

13.6 Objektum inicializlkA C# 3.0 objektumok pldnyostsnak egy rdekesebb formjt is tartalmazza:class Person { private string name; public Person() { } public string Name { get { return name; } set { this.name = value; } } } Person p = new Person { Name = "Istvan" };

Ilyen esetekben vagy egy nylvnos tagra, vagy egy tulajdonsgra hivatkozunk (ez utbbit hasznltuk). Termszetesen, ha ltezik paramteres konstruktor, akkor is hasznlhatjuk ezt a belltsi mdot, a kvetkez kppen:Osztaly valtozo = new Osztaly(/*parameterek*/) { };

13.7 DestruktorokA destruktorok a konstruktorokhoz hasonl specilis metdusok amelyek az er forrsok felszabadtsrt felelnek. A C# objektumai ltal elfoglalt memrit a szemtgyjt (Garbage Collector) szabadtja fel, abban az esetben ha az objektumra nincs rvnyes referencia:MyClass mc = new MyClass(); //mc egy MyClass objektumra mutat mc = null; //az objektumra mr nem mutat semmi, felszabadthat

A szemtgyjt m kdse nem determinisztikus, azaz el re nem tudjuk megmondani, hogy mikor fut le, ugyanakkor kzzel is meghvhat, de ez nem ajnlott:MyClass mc = new MyClass(); mc = null; GC.Collect(); GC.WaitForPendingFinalizers();

Forrs: http://www.doksi.hu

65 A GC a hatkonysg szempontjbl a legjobb id t vlasztja ki arra, hogy elvgezze a gy jtst (de legks bb akkor m kdsbe lp amikor elfogy a memria). A GC miel tt megsemmsiti az objektumokat meghvja a hozzjuk tartoz destruktort, msnven Finalizert. Vegyk a kvetkez kdot:class DestructableClass { public DestructableClass() { } ~DestructableClass() { } }

A destruktor neve tilde jellel (~) kezd dik, neve megegyezik az osztlyval s nem nem lehet semmilyen mdostja vagy paramtere. A fenti kd valjban a kvetkez formban ltezik:protected override void Finalize() { try { } finally { base.Finalize(); } }

Minden tpus rkli a System.Object t destruktorral fellrunk. A Finalize() el szr destruktorban ltalunk megszabott mdon), metdust (ez legalbb a System.Object nem r:

l a Finalize() metdust, amelyet a felszabadtja az osztly er forrsait (a aztn meghvja az sosztly Finalize() lesz) s gy tovbb amg a lnc vgre

class Base { ~Base() { Console.WriteLine("Base destruktor.."); } } class Derived { ~Derived() { Console.WriteLine("Derived destruktor..."); } }

Ezutn:

Forrs: http://www.doksi.hu

66class Program { static public void Main() { Derived d = new Derived(); Console.ReadKey(); } }

Amikor elindtjuk a programot nem trtnik semmi, ahogy az vrhat is volt. Amikor viszont lenyomunk egy gombot a Console.ReadKey() nek elindul a GC s a kimenet a kvetkez lesz:Derived destruktor Base destruktor

Els knt a leszrmazott, majd az sobjektum semmisl meg. A destruktorokra vonatkozik nhny szably, ezek a kvetkez ek: Egy osztlynak csak egy destruktora lehet A destruktor nem rklhet A destruktort nem lehet direkt hvni, ez mindig automatikusan trtnik Destruktora csakis osztlynak lehet, struktrnak nem

Forrs: http://www.doksi.hu

67

14. MetdusokBizonyra szeretnnk, ha a kutynk nem csak ltezne a semmiben, hanem csinlna is valamit. Ksztsnk nhny metdust (ugye senki nem felejtette el, a metdusokal m velteket tudunk vgezni az objektumon):class Dog { private string name; private int age; public Dog(string n, int a) { name = n; age = a; } public void Sleep(int time) { Console.WriteLine("A kutya {0} orat alszik..."); } public void Eat() { Consol.WriteLine("A kutya most eszik..."); } }

Most mr tud enni s aludni, a kt legfontosabb dolgot. Nzzk az alvst:public void Sleep(int time) { Console.WriteLine("A kutya {0} orat alszik...", time); }

El szr megadjuk a lthatsgot, ez publikus lesz, hogy meghvhassuk. Ezutn a metdus visszatrsi rtknek a tpusa jn. Mire j a visszatrsi rtk? Az objektumainkon nem csak m veleteket vgznk, de szeretnnk lekrdezni az llapotukat is s felhasznlni ezeket az rtkeket. Egy msik lehet sg, amivel mr tallkoztunk az int.Parse() metdus kapcsn, azok a kisegt fggvnyek amelyek nem kapcsoldnak kzvetlenl az objektum letciklushoz, de hasznosak s logikailag az osztly hatkrbe tartoznak. Visszatrsi rtkkel rendelkez metdust hasznlhatunk minden olyan helyen, ahol a program valamilyen tpust vr (rtkads, logikai kifejezsek, metdus paramterei, etc..). Kanyarodjunk vissza az eredeti szlhoz! Az alvs metdusunk nem tr vissza semmivel, ezt a void kulcsszval jelezzk, ez az n. ltalnos tpus (a ks bbiekben mg lesz rla sz). Ezutn a metdus neve s paramterlistja kvetkezik. A fggvnyeket az objektum neve utn rt pont opertorral hvhatjuk meg (ugyanez rvnyes a publikus adattagokra, tulajdonsgokra, stb. is):

Forrs: http://www.doksi.hu

68

Dog d = new Dog("Rex", 2); d.Eat(); d.Sleep(3);

Erre a kimenet:A kutya most eszik... A kutya 3 orat alszik...

14.1 ParamterekAz objektummal val kommunikci rdekben kpesnek kell lennnk kv lr l megadni adatokat, vagyis paramtereket. A paramterek szmt s tpusait a fggvny deklarcijban, vessz vel elvlasztva adjuk meg. Egy metdusnak gyakorlatilag brmennyi paramtere lehet. A metdus nevt s paramterlistjt alrsnak, szignatrnak vagy prototpusnak nevezzk. A paramterek a metduson bell loklis vltozkknt viselkednek, s a paramter nevvel hivatkozunk rjuk. A C# nyelvben paramterek tadhatunk rtk s cm szerint is. El bbi esetben egy teljesen j pldny jn ltre az adott osztlybl, amelynek rtkei megegyeznek az eredetivel. A msik esetben egy az objektumra mutat referencia addik t valjban, teht az eredeti objektummal dolgozunk. Az rtk- s referenciatpusok klnbz en viselkednek az tads szempontjbl. Az rtktpusok alaprtelmezetten rtk szerint addnak t, mg a referenciatpusoknl a cm szerinti tads az el re meghatrozott viselkeds. Utbbi esetben van azonban egy kivtel, mgpedig az, hogy mg a referenciatpus rtkeit megvltoztathatjuk (s ez az eredeti objektumra is hat) addig magt a referencit mr nem. Ha ezt mgis megtesszk, az a program futsra nem hat, de a vltozs csakis a metduson bell lesz szlelhet .using System; class Program { static public void AllocArray(int[] array, int size) { array = new int[size]; Console.WriteLine(array.Length); //100 } static public void Main() { int[] a = new int[10]; AllocArray(a, 100); Console.WriteLine(a.Length); //10 } }

Forrs: http://www.doksi.hu

69 Ha mgis mdostani akarjuk a referenciatpus referencijt, akkor kln jeleznnk kell azt, hogy cm szerint akarjuk tadni. Ktflekppen adhatunk t paramtert cm szerint. Az els esetben az tadott objektum inicializlva kell legyen. A cm szerinti tadst a forrskdban is jellni kell, mind a metdus prototpusnl, mind a hvs helyn:using System; class Dog { private int age; private string name; public Dog(string s, int a) { name = s; age = a; }/* mr elksztett metdusok */

public void PlayOtherDog(ref Dog other) { Console.WriteLine("Ket kutya jatszik..."); } }

class Program { static public void Main() { Dog d1 = new Dog("Rex", 2); Dog d2 = new Dog("Rinti", 3); d1.PlayOtherDog(ref d2); Console.ReadKey(); } }

A ref kulcsszval jelljk meg azokat a paramtereket, amelyeknek a cmt akarjuk tadni. Ezt a hvs helyn is meg kell tennnk. A cm szerinti tads msik formjban nem inicializlt paramtert is tadhatunk, de ekkor felttel, hogy a metduson bell lltsuk be. A hasznlata megegyezik a ref el, azaz a szignatrban s a hvsnl is jelezni kell a szndkunkat. A hasznland kulcssz az out (Nomen est omen A nv ktelez):using System; class Dog { private int age;

Forrs: http://www.doksi.hu

70private string name; public Dog(string s, int a) { name = s; age = a; }/* mr elksztett metdusok */

public void PlayOtherDog(ref Dog other) { Console.WriteLine("Ket kutya jatszik..."); } public void InitDog(out Dog idog) { idog = new Dog("Lassie", 4); } } class Program { static public void Main() { Dog d1 = new Dog("Rex", 2); Dog d2 = new Dog("Rinti", 3); d1.PlayOtherDog(ref d2); Dog d3; d2.InitDog(out d3); Console.ReadKey(); } }

Ebben a pldban nem lett volna muszj cm szerint tadnunk a paramtereket, hiszen az objektumok rtkeit nem mdostottuk. Amikor nem tudjuk, hogy pontosan hny paramtert akarunk tadni, akkor hasznlhatunk paramtertmbket:static void Func(params int[] paramarray) {/*Itt csinalunk valamit*/

} static public void Main() { int[] array = new int[] { 1, 2, 3, 4 }; Func(array); }

Forrs: http://www.doksi.hu

71

A paramtertmbt a params kulcsszval jelezzk, ezutn a metdus belsejben pontosan gy viselkedik, mint egy normlis tmb. A cm s rtk szerinti tadsrl a kvetkez oldalakon olvashatunk tbbet: http://msdn.microsoft.com/en-us/library/9t0za5es.aspx http://msdn.microsoft.com/en-us/library/s6938f28.aspx

14.2 Parancssori paramterekA Main nek ltezik paramteres vltozata is:using System; class Program { static public void Main(String[] args) { } }

Ekkor a Main paramtere egy tmb, ami a parancssori paramtereket trolja el. Pl. gy futtatjuk a programot: program.exe elso masodik harmadik Ha ki szeretnnk iratni a paramtereket, akkor gy mdostjuk a programot:

using System; class Program { static public void Main(String[] args) { foreach(string s in args) { Console.WriteLine(s); } } }

Erre a kimenet a kvetkez : elso masodik harmadik

14.3 Kiterjesztett metdusok

Forrs: http://www.doksi.hu

72

A C# 3.0 lehet sget ad arra, hogy egy mr ltez tpushoz j funkcikat adjunk, anlkl, hogy azt kzvetlenl mdostannk. Egy kiterjesztett metdus (extension method) minden esetben egy statikus osztly statikus metdusa kell legyen. Egsztsk ki a string tpust egy metdussal, ami kirja a kperny re az adott karaktersorozatot:static public class StringPrinter { static public void Print(this string s) { Console.WriteLine(s); } }

A this mdost utn a paramter tpusa kvetkezik, amely meghatrozza a kiterjesztett osztly tpust. Ezutn a metdust gy hasznljuk:string s = "abcd"; s.Print();//vagy hagyomnyos statikus metdusknt:

StringPrinter.Print(s);

Nemcsak osztlyt, de interfszt is b vthetnk. Ha kt kiterjesztett metdus ugyanazzal a szignatrval rendelkezik, akkor a hagyomnyos statikus ton kell hvnunk ket. Ha nem gy tesznk akkor a specilisabb paramter metdus fog meghvdni. Egy kiterjesztett metdust nem defiinlhatunk begyazott osztlyban. A kiterjesztett metdusokrl a kvetkez oldalon olvashatunk tbbet: http://msdn.microsoft.com/en-us/library/bb383977.aspx

14.4 Gyakorl feladatok1. Ksztsnk metdusokat a kutya osztlyhoz, amelyekkel elvgezhetjk a szoksos teend ket: pl.: frdets, stltats, stb. 2. Ksztsnk osztlyt, amely egy tmbt tartalmaz. Az osztly konstruktorban foglaljuk le a tmbt (a mrett a konstruktor paramtere tartalmazza). rjunk hozz egy metdust, amely kirja a tmbt a konzolra. Pl.:MyArray ma = new MyArray(10); //10 elem tmb ma.Print(); //kirjuk

3. Ksztsnk egy kiterjesztett metdust, amely kirja egy egsz szmokbl (int) ll tmb elemeit (a szksges statikus osztlyokrl a kvetkez fejezet szl).

Forrs: http://www.doksi.hu

73

15. Statikus tagokA hagyomnyos adattagok s metdusok objektumszinten lteznek, azaz minden pldny sajt pldnnyal rendelkezik. Gyakran van azonban szksgnk arra, hogy minden pldny egy kzs tagot hasznljon, pl. ha szeretnnk szmolni, hogy hny objektumot hoztunk ltre. Az sszes statikus tagbl sszesen egy darab ltezik. A statikus tagok jelent sge a C# tisztn objektum orientltsgban rejlik, ugyanis nem definilhatunk globlis mindenki szmra egyformn elrhet tagokat. Ezt vltjk ki a statikus adattagok s metdusok. gy megklnbztetnk pldny (instance) s statikus tagokat.

15.1 Statikus adattagokStatikus adattagot (s metdust ld. kvetkez fejezet) a static kulcssz segtsgvel hozhatunk ltre:public Animals { static public int animalCounter = 0; public Animals() { ++animalCounter; } }

A pldban a statikus adattag rtkt minden alkalommal megnveljk eggyel, amikor meghvjuk a konstruktort. Vagyis a pldnyok szmt troljuk el benne. A statikus tagokhoz az osztly nevn (s nem egy pldnyn) keresztl frnk hozz:Console.WriteLine("A peldanyok szama: {0}", Animals.animalCounter);

A statikus tagok azel tt inicializldnak, hogy el szr hozzfrnnk, illetve miel tt a statikus konstruktor ha van lefut.

15.2 Statikus metdusokA statikus metdusokbl, akrcsak az adattagokbl osztlyszinten egy darab ltezik. Statikus metdus ltrehozsa a kvetkez kppen trtnik:public class Math { static public void Pi() {/*...*/

} }

Ezt gy tudjuk meghvni:Console.WriteLine("Pi erteke: {0}", Math.Pi());

Forrs: http://www.doksi.hu

74 Brmely statikus taghoz az osztlyon s nem egy pldnyon kereszt l frnk hozz. A pldnyon val hvs fordtsi hibt jelent. Statikus metdust ltalban akkor hasznlunk, ha nem egy pldny llapotnak a megvltoztatsa a cl, hanem egy osztlyhoz kapcsold m velet elvgzse. A statikus metdusok nem frhetnek hozz a pldnytagokhoz (legalbbis direkt mdon nem).

15.3 Statikus tulajdonsgokEnnek a fejezetnek a megrtshez ajnlott elolvasni a Tulajdonsgok cm rszt

A statikus tulajdonsgok a C# egy viszonylag ritkn hasznlt lehet sge. ltalban osztlyokhoz kapcsold konstans rtkek lekrdezsre hasznljuk:public class Math { static public double Pi { get { return 3.14; } } }

15.4 Statikus konstruktorA statikus konstruktor a statikus tagok belltsrt felel. A statikus konstruktor azutn fut le, hogy a program elindult, de azel tt, hogy egy pldny keletkezik. A statikus konstruktornak nem lehet lthatsgot adni, illetve nincsenek paramterei sem. Mivel ez is egy statikus metdus nem frhet hozz a pldnytagokhoz. Plda statikus konstruktorra:public class Person { public static string name; static Person() { name = "Anonymus"; } }

15.5 Statikus osztlyokEgy osztlyt statikusnak jellhetnk, ha csak s kizrlag statikus tagjai vannak. Egy statikus osztlybl nem hozhat ltre pldny, nem lehet pldnykonstruktora (de statikus igen) s mindig lezrt (ld. rkl ds). A fordt minden esetben ellen rzi ezeknek a feltteleknek a teljeslst.static class Math { static private double pi = 3.141516;

Forrs: http://www.doksi.hu

75static public double Pi() { return pi; } static public double Cos(double x) { /*...*/ }/*Egyb tagok*/

}

15.6 Gyakorl feladatok1. Ksztsk el a Math statikus osztlyt! Az osztly tartalmazzon metdusokat a ngy alapm veletre (illetve tetsz leges matematikai m veletre). Az sszeads s szorzs metdusok a paramtereiket a params tmbn (ld. metdusok) kapjk meg, vagyis brmennyi taggal elvgezhet ek legyenek a m veletek. 2. Az el z feladat osztlyt felhasznlva ksztsnk egy egyszer szmolgpet! Azoknl a metdusoknl, amelyek meghatrozatlan szm paramtert vrnak ciklussal olvassuk be a tagokat!

Forrs: http://www.doksi.hu

76

16. TulajdonsgokA tulajdonsgokat (vagy property ket) a mez k kzvetlen mdostsra hasznljuk, anlkl, hogy megsrtennk az egysgbezrs elvt. A tulajdonsgok kv lr l nzve pontosan ugyanolyanok, mint a hagyomnyos vltozk:using System; class Person { private string name; public Person(string name) { this.name = name; }//Ez a tulajdonsg

public string Name { get { return this.name; } set { this.name = value; } } } class Program { static public void Main() { Person p = new Person("Istvan"); Console.WriteLine(p.Name); } }

A tulajdonsggal lekrdeztk a szemly nevt. Hagyomny - de nem ktelez hogy a tulajdonsg neve az adattag nevnek nagybet vel kezd d vltozata.public string Name { get { return this.name; } set { this.name = value; } }

-

Els knt megadtuk a lthatsgot, aztn a visszatrsi rtket s a nevet. A tulajdonsg trzse kt rszre az n. getter re s setter re oszlik. El bbivel lekrdezzk az adott rtket, pp gy mint egy hagyomnyos metdus esetben tennnk. A setter mr rdekesebb egy kicsit. Minden esetben amikor az adott tulajdonsgnak rtket adunk egy lthatatlan paramter jn ltre, aminek a neve value, ez fogja tartalmazni a tulajdonsg j rtkt. A settert gy hasznlhatjuk:class Program { static public void Main()

Forrs: http://www.doksi.hu

77{ Person p = new Person("Istvan"); p.Name = "Dezso"; Console.WriteLine(p.Name); //Dezso } }

Lthat, hogy pontosan gy m kdik mint egy vltoz. Egyik esetben sem vagyunk rknyszertve, hogy azonnal visszadjuk/beolvassuk az adttag rtkt, tetszs szerint vgezhetnk m veleteket is rajtuk:public string Name { get { return ("Mr." + this.name); } set { this.name = value; } }

Arra is van lehet sg, hogy csak az egyiket hasznljuk, ekkor csak-rhat/csakolvashat tulajdonsgokrl beszlnk (br el bbi hasznlata elg ritka). A getter/setter lthatsgt kln megadhatjuk, radsul ezeknek nem kell egyeznik sem:public string Name { get { return ("Mr." + this.name); } private set { this.name = value; } }

Ebben az esetben a getter megtartja az alaprtelmezett publikus lthatsgt, mg a setter private elrs lesz, kiv lr l nem lehet meghvni. A C# 3.0 rendelkezik egy nagyon rdekes jtssal az n. automatikus tulajdonsgokkal. Nem kell ltrehoznunk sem az adattagot, sem a teljes tulajdonsgot, a fordt mindkett t legenerlja neknk:class Person { public string Name { get; set; } }

A fordt automatikusan ltrehoz egy private elrs name nev adattagot s elkszti hozz a gettert/settert is. Van azonban egy problma, mghozz az, hogy a fordts pillanatban ez a vltoz mg nem ltezik. Viszont van setter, amit hasznlhatunk s mr ltezik:class Person { private string Name { get; set; } public Person(string n) {

Forrs: http://www.doksi.hu

78name = n; //Ez nem m kdik Name = n; //Ez viszont igen } }

Forrs: http://www.doksi.hu

79

17. Indexel kAz indexel k hasonlak a tulajdonsgokhoz, azzal a klnbsggel, hogy nem nvvel, hanem egy indexxel frnk hozz az adott informcihoz. ltalban olyan esetekben hasznljk, amikor az osztly/struktra tartalmaz egy tmbt vagy valamilyen gy jtemnyt (vagy olyan objektumot, amely maga is megvalst egy indexel t). Egy indexel t gy implementlhatunk:class Names { private ArrayList nameList; public Names() { nameList = new ArrayList(); nameList.Add("Istvan"); nameList.Add("Judit"); nameList.Add("Bela"); nameList.Add("Eszter"); } public string this [int idx] { get { if(idx < nameList.Count) { return nameList[idx].ToString(); } else return null; } } }

Ez gyakorlatilag egy nvtelen tulajdonsg, a this mutat mutat az aktulis objektumra, amin az indexel t definiltuk. Nemcsak egy indexet adhatunk meg, hanem tetszs szerintit, illetve az index tpusa sem kttt. Pl.:public int this [int idx1, int idx2] {/*...*/

}

Forrs: http://www.doksi.hu

80

18. Gyakorl feladatok II.18.1 Tmb tpusValstsunk meg egy tmb tpust. Az osztly tartalmazzon metdusokat/tulajdonsgokat/indexel ket a szoksos tmbm veletek (kirs, rendezs, stb) elvgzsre. Az indexel t gy ksztsk el, hogy ellen rizze, hogy ltez indexekre hivatkoznuk. Ha nem akkor rjon hibazenetet a kperny re.

Forrs: http://www.doksi.hu

81

19. rkl dsrkl dssel egy mr ltez tpust terjeszthetnk ki vagy b vthetjk tetsz leges szolgltatssal. A C# csakis egyszeres rkl dst engedlyez, ugyanakkor megengedi tbb interfsz impementlst (interfszekr l hamarosan). Ksztsk el az elmleti rsz pldjt (llat-Kutya-Krokodil) C# nyelven. Az egyszer sg kedvrt hagyjuk ki az llat s Kutya kzti specilisabb osztlyokat:class Animal { public Animal() { } } class Dog : Animal { public Dog() { } } class Crocodile : Animal { public Crocodile() { } }

A Kutya s Krokodil osztlyok egyarnt megvalstjk az szegnyes) funkcionalitst. B vtsk ki az sosztlyt:class Animal { public Animal() { } public void Eat() { Console.WriteLine("Az allat eszik..."); } }

sosztly (egyel re

Ezt az j metdust az tdosztlyok is rklni fogjk, hvjuk is meg valamelyik sosztlyon:Dog d = new Dog(); d.Eat();

Az eredmny az lesz, hogy kirjuk a kperny re a megadott zenetet. Honnan tudja vajon a fordt, hogy egy sosztlybeli metdust kell meghvnia? A referenciatpusok (minden osztly az) specilis mdon jelennek meg a memriban, rendelkeznek tbbek kzt egy n. metdustblval, ami mutatja, hogy az egyes metdushvsoknl melyik metdust kell meghvni. Persze ezt is meg kell hatrozni valahogy, ez nagy vonalakban gy trtnik, hogy a fordt a fordts pillanatban megkapja a metdus nevt s elindul visszafel az osztlyhierarchia mentn. A fenti pldban a hv osztly nem rendelkezik Eat() nev metdussal s nem is definilja t annak a viselkedst (err l hamarosan), ezrt az eggyel feljebbi st kell

Forrs: http://www.doksi.hu

82 megnznnk. Ez egszen a lehet legjabb metdusdefinciig megy s amikor megtallja a megfelel implementcit bejegyzi azt a metdustblba.

19.1 KonstruktorEgy leszrmazott konstruktorban meghvhatjuk az sosztly konstruktort:class BaseClass { protected int data; public Base(int _data) { this.data = _data; } } class DerivedClass : BaseClass { private int data2; public DerivedClass(int d2) : base(d2) { data2 = data; } }

Ezt a base fggvnnyel tehetjk meg s, ahogy a pldban is ltszik a paramtereket is tadhatjuk.

19.2 PolimorfizmusKorbban mr beszltnk arrl, hogy az s s leszrmazottak kzt az-egy relci ll fent. Ez a gyakorlatban azt jelenti, hogy minden olyan helyen, ahol egy stpust hasznlunk ott hasznlhatunk leszrmazottat is (pl. egy llatkertben llatok vannak, de az llatok helyre (nylvn) behelyettesthetek egy specilis fajt). Pldul gond nlkl rhatom a kvetkez t:Animal a = new Dog();

A new opertor meghvsa utn a gy fog viselkedni mint a Dog osztly egy pldnya, hasznlhatja annak metdusait, adattagjait. Arra azonban figyeljnk, hogy ez visszafel nem m kdik, a fordt hibt jelezne. Abban az esetben ugyanis, ha a fordt engedn a visszafel konverzit az n. leszeletel ds (slicing) effektus lpne fel, azaz az adott objektum elveszten a specilisabb osztlyra jellemz karakterisztikjt. A C++ nyelvben sokszor jelent gondot ez a problma, mivel ott egy pointeren keresztl megtehet a lebutts. Szerencsre a C# nyelvben ezt megoldottk, gy nem kell aggdnunk miatta.

Forrs: http://www.doksi.hu

83

19.3 Virtulis metdusokA virtulis (vagy polimorfikus) metdusok olyan sosztlyok olyan metdusai amelyek viselkedst a leszrmazottak tdefinilhatjk. Virtulis metdust a virtual kulcssz segtsgvel deklarlhatunk:class Animal { public Animal() { } public virtual void Eat() { Console.WriteLine("Az allat eszik..."); } } class Dog { Public Dog() { } public override void Eat() { Console.WriteLine("A kutya eszik..."); } }

A leszrmazott osztlyban az override kulcsszval mondjuk meg a fordtnak, hogy szndkosan hoztunk ltre az sosztlyval azonos nev metdust s a leszrmazott osztlyon ezt kvnjuk hasznlni mostantl. Egy override al jellt metdus automatikusan virtulis is lesz, gy az leszrmazottai is tdefinilhatjk a m kdst. Prbljuk ki az j metdust:Dog d = new Dog(); d.Eat();

A kimenet:A kutya eszik

Mi trtnik vajon a kvetkez esetben:Animal[] aniArray = new Animal[2]; aniArray [0] = new Animal(); aniArray [1] = new Dog(); aniArray [0].Eat(); aniArray [1].Eat();

Amit a fordt lt, az az, hogy ksztettnk egy Animal tpus elemekb l ll tmbt s, hogy az elemein meghvtuk az Eat() metdust. Csakhogy az Eat() egy virtulis

Forrs: http://www.doksi.hu

84 metdus, radsul van leszrmazottbeli implementcija is, amely tdefinlja az eredeti viselkedst, s ezt explicit jelltk is az override kulcsszval. gy a fordt el tudja dnteni a futsidej tpust, s ezltal temezi a metdushvsokat. Ez az n. ks i kts (late binding). A kimenet gy mr nem lehet ktsges:Az llat eszik... A kutya eszik...

Az utdosztly metdusnak szignatrja, visszatrsi rtke s lthatsga meg kell egyezzen azzal amit t akarunk definilni. Mr beszltnk arrl, hogyan pl fel a metdustbla, a fordt megkeresi a legkorbbi implementcit, s most mr azt is tudjuk, hogy az els ilyen implementci egy virtulis metdus lesz, azaz a keress legks bb az els virtulis vltozatnl megll. Tegyk fel, hogy nem ismerjk az sosztly fellett s a hagyomnyos mdon deklarljuk az Eat() metdust (ugye nem tudjuk, hogy mr ltezik). Ekkor a program ugyan lefordul, de a fordt figyelmezet minket, hogy eltakarjuk az rkltt metdust. s valban, ha meghvnnk akkor az j metdus futna le. Ezt a jelensget rnykolsnak (shadow) nevezik. Termszetesen mi azt szeretnnk, hogy a fordts hiba nlkl menne vgbe, gy tjkoztatnunk kell a fordtt, hogy szndkosan takarjuk el az eredeti implementcit. Ezt a new kulcsszval tehetjk meg:public class Animal { public Animal() { } public virtual void Eat() { Console.WriteLine("Az allat eszik..."); } }

public class Dog : Animal { public Dog() { } public new void Eat() { Console.WriteLine("A kutya eszik..."); } }

Ezutn a Dog utdjai mr nem ltjk az eredeti Eat() metdust. Viszont kszthetnk bel le virtulis metdust, amelyet az utdjai mr kedvkre hasznlhatnak. Azaz, a new mdostval elltott metdus j sort kezd, amikor a fordt felpti a metdustblt, vagyis a new virtual kulcsszavakkal elltott metdus lesz az j metdussorozat gykere.

Forrs: http://www.doksi.hu

85 A kvetkez fejezet lezrt osztlyaihoz hasonlan egy metdust is deklarlhatunk lezrtknt, ekkor a leszrmazottak mr nem definilhatjk t a m kdst:class Animal { public Animal() { } public virtual void Eat() { Console.WriteLine("Egy allat eszik..."); } } class Dog : Animal { public Dog() { } public sealed override void Eat() { Console.WriteLine("Egy kutya eszik..."); } } class Dobermann : Dog { public Dobermann() { } public override void Eat() //Ez nem fog lefordulni {//valamit csinlunk

} }

Nem jellhetnk virtulisnak statikus, absztrakt s override al jellt tagokat (az utols kett egybknt virtulis is lesz, de ezt nem kell kln jellni).

19.4 Lezrt osztlyokEgy osztlyt lezrhatunk, azaz megtilthatjuk, hogy j osztlyt szrmaztassunk bel le://Ez mr egy vgleges osztly

public sealed class Dobermann : Dog { }//Ez nem fog lefordulni

public class MyDobermann : Dobermann { }

A struktrk (rluk ks bb) alaprtelmezetten lezrtak.

Forrs: http://www.doksi.hu

86

19.5 Absztrakt osztlyokEgy absztrakt osztlyt nem lehet pldnyostani. A ltrehozsnak clja az, hogy kzs felletet biztostsunk a leszrmazottainak:abstract class Animal { abstract public void Eat(); } class Dog : Animal { Animal() { } public override void Eat() { Console.WriteLine("A kutya eszik..."); } }

Lthat, hogy mind az osztly, mind a metdus absztraktknt lett deklarlva, ugyanakkor a metdus nem virtulis s nincs defincija. Egy absztrakt osztly csak a fordts kzben absztrakt, a lefordtott kdban teljesen normlis osztlyknt szerepel, virtulis metdusokkal. A fordt feladata az, hogy betartassa a r vonatkoz szablyokat. Ezek a szablyok a kvetkez ek: absztrakt osztlyt nem lehet pldnyostani abszrakt metdusnak nem lehet defincija a leszrmazottaknak definilnia kell az rkltt absztrakt metdusokat.

Absztrakt osztly tartalmazhat nem absztrakt metdusokat is, ezek pont gy viselkednek, mint a hagyomnyos nem-virtulis fggvnyek. Az rkltt absztrakt metdusokat az override kulcssz segtsgvel tudjuk definilni (hiszen virtulisak, mg ha nem is ltszik). Amennyiben egy osztlynak van legalbb egy absztrakt metdusa az osztlyt is absztraktknt kell jellni. Annak ellenre, hogy egy absztrakt osztlyt nem pldnyosthatunk mg lehet konstruktora, mgpedig azrt, hogy bellthassuk vele az adattagokat:abstract class Animal { protected int age; public Animal(int _age) { this.age = _age; }//Egyb metdusok...

} class Dog : Animal { public Dog(int _age) : base(_age) { }//Egyb metdusok

}

Forrs: http://www.doksi.hu

87

Vajon, hogyan m kdik a kvetkez pldban a polimorfizmus elve? :Animal[] animArray = new Animal[2]; animArray[0] = new Dog(2); animArray[1] = new Crocodile(100);

Ennek a kdnak hiba nlkl kell fordulnia, hiszen tnylegesen egyszer sem pldnyostottuk az absztrakt sosztlyt. A fordt csak azt fogja megvizsglni, hogy mi van a new opertor jobb oldaln, az alaposztly nem rdekli. Termszetesen a kvetkez esetben nem fordulna le:animArray[0] = new Animal(2);

Az absztrakt osztlyok rendelkeznek nhny gyenge ponttal. Ha egy leszrmazottjbl szrmaztatok, akkor az j osztlynak nem kell megvalstania az absztrakt metdusokat, viszont hasznlhatja azokat:public abstract class Animal { public Animal() { } public abstract void Eat(); } public class Dog : Animal { public Dog() { } public override void Eat() { Console.WriteLine("A kutya eszik..."); } } public class Dobermann : Dog { public Dobermann() { } } Dobermann d = new Dobermann(); d.Eat(); //Ez m kdik

Forrs: http://www.doksi.hu

88

20. InterfszekAz interfszek hasonlak az absztrakt osztlyokhoz, abban az rtelemben, hogy meghatrozzk egy soztly viselkedst, fellett. A nagy klnbsg a kett kzt az, hogy mg el bbi eleve meghatroz egy osztlyhierarchit, egy interfsz nem kthet kzvetlenl egy osztlyhoz, mindssze el r egy mintt, amit meg kell valstania az osztlynak. Egy msik el nye az interfszek hasznlatnak, hogy mg egy osztlynak csak egy se lehet, addig brmennyi intefszt megvalsthat. Ezen fell interfszt hasznlhatunk struktrk esetben is. Interfszt a kvetkez kppen deklarlunk:public interface IAnimal { void Eat(); }

Az interfsz nevt ltalban nagy I bet vel kezdjk. Lthat, hogy nincs definci, csak deklarci. A megvalst osztly dolga lesz majd megvalstani a tagjait. Egy interfsz a kvetkez ket tartalmazhatja: metdusok, tulajdonsgok, indexel k s esemnyek. A tagoknak nincs kln lthatsguk, ehelyett minden tagra az interfsz elrhet sge vonatkozik. A kvetkez forrskd megmutatja, hogyan valsthatjuk meg a fenti interfszt:public interface IAnimal { void Eat(); }

public class Dog : IAnimal { public Dog() { } public void Eat() { Console.WriteLine("A kutya eszik..."); } }

Fontos, hogy amennyiben egy msik osztlybl is szrmaztatunk, akkor a felsorolsnl az sosztly nevt kell el revenni, utna jnnek az interfszek:public interface IFace1 { } public interface IFace2 { } class Base { } class Derived : Base, IFace1, IFace2 {/*...*/

}

Forrs: http://www.doksi.hu

89 Egy interfszt szrmaztathatunk ms interfszekb l:public interface IAnimal { void Eat(); } public interface IDog : IAnimal { void Vau(); } public class Dog : IAnimal, IDog { public Dog() { } public void Eat() { Console.WriteLine("A kutya eszik..."); } public void Vau() { Console.WriteLine("Vau-vau..."); } }

Egy adott interfszt megvalst objektumot implicit tkonvertlhatjuk az interfsz tpusra:public IEnumerable {/*...*/

} class EnumClass : IEnumerable {/*...*/

} IEnumerable ie = new EnumClass(); //Ez m kdik

Az is s as opertorokkal megtudhatjuk, hogy egy adott osztly megvalst e egy interfszt:public interface IMyIf { } class MyIClass : IMyIf { } MyIClass mic = new MyIClass();

Forrs: http://www.doksi.hu

90if(mic is IMyIf) { Console.WriteLine("Az osztaly megvalositja az interfeszt..."); } IMyIf test = mic as IMyIf; if(test != null) { Console.WriteLine("Az osztaly megvalositja az interfeszt..."); }

Az is hasznlata egyrtelm , az as pedig null t ad vissza, ha a konverzi sikertelen volt.

20.1 Explicit interfszimplementciHa tbb interfszt is implementlunk, az nvtkzshez is vezethet. Ennek kikszblsre explicit mdon megadhatjuk a megvalstani kvnt funkcit:public interface IOne { void Method(); } public interface ITwo { void Method(); } public class MyClass : IOne, ITwo { IOne.Method() { } ITwo.Method() { } }

A kt Method() szignatrja megegyezik, gy valahogy meg kell ket klnbztetnnk. Ekkor azonban a fggvnyhvsnl is problmba tkznk, ezrt konverzit kell vgrehajtanunk:MyClass mc = new MyClass(); ((IOne)mc).Method(); ((ITwo)mc).Method();

Egy msik lehet sg:MyClass mc = new MyClass(); IOne iface = (IOne)mc; iface.Method();

Ekkor explicit konverzit hajtunk vgre s a megfelel metdust.

interfszen hvjuk meg a

Forrs: http://www.doksi.hu

91

20.2 Virtulis tagokEgy interfsz tagjai alaprtelmezs szerint lezrtak, de a megvalstsnl jellhetjk ket virtulisnak. Ezutn az osztly leszrmazottjai tetszs szerint mdosthatjk a defincit, a mr ismert override kulcsszval:public interface IAnimal { void Eat(); }

public class Dog : IAnimal { public Dog() { } public virtual void Eat() { Console.WriteLine("A kutya eszik..."); } } public class Dobermann : Dog { public Dobermann() { } public override void Eat() { Console.WriteLine("A dobermann eszik..."); } }

Egy leszrmazott jraimplementlhatja az adott interfszt, amennyiben nemcsak az snl, de az utdnl is jelljk a megvalstst:public class Dobermann : Dog, IAnimal { public Dobermann() { } public new void Eat() { Console.WriteLine("A dobermann sokat eszik..."); } }

Ez esetben nylvn hasznlnuk kell a new kulcsszt annak jellsre, hogy eltakarjuk az s megvalstst.

Forrs: http://www.doksi.hu

92

20.3 Gyakorlati plda 1.Korbban mr tallkoztunk a foreach ciklussal, s mr tudjuk, hogy csak olyan osztlyokon kpes vgigiterlni, amelyek megvalstjk az IEnumerator s IEnumerable interfszeket. Mindkett a System.Collections nvtrben tallhat. Els knt nzzk az IEnumerable interfszt:public interface IEnumerable { IEnumerator GetEnumerator(); }

Ez a foreach nek fogja szolgltatni a megfelel felletet, ugyanis a ciklus meghvja a metdust, s annak vissza kell adnia az osztlyt IEnumerator knt (ld. implicit konverzi). Ezrt kell megvalstani egyttal az IEnumerator interfszt is, ami gy nz ki:public interface IEnumerator { bool MoveNext(); void Reset(); object Current { get; } }

A MoveNext() a kvetkez elemre mozgatja a mutatt, ha tudja, de ha a vgre rt akkor false rtkkel tr vissza. A Reset() alaprtelmezsre lltja a mutatt, azaz -1 re. Vgl a Current (read-only) tulajdonsg az aktulis poziciban lv elemet adja vissza. Ennek object tpussal kell visszatrnie, hiszen minden tpusra m kdnie kell (ltezik generikus vltozata is, de err l ks bb). Hasznljuk az Animal osztlyunk egy kiss mdostott vltozatt:public class Animal { private string name; public Animal(string _name) { this.name = _name; } public Name { get { return this.name; } } }

Most ksztsnk egy osztlyt, amelyen megvalstjuk a kt interfszt, s ami tartalmaz egy Animal objektumokbl ll listt:

Forrs: http://www.doksi.hu

93public class AnimalContainer : IEnumerable, IEnumerator { private ArrayList container = new ArrayList(); private int currPosition = -1; public AnimalContainer() { container.Add(new Animal("Rex")); container.Add(new Animal("Rin-Tin-Tin")); container.Add(new Animal("Cheetah")); } }

Ez persze mg nem az egsz osztly, felvettnk egy ArrayList et, amiben eltroljuk az objektumokat, illetve deklarltunk egy egsz szmot, ami az aktulis pozict trolja el s kezd rtk l -1 et adtunk (ld. Reset()). A konstruktorban lthat, hogy rgtn a new al hoztunk ltre j objektumokat, nem pedig kln tettk ezt. Ksztsk el az IEnumerator ltal ignyelt metdusokat:public bool MoveNext() { return (++position < container.Count) } public object Current { get { return container[currPosition]; } } public void Reset() { currPosition = -1; }

Vgl az IEnumerable interfszt valstjuk meg:public IEnumerator GetEnumerator() { return (IEnumerator)this; }

Ezutn hasznlhatjuk is az osztlyt:AnimalContainer ac = new AnimalContainer(); foreach(Animal a in ac) { Console.WriteLine(a.Name); }

Forrs: http://www.doksi.hu

94

20.4 Gyakorlati plda 2.A msodik gyakorlati pldnkban az IComparable interfszt fogjuk megvalstani, amelyre gyakran van szksgnk. Ez az interfsz ltalban olyan adatszerkezeteknl kvetelmny amelyek az elemeiken megvalstanak valamilyen rendezst. A generikus List tpusmak is van rendez metdusa, amely ezzel a metdusal dolgozik. Az IComparable egyetlen metdussal a CompareTo() val rendelkezik, amely egy object tpust kap paramterl:class ComparableClass : IComparable { int value; public ComparableClass(int val) { this.value = val; } public int Value { get { return value; } } public int CompareTo(object o) { if(o is ComparableClass) { ComparableClass c = (ComparableClass)o; return value.CompareTo(c.Value); } else throw(new Exception("Nem megfelelo objektum...")); } }

Az osztlyban a beptett tpusok CompareTo() metdust hasznltuk, hiszen k mind megvalstjk ezt az interfszt. Ez a metdus -1 et ad vissza ha a hv fl kisebb, 0 t, ha egyenl s 1 et ha nagyobb. A hasznlata:List list = new List(); Random r = new Random(); for(int i = 0;i < 10;++i) { list.Add(new ComparableClass(r.Next(1000))); } foreach(ComparableClass c in list) { Console.WriteLine(c.Value); }

Console.WriteLine("A rendezett lista:"); list.Sort();

Forrs: http://www.doksi.hu

95

foreach(ComparableClass c in list) { Console.WriteLine(c.Value); }

Hasonl feladatot lt el, de jval rugalmasabb az IComparer interfsz. A List rendezsnl megadhatunk egy sszehasonlt osztlyt is, amely megvalstja az IComparer interfszt. Most is csak egy metdust kell elksztennk, ez a Compare() amely kt object tpust vr paramtereknt:class ComparableClassComparer : IComparer { public int Compare(object x, object y) { if(x is ComparableClass && y is ComparableClass) { ComparableClass _x = (ComparableClass)x; ComparableClass _y = (ComparableClass)y; return _x.CompareTo(_y); } else throw(new Exception("Nem megfelelo parameter..."); } }

Ezutn a kvetkez kppen rendezhetjk a listt:list.Sort(new ComparableClassComparer());

Az IComparer el nye, hogy nem kt dik szorosan az osztlyhoz (akr anlkl is megrhatjuk, hogy ismernnk a bels szerkezett), gy tbbfle megvalsts is lehetsges.

Forrs: http://www.doksi.hu

96

21. Opertor tlterhelsNylvn szeretnnk, hogy az ltalunk ksztett tpusok hasonl funkcionalitssal rendelkezzenek mint a beptett tpusok (int, string, stb). Vegyk pl. azt a pldt, amikor egy mtrix tpust valstunk meg. J lenne, ha az sszeads, kivons, szorzs, stb. m veleteket gy tudnnk vgrehajtani, mint egy egsz szm esetben, nem pedig metdushvsokkal. Szerencsre a C# ezt is lehet v teszi szmunkra, ugyanis engedi az opertortlterhelst, vagyis egy adott opertort tetszs szerinti funkcival ruhzhatunk fel az osztlyunkra vonatkoztatva.Matrix m1 = new Matrix(); Matrix m2 = new Matrix();//ehelyett

Matrix m3 = m1.Add(m2);//rhatjuk ezt

Matrix m4 = m1 + m2;

A tlterhelhet opertorok listja: +(unris) -% >> >= -(unris) + & == ++ / = size) { throw(new StackOverflowException("Tele van...")); } t[pointer] = _in; ++pointer; } public object Pop() { --pointer; if(pointer >= 0) { return t[pointer]; } pointer = 0; throw(new InvalidOperationException("Ures...")); } }

Ezt most a kvetkez kppen hasznlhatjuk:

Forrs: http://www.doksi.hu

109Stack s = new Stack(10); for(int i = 0;i < 10;++i) { s.Push(i); } for(int i = 0;i < 10;++i) { Console.WriteLine(Console.WriteLine(int.Parse(s.Pop())); }

M kdni m kdik, de se nem hatkony se nem knyelmes. A hatkonysg az rtk/referenciatpusok miatt cskken jelent sen (ld. boxing/unboxing), a knyelem pedig amiatt, hogy mindig figyelni kell pp milyen tpussal dolgozunk, nehogy olyan kasztolssal ljnk ami kivtelt dob. Ezeket a problmkat knnyen kikszblhetjk, ha genrikus osztlyt ksztnk:class Stack { T[] t; int pointer; readonly int size; public Stack(int capacity) { t = new T[capacity]; size = capacity; pointer = 0; } public void Push(T _in) { if(pointer >= size) { throw(new StackOverflowException("Tele van...")); } t[pointer] = _in; ++pointer; } public object Pop() { --pointer; if(pointer >= 0) { return t[pointer]; } pointer = 0; throw(new InvalidOperationException("Ures...")); } }

Ezutn akrmelyik tpuson knnyen hasznlhatjuk:

Forrs: http://www.doksi.hu

110

Stack s = new Stack(10); Stack c = new Stack(10); for(int i = 0;i < 10;++i) { s.Push(i); c.Push(i.ToString()); } for(int i = 0;i < 10;++i) { Console.WriteLine("{0}, {1}", s.Pop(), c.Pop()); }

A generikus tpusok nem kovarinsak, azaz egy generikus pldnyt nem kasztolhatunk olyan tpusra, amelyre normlis esetben igen:class Base { } class Derived : Base { } Stack s = new Stack(10); Stack b = s; //ez nem m kdik

24.3 Generikus megszortsokAlaprtelmezetten egy generikus paramter brmely tpust jelkpezheti. A deklarcinl azonban kikthetnk megszortsokat a paramterre. A megszortsokat a where kulcsszval vezetjk be:where where where where where where T T T T T T : : : : : : alaposztly interfsz osztly struktra new() //alaprtelmezett konstruktor U

Egy plda:public interface IFace { } public class BaseClass { } class NewClass where T : BaseClass, IFace, new() {}

Forrs: http://www.doksi.hu

111 A NewClass osztly csak akkor pldnyosthat, ha a megadott tpusa a BaseClass osztlybl szrmazik, megvalstja az IFace interfszt s rendelkezik alaprtelmezett konstruktorral:class GoodClass : BaseClass, IFace { public GoodClass() { } } NewClass nc = new NewClass();

Az osztly s struktra megszorts osztlynak/struktrnak kell lennie.

azt

jelenti,

hogy

a

paramternek

24.4 rkl dsGenerikus osztlybl szrmaztathatunk is, ekkor vagy az sosztly egy specializlt vltozatbl szrmaztatunk, vagy a nyers generikus osztlybl:class Base { } class Derived : Base { }//vagy

class IntDerived : Base { }

24.5 Statikus tagokGenerikus tpusok esetben minden tpushoz kln statikus tag tartozik:class MyClass { public static int data; } MyClass.data = 10; MyClass.data = 20; Console.WriteLine(MyClass.data); //10 Console.WriteLine(MyClass.data); //20

Forrs: http://www.doksi.hu

112

24.6 Generikus gy jtemnyekA C# 2.0 bevezetett nhny hasznos generikus adatszerkezetet, tbbek kzt listt s vermet. Ezeket a tpusokat a tmbkhz hasonlan hasznlhatjuk. A kvetkez kben megviszglunk ezek kzl nhnyat. Ezek a szerkezetek a System.Collections.Generic nvtrben tallhatak:List list = new List(); for(int i = 0;i < 10;++i) { list.Add(i); } foreach(int i in list) { Console.WriteLine(i); }

Az Add() metdus a lista vghez adja hozz a pramterknt megadott elemet, hasonlan az ArrayList hez (tulajdonkppen a List az ArrayList generikus vltozata). Hasznlhatjuk rajta az indexel opertort is. A SortedList kulcs rtk prokat trol el s a kulcs alapjn rendezi is ket:SortedList slist = new SortedList(); slist.Add("elso", 1); slist.Add("masodik", 2); slist.Add("harmadik", 3);

A lista elemei tulajdonkppen nem a megadott rtkek, hanem a kulcs rtk prokat reprezentl KeyValuePair objektumok. A lista elemeinek elrshez is hasznlhatjuk ezeket:foreach(KeyValuePair kv in slist) { Console.WriteLine("Kulcs: {0}, Ertek: {1}", kv.Key, kv.Value); }

A lista kulcsai csakis olyan tpusok lehetnek, amelyek megvalstjk az IComparable interfszt, hiszen ez alapjn trtnik a rendezs. Ha ez nem igaz, akkor mi magunk is definilhatunk ilyet, rszletekrt ld. az Interfszek fejezetet. A SortedList rendezetlen prja a Dictionary:Dictionary dict = new Dictionary(); dict.Add("elso", 1); dict.Add("masodik", 2); foreach(KeyValuePair kv in dict) { Console.WriteLine("Key: {0}, Value: {1}", kv.Key, kv.Value); }

Forrs: http://www.doksi.hu

113

24.7 Generikus interfszekA letbb hagyomnyos interfsznek ltezik generikus vltozata is. Pldul az IEnumerable s IEnumerator is ilyen:class MyClass : IEnumerable, IEnumerator { }

Ekkor a megvalsts teljesen ugyangy m kdik mint a hagyomnyos esetben, csak pp hasznlnunk kell a generikus paramter(eke)t. A generikus adatszerkezetek a generikus ICollection, IList s IDictionary interfszeken alapulnak, gy ezeket megvalstva akr mi magunk is ltrehozhatunk ilyet.

Forrs: http://www.doksi.hu

114

25. Delegate -ekA delegate ek o