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(

"Teszt");
alma );

//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

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

// fggvnydefinci

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

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

Plda:
double d=2.3;
int i=(int) d;

// i=2

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

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)

Plda:

double dd=Math.Sin(Math.PI/2);
Console.WriteLine(dd);
// rtke 1.
dd=Math.Pow(2,3);
Console.WriteLine(dd);
// 8

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

csak struktrn bellrl rhet el


brki elrheti ezt a mezt
programon bellrl (assembly) elrhet

Plda:
struct szemly
{
public string nv;

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.

Plda:
struct alma
{
string nev="jonatn"; // fordtsi hiba

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;

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

}
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"
}
}

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
{
}

re=value;

}
float Im
{
get
{
}
set
{
}

return im;

im=value;

}
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);
}
}

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; };
}

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

class utd: s
{

};

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();

// hvs rendben

#undefine alma
almafuggveny();

// 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.

Brian W. Kernigham, Dennis M. Ritchie : A C programozsi nyelv


Mszaki Knyvkiad, Budapest 1985, 1988

2.

Bjarne Stroustrup: C++ programming language


AT&T Bell Lab, 1986

3.

Tom Archer : Inside C#


MS Press, 2001

4.

Microsoft C# language specifications


MS Press, 2001

5.

John Sharp, Jon Jagger: Microsoft Visual C#.NET


MS Press, 2002

6.

Ills Zoltn: A C++ programozsi nyelv


ELTE IK, Mikrolgia jegyzet, 1995-

7.

David S.Platt: Bemutatkozik a Microsoft.NET


Szak Kiad, 2001

8.

Ills Zoltn: A C# programozsi nyelv s krnyezete


Informatika a felsoktatsban 2002, Debrecen

9.

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