You are on page 1of 245

Marcin Lis

CWICZENIA

Czas

na

praktyczn1 nauk C#!

Odkryj wygodne riard'zla progr:i.m1stycz1'\e I obiektowe mo2:1lwosei C#


Poi:::n:;:aj nojv1iejs:z:e konstrukcje jzyko. i naucz .si sosovra je w pro.ktyce
D,owiedz si.,., ;ak 1..rykorzysty.vo. C# do t.1101-zenia. doskonltycl"I nplikncji Windows

ub ie cl

Main()
Consoe.

01d

se

ca

rite ne

Wszelkie prawa zastrzeone. Nieautoryzowane rozpowszechnianie caoci


lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione.
Wykonywanie kopii metod kserograficzn, fotograficzn, a take kopiowanie
ksiki na noniku filmowym, magnetycznym lub innym powoduje naruszenie
praw autorskich niniejszej publikacji.
Wszystkie znaki wystpujce w tekcie s zastrzeonymi znakami firmowymi
bd towarowymi ich wacicieli.
Autor oraz Wydawnictwo HELION dooyli wszelkich stara, by zawarte
w tej ksice informacje byy kompletne i rzetelne. Nie bior jednak adnej
odpowiedzialnoci ani za ich wykorzystanie, ani za zwizane z tym ewentualne
naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo
HELION nie ponosz rwnie adnej odpowiedzialnoci za ewentualne
szkody wynike z wykorzystania informacji zawartych w ksice.
Redaktor prowadzcy: Ewelina Burska
Projekt okadki: Maciej Pasek
Materiay graficzne na okadce zostay wykorzystane za zgod Shutterstock.
Wydawnictwo HELION
ul. Kociuszki le, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@h elion.pl
WWW: http://helion.pl (ksigarnia internetowa, katalog ksiek)
Drogi Czytelniku!
Jeeli chcesz oceni t ksik, zajrzyj pod adres
http://helion.pl/user/opinie ?cwcsh3 ebook
Moesz tam wpisa swoje uwagi, spostrzeenia, recenzj.
_

Listingi do ksiki mona znale pod adresem:


ftp://ftp.helion.pl/przyklady/cwcsh3.zip
ISBN: 978-83-246-5652-3
Copyright Helion 2012
Printed in Poland.

Pole ksik na Facebook.com

Ksigarnia internetowa

Kup w wersji papierowej

Lubi to! Nasza spoeczno

Oce ksik

Spis treci
Wstp

Cz I

Jzyk programowania

Rozdzia 1.

Pierwsza aplikacja

11

Jzyk C#
Jak waciwie nazywa si ten jzyk?
rodowisko uruchomieniowe
Narzdzia
Najprostszy program
Kompilacja i uruchamianie
Visual C# Express
Dyrektywa using

11
12
12
14
14
15
19
23

Zmienne i typy danych

25

Typy danych
Typy arytmetyczne
Typ bool (Boolean)
Deklarowanie zmiennych
Nazewnictwo zmiennych
Typy odnonikowe
Typ string
Typ object
Warto null
Operatory
Operatory arytmetyczne
Operatory bitowe

25
25
27
28
32
33
34
34
35
35
36
43

Rozdzia 2.

C#

w i cz e n i a

Operatory logiczne
Operatory przypisania
Operatory porwnania (relacyjne)
Operator warunkowy (?)
Pozostae operatory
Priorytety operatorw
Komentarze

45
45
46
47
48
48
49

Instrukcje

51

Instrukcje warunkowe
Instrukcja if... else
Instrukcja if. .. else if
Instrukcja switch
Ptle
Ptla for
Ptla while
Ptla do . . . while
Ptla f oreach
Instrukcja goto
Wprowadzanie danych
Argumenty wiersza polece
Instrukcja ReadLine

51
51
55
57
59
59
66
68
70
70
73
74
80

Cz li

Programowanie obiektowe

89

Rozdzia 4.

Klasy i obiekty

91

Rozdzia 3.

Rozdzia 5.

Klasy
Metody
Konstruktory
Specyfikatory dostpu
Dziedziczenie

91
94
103
107
114

Tablice

119

Deklarowanie tablic
Inicjalizacja tablic
Rozmiar tablicy
Ptla foreach
Tablice wielowymiarowe

120
122
124
127
130

S p i s t reci

Rozdzia 6.

Wyjqtki i obsuga bdw

137

Obsuga bdw
Blok try.catch
Hierarchia wyjtkw
Wasne wyjtki

137
143
148
151

Interfejsy

155

Prosty interfejs
Interfejsy w klasach potomnych
Czy to interfejs?
Rzutowanie
Sowo kluczowe as
Sowo kluczowe is

155
159
167
172
174
175

Cz Ili

Programowanie w Windows

177

Rozdzia 8.

Pierwsze okno

179

Utworzenie okna
Wywietlanie komunikatu
Zdarzenie ApplicationExit

179
184
185

Delegacje i zdarzenia

187

Delegacje
Zdarzenia

187
192

Rozdzia 7.

Rozdzia 9.

Rozdzia 1 O. Komponenty
Etykiety (Label)
Przyciski (Button)
Pola tekstowe (TextBox)
Pola wyboru (CheckBox, RadioButton)
Listy rozwijane (ComboBox)
Listy zwyke (ListBox)
Menu
Menu gwne
Menu kontekstowe
Waciwoci Menu
Skrty klawiaturowe

197
197
203
206
211
217
220
224
224
232
235
240

C#

w i cz e n i a

Wstp
Czy warto poznawa C#? To pytanie zadaje sobie bardzo
wielu programistw na caym wiecie . Jzyk ten jest mocno
promowany przez firm Microsoft, gdzie powstay jego pierw
sze specyfikacje i implementacje, ale nawet osoby, ktre nie przepadaj
za t firm, przyznaj, e C# jest udanym produktem. Co wicej, jest
na tyle podobny do c + + i Javy, e programici znajcy oba te jzyki
od razu go polubi. Z kolei wszyscy ci, ktrzy dopiero rozpoczynaj
swoj przygod z programowaniem, dostan do dyspozycji jzyk prost
szy do nauki ni wspomniane C + + , przy czym w tym przypadku
prostszy" wcale nie oznacza o mniejszych moliwociach" . Co wicej,
jeli kto nauczy si C# jako pierwszego jzyka, nie b dzie mia
trudnoci z pniejszym poznaniem c + + czy Javy.

'

Czy zatem warto? Na pewno tak. Miny ju czasy, kiedy programista


zna tylko jeden jzyk programowania, wic niezalenie od tego, czy
jest to dla nas pierwszy, czy kolejny jzyk, warto si z nim zapozna .
Oczywicie, trudno w tej chwili prorokowa, czy osignie on tak du
popularno jak wspomniani wyej aktualni liderzy (cho wszystko
na to wskazuje1), ale ju teraz wiadomo, e w wielu zastosowaniach
na pewno bdzie wykorzystywany, choby ze wzgldu na wygod
i naprawd due moliwoci. Dlatego te powstaa ta ksika, ktra
stanowi doskonay pierwszy krok do wyprawy w krain C#, przy
datny zarwno dla osb pocztkujcych, jak i znajcych ju inny jzyk
(bd jzyki) programowania .
1 Wedle niektrych bada na pocztku 2012 roku popularno C# zbliya
si do C + +, ktry systematycznie traci udziay

rynku.

C#

w i cz e n i a

W ksice opisano standard C# 4 . 0, cho wikszo wicze bdzie


poprawnie dziaa nawet w pierwotnych, powstaych kilka lat temu,
a obecnie rzadko spotykanych wersjach 1 .0 i 1 . 1 . Przedstawiony mate
ria jest rwnie w peni zgodny ze standardami C# 4.5 (ktry w trakcie
powstawania tej publikacji by dostpny w wersji developer preview)
oraz 5 .O (znajdujcymi si w fazie opracowywania) .

I
Jzyk p rog ra mowa n i a

1o

C#

w i cz e n i a

1
Pie rwsza a p l i ka cja
Jzyk C#
Jzyk C# zosta opracowany w firmie Microsoft i wywodzi si z rodziny
CIC + + , cho zawiera rwnie wiele elementw znanych programi
stom Javy, takich jak np . mechanizmy automatycznego odzyskiwania
pamici. Programici korzystajcy na co dzieli z wymienionych jzy
kw programowania bd si czuli doskonale w tym rodowisku .
Z kolei dla osb nieznajcych C# nie bdzie on trudny do opanowa
nia, a na pewno duo atwiejszy ni tak popularny C + + .
Gwnym twrc C# jest Anders Hejlsberg, czyli nie kto inny jak
projektant produkowanego niegdy przez firm Borland pakietu Delphi,
a take Turbo Pascala ! W Microsofcie Hejlsberg rozwija m.in. ro
dowisko Visual J + + . To wszystko nie pozostao bez wpywu na naj
nowszy produkt, w ktrym mona dojrze wyrane zwizki zarwno
z C i C + + , jak Jav i Delphi, czyli Object Pascalem.
C# jest w peni obiektowy (zorientowany obiektowo), zawiera wspo
mniane ju mechanizmy odzyskiwania pamici i obsug wyjtkw.
Jest te cile powizany z rodowiskiem uruchomieniowym .NET,
co - oczywicie - nie znaczy, e nie mog powstawa jego imple
mentacje przeznaczone dla innych platform. Oznacza to jednak, e
doskonale sprawdza si w najnowszym rodowisku Windows oraz
w sposb bezporedni moe korzysta z klas .NET, co pozwala na
szybkie i efektywne pisanie aplikacji.

12

C#

w i cz e n i a

Ja k waciwie nazywa si ten jzyk?


Pewne zamieszanie panuje w kwestii nazwy jzyka. Trzeba wic od
razu podkreli , e C# wymawiamy jako C-Sharp (czyli fonetycznie
si-szarp lub ce-szarp) i jest to jedyna poprawna nazwa. To nie jest
C-Hash, C-Number, C-Pound, C-Gate itp . Aby jednak zrozumie, skd
wynikaj te nieporozumienia, naley wrci do genezy nazewnictwa
jzykw z tej rodziny. Dlaczego np . tak popularny jzyk C (1 9 7 1 ) zo
sta oznaczony wanie t liter alfabetu? Ot dlatego, e wywodzi
si wprost z jzyka B (1 969) . Z kolei C + + to nic innego jak zoenie
nazwy C i operatora + + , co w tumaczeniu znaczy, e jest to kolejna,
ulepszona wersja C. Podobnie C#, w ktrym pierwotnie za liter C sta
znak # oznaczajcy w notacji muzycznej podwyszenie dwiku
o p tnu1 (znak o kodzie U+ 266f), co mona interpretowa jako kolej
ne, ulepszone C . Poniewa jednak znak ten nie wystpuje na stan
dardowej klawiaturze, podjto decyzj, e bdzie reprezentowany przez
znak # (hash, znak o kodzie U + 0023), niemniej wymawiany bdzie
jako sharp (fonetycznie : szarp) , czyli, podkrelmy raz jeszcze, nazwa
tego jzyka powinna by wymawiana jako C-Sharp (fonetycznie : ce
szarp lub si szarp) .

Srod owisko u ruchomieniowe


Programy pisane w technologii .NET, niezalenie od zastosowanego
jzyka, wymagaj specjalnego rodowiska uruchomieniowego, tzw.
CLR
Common Language Runtime. Prba uruchomienia takiego
programu w zwykym rodowisku Windows skmiczy si niepowo
dzeniem i komunikatami o braku odpowiednich bibliotek. Niezbdne
jest zatem zainstalowanie pakietu .NET Framework (najlepiej w moli
wie najnowszej wersji) dostpnego na stronach Microsoftu (http://www.
microsoft.com/net). Dotyczy to wszystkich systemw wczeniejszych
ni Windows XP (od wersji XP, a wic obecnie praktycznie w kadym
przypadku, platforma .NET jest instalowana standardowo wraz z sys
temem) .
-

1 Std zapewne to nieszczsne C-Cis, pojawiajce si w niektrych polskich


tumaczeniach.

R o zd z i a 1.

P i e rwsza a p l i k a c j a

13

Skd takie wymogi? Ot program pisany w technologii .NET, czy to


w C#, Visual Basicu czy innym jzyku, nie jest kompilowany do kodu
natywnego danego procesora (rozumianego" bezporednio przez pro
cesor) , ale do kodu poredniego2 (przypomina to w pewnym stopniu
byte-code znany z Javy) . Tene kod poredni jest wsplny dla caej
platformy. Innymi sowy, kod rdowy napisany w dowolnym jzyku
zgodnym z .NET jest tumaczony na wsplny jzyk zrozumiay dla
rodowiska uruchomieniowego . Pozwala to m.in. na bezporedni
oraz bezproblemow wspprac moduw i komponentw pisanych
w rnych jzykach . Fragment prostego programu w tym wsplnym
jzyku porednim widoczny jest na poniszym listingu .
. method publ i c h i debys i g stat i c voi d

Mai n ( s t r i n g [ J a rg s ) c i l man aged

. entrypoi n t

li Code

size 309 (Oxl 35)

. maxstack 3
. l oc a l s i n i t ( i nt32 V O . i n t32 V 1 . i n t32 V 2 . fl oat64 V 3 . fl oat64 V 4 .
obj ect [ J V_5 )
IL 0 0 0 0: l dc . i 4 . l
I L 0 0 0 1 : St l OC . 0
-5
I L 0 0 0 2 : l dc . i 4 . s
IL 0 0 0 4 : s t l oc . l
I L 0 0 0 5 : l dc . i 4 . 4
I L 0 0 0 6 : st l OC . 2
I L_0 0 0 7 : l dstr bytea rray ( 50 O O 6 1 O O 72 O O 6 1 O O 60 O O 65 O O 74 O O 72
OO 79 OO 20 O O 72 OO F3 OO 77 OO 6E OO 6 1 OO 6E OO 69 OO 6 1 OO 3A O O OA 00 )
I L_O O O c : c a l l voi d [mscorl i bJ System . Con s o l e : : W ri teLi n e ( st r i n g )

}
Nie jest on moe na pierwszy rzut oka zbyt przejrzysty, ale osoby
znajce np . asembler z pewnoci dostrzeg spore podobie11Stwa. Na
szczcie, przynajmniej na pocztku przygody z C#, nie trzeba schodzi
na tak niski poziom programowania. Moliwo obejrzenia kodu po
redniego moe by jednak przydatna np . przy wyszukiwaniu bdw
we wsppracujcych ze sob komponentach.
Najwaniejsze w tej chwili jest to, e aby uruchomi program napisany
w C#, musimy mie zainstalowany pakiet .NET Framework, ktry
potrafi poradzi sobie z kodem porednim oraz zawiera biblioteki
z definicjami przydatnych klas .
2

Kompilacja kodu poredniego do kodu natywnego procesora jest wykonywana


przez kompilator just-in-time w momencie uruchomienia aplikacji. rodowisko
uruchomieniowe moe te przechowywa gotowe do uruchomienia
prekompilowane i zoptymalizowane fragmenty kodu aplikacji.

14

C#

w i cz e n i a

Na rzdzia
Najpopularniejszym rodowiskiem programistycznym sucym do
tworzenia aplikacji C# jest - oczywicie - produkowany przez
firm Microsoft pakiet Visual C # . Jest on dostpny jako oddzielny
produkt, jak rwnie jako cz pakietu Visual Studio . Wszystkie
prezentowane w tej ksice przykady mog by tworzone przy uyciu
tego wanie produktu (a take produktw niezalenych, takich jak
Mono czy DotGNU) . Korzysta mona z darmowej edycji Visual C#
Express dostpnej pod adresem http://www.microsoft.com/express.
Istnieje rwnie darmowy kompilator C# (csc .exe), bdcy czci
pakietu .NET Framework (pakietu tego naley szuka pod wspomnia
nym ju adresem http:// www.microsoft.com/net lub http://msdn .microsoft.
com/netframework/). Jest to kompilator uruchamiany w wierszu pole
cef1, nie oferuje wic dodatkowych udogodniefl przy budowaniu
aplikacji, tak jak Visual Studio, jednak do naszych celw jest cako
wicie wystarczajcy.
Co wicej, wanie ten kompilator zaprezentowano podczas wyko
nywania wicze. Bdzie tak przede wszystkim dlatego, e kiedy nie
korzysta si z wizualnych pomocy (szczeglnie przy tworzeniu aplikacji
z interfejsem graficznym) , atwiej zrozumie zalenoci wystpujce
w kodzie oraz zobaczy, w jaki sposb realizowanych jest wiele me
chanizmw jzyka, takich jak np . zdarzenia . Oczywicie, jeli kto
woli korzysta z Visual C#, moe posugiwa si tym narzdziem.

Naj prostszy prog ra m


Na pocztku napiszemy najprostszy chyba program, ktrego zadaniem
bdzie wywietlenie na ekranie dowolnego tekstu. Nie jest to skom
plikowane zadanie, jednak pewne rzeczy trzeba bdzie przyj na
sowo" , dopki nie zostan omwione definicje klas , bo kady pro
gram napisany w C# skada si ze zbioru klas . Oglna struktura pro
gramu powinna wyglda nastpujco :
u s i n g Sy stem :
publ i c cl a s s n a zwa k l a sy

R o zd z i a 1.
{

P i e rwsza a p l i k a c j a

15

publ i c stati c voi d M a i n ( )

{
//tutaj instrukcje do wykonania

Takiej wanie struktury bdziemy uywa w kolejnych wiczeniach,


przyjmujc, e tak powinien wyglda program . Kod wykonywalny,
np . instrukcje wyprowadzajce dane na ekran, umieszcza bdziemy
w oznaczonym miejscu funkcji Ma i n ( ) . Tak instrukcj jest:
Con sol e . W ri tel i n e ( "Tek st do wywi etl en i a " ) ;

WICZENIE

Pierwszy program

Napisz program wywietlajcy dowolny napis na ekranie, np . Mj


pi erws zy program! .
u s i n g Sy stem ;
publ i c cl a s s Program

publ i c stati c voi d Mai n ( str i n g [ J a rg s )

Con so l e . W r i tel i ne ( " Mj pi erwszy program ! " ) ;

Plik ten mona zapisa na dysku pod nazw program .es. Oczywicie,
moliwe jest rwnie nadanie innej , praktycznie dowolnej nazwy
(np . aplikacja .es).
Wielko liter

kodzie rdowym ma znaczenie. Jeli si pomylimy,

kompilacja si nie uda!

Kom pi l acja i u ruchamia nie


Kod z wiczenia 1 . 1 naley teraz skompilowa i uruchomi . Korzysta
bdziemy z kompilatora uruchamianego w wierszu polece - csc. exe
(dostpnego po zainstalowaniu w systemie pakietu .NET Framework,

16

C#

w i cz e n i a

a take Visual C# Express) . Jeeli korzystamy z interfejsu graficzne


go w Linuksie, naley najpierw uruchomi program terminala (kon
soli) . Przykadowo dla dystrybucji Ubuntu (wersja 1 0 . , powoka gra
ficzna Gnome) naley z menu Programy wybra kolejno Akcesoria
i Terminal. Jeli pracujemy w systemie Windows , wciskamy na kla
wiaturze kombinacj klawiszy Windows+R3, w polu Uruchom wpi
sujemy cmd lub cmd . exe4 i klikamy przycisk OK lub wciskamy klawisz
Enter (rysunek 1 . 1 ) . (W systemach 2000 i XP, a take starszych, pole
Uruchom jest te dostpne bezporednio w menu Start5). Pojawi si
wtedy okno wiersza polece (wiersza polecenia) , w ktrym bdzie
mona wydawa komendy . Jego wygld dla systemw z rodziny
Windows 7 zosta przedstawiony na rysunku 1 .2 (w innych wersjach
wyglda bardzo podobnie) .
Rysunek 1 . 1.
Uruchamianie
polecenia cmd
w Windows 7

Uruchamianie

g
;;;;
p

Wpi.sz nazw programu, folderu, dokumentu lubza.sobu


internetowego, a zostanie on otwarty przez system
Windows.

.Qtwrz:

[ml

...1

OK

][

Anuluj

][

E.rzegldaj.

Rysunek 1. 2. Okno konsoli (wiersza polecel1) w systemie Windows 7


Aby wykona kompilacj, w najprostszym przypadku jako parametr
wywoania kompilatora csc .exe naley poda nazw pliku z kodem
rdowym - wywoanie bdzie wic miao posta :
c i eka dostpu do komp i 7 atora\ c s c . exe program . es

Klawisz funkcyjny Windows jest te opisywany jako Start.

W starszych systemach (Windows 98, Me) naley uruchomi aplikacj


command.exe (Start/Uruchom/command.exe).

W systemach Vista i 7 pole Uruchom standardowo nie jest dostpne w menu


startowym, ale mona je do niego doda, korzystajc z opcji Dostosuj.

R o zd z i a 1.

P i e rwsza a p l i k a c j a

17

Oto przykad :
c : \wi n dows \ M i c rosoft . N ET\ Framewo r k \ v4 . 0 . 30 3 19\ c s c . exe program . e s

cieka dostpu do kompilatora to katalog, w ktrym zosta zainsta


lowany pakiet .NET Framework. Znajduje si on w lokalizacji
windows\ M i cros oft . NET\ Framewo r k \ wersja

gdzie windows oznacza katalog systemowy, a


platformy .NET, np . v4 . 0 . 30319.

wersja

okrela wersj

Nie naley przy tym zapomnie o podawaniu nazwy pliku zawsze


z rozszerzeniem. Typowym rozszerzeniem plikw z kodem rdowym
C# jest cs, chocia nie jest ono obligatoryjne i kompilator przyjmie
bez problemw rwnie dowolny inny plik zawierajcy poprawny
tekst programu. W celu uatwienia pracy warto doda do zmiennej
systemowej path ciek dostpu do pliku wykonywalnego kompilatora,
mona np . wyda (w wierszu polece) polecenie6:
path=%path% : " c : \wi ndows \ M i cros oft . N ET\ Framewo r k \ v4 . 0 . 30 3 19 \ "

Wtedy kompilacja bdzie moga by wykonywana za pomoc ko


mendy :
c s c . exe program . es

Po kompilacji powstanie plik wynikowy program.exe, ktry mona


uruchomi w wierszu polece (w konsoli systemowej) , czyli tak jak
kad inn aplikacj, o ile - oczywicie - zosta wczeniej zain
stalowany pakiet .NET Framework.
WICZENIE

Skompilowanie i uruchomienie programu

Skompiluj i uruchom program napisany w wiczeniu 1 . 1 .


Etap kompilacji oraz wynik dziaania programu widoczny jest na ry
sunku 1 . 3 . Jak wida, o ile w kodzie rdowym nie wystpuj bdy,
kompilator nie wywietla jakichkolwiek informacji oprcz noty copyri
ght, generuje natomiast plik wykonywalny typu exe. Kompilator csc
umoliwia stosowanie rnych opcji pozwalajcych na ingerencj
w proces kompilacji. S one pokazane w tabeli 1 . 1 .

Oczywicie, naley samodzielnie dostosowa numer wersji platformy .NET.


Uyty w poleceniu cig v4 . O. 30319 jest przykadowy.

18

C#
iii

w i cz e n i a

C:\Windows\system32\cmd.exe

Rysunek 1 . 3. Kompilacja i uruch omienie pierwszego program u w C#


Tabela 1. 1. Wybrane opcje kompilatora csc
Nazwa opcji

Forma
skrcona

/out :

Parametr

Znaczenie

nazwa pliku

Nazwa pliku
wynikowego,
domylnie jest to
nazwa pliku z kodem
rdowym.

/ta rget :

/t :

exe

Tworzy aplikacj
konsolow.

/ta rget :

/t :

wi nexe

Tworzy aplikacj
okienkow.

/ta rget :

/t :

l i b r a ry

Tworzy bibliotek.

/ p l atform :

/p :

x8 6, I t a n i urn, x64,
anycpu

Okrela platform
sprztowo-systemow
dla ktrej ma by
generowany kod.
Domylnie jest o kada
platforma (anycpu).

/ recu r s e :

ma s k a

Komplikuje wszystkie
pliki ( z katalogu
biecego oraz
katalogw podrzdnych),
ktrych nazwa jest
zgodna z mask.

/wi n32i con :

n a zwa p l i k u

Docza do pliku
wynikowego podan
ikon.

R o zd z i a 1.

P i e rwsza a p l i k a c j a

19

Tabela 1. 1. Wybrane opcje kompilatora csc - cig dalszy


Nazwa opcji

Forma
skrcona

/debug

Parametr

Znaczenie

+lub -

Wcza ( +)
oraz wycza (- )
generowanie
informacji dla
debuggera.

/opt1 m 1 ze

Io

+lub -

Wcza ( +)
oraz wycza (- )
optymalizacj kodu.

/ 1 ncrementa l

/1 ncr

+lub -

Wcza ( +)
oraz wycza (- )
kompilacj
przyrostow.

/wa rn a s error

Wcza tryb
traktowania ostrzee
jako bdw.

/wa rn :

/w :

od O do 4

Ustawia poziom
ostrzee.

/ n owa rn :

lista ostrzee

Wycza generowanie
podanych ostrzee.

/hel p

I?

/ n o l ogo

Wywietla list opcji.


Nie wywietla noty
copyright.

Visu a I C# Exp ress


Do wykonywania wicze zawartych w ksice z powodzeniem wy
starczy opisany wyej kompilator uruchamiany w wierszu polece
(csc .exe), dostpny w pakiecie .NET Framework. Dla osb, ktre wo
layby jednak wykorzysta do nauki pakiet Visual C# Express (lub
Visual Studio) , zostao zamieszczonych kilka poniszych wicze
pokazujcych, w jaki sposb utworzy projekt i wykona kompilacj .

C#

20

WICZENIE

w i cz e n i a

Pierwszy projekt w Visual C#

Uruchom Visual C# Express (Visual Studio) , utwrz pusty projekt,


a nastpnie dodaj do niego przygotowany plik program .es. Wykonaj
kompilacj kodu.
Po uruchomieniu pakietu naley utworzy nowy projekt (menu File/
New Project), nastpnie wybra opcj Empty Project i zatwierdzi wybr
przyciskiem OK (w polu Name mona poda nazw projektu) . Na
stpnie (po utworzeniu pustego projektu) , korzystajc z menu Project
i opcji Add Existing Item, trzeba doda do projektu plik program .es.
Jeeli zawarto dodanego pliku nie pojawi si na ekranie, mona j
wywietli, klikajc dwukrotnie jego nazw w oknie Solution Explorer
(rysunek 1 .4) . Projekt naley nastpnie zapisa w wybranym katalo
gu, wybierajc z menu File opcj Save all. Plik wynikowy tworzy si,
wybierajc z menu Build pozycj Build Solution lub wciskajc kla
wisz F6 (jeeli menu Build nie jest dostpne , mona je wczy przez
wybranie z menu Tools pozycji Settings i Expert settings). Plik wyko
nywalny zostanie zapisany w katalogu projektu (tam gdzie zosta za
pisany projekt) , w podkatalogu ./nazwa projektu/Bin/Release (bdzie
to aplikacja konsolowa i naley j uruchamia w wierszu polecei1) .

\!l

References
program.es

Rysunek 1 . 4. Plik program.es dodany do projektu


Studio .NET

pakiecie Visual

R o zd z i a 1.

P i e rwsza a p l i k a c j a

21

Gdyby kod mia by pisany bezporednio w edytorze Visual C#, na


ley postpi inaczej ni w wiczeniach 1 . 2 i 1 . 3 . Do wyboru s dwa
sposoby - mona napisa cay kod od zera lub te nakaza pakietowi
wygenerowanie szkieletu aplikacji i dopiero ten szkielet wypeni
instrukcjami. Do wicze z tej ksiki lepszy jest sposb pierwszy,
jako e kod generowany automatycznie bdzie si nieco rni od pre
zentowanych dalej przykadw. W dwch kolejnych wiczeniach zo
stanie jednak pokazane , jak zastosowa oba sposoby.
WICZENIE

Dodawanie nowego pliku do istniejcego projektu

W Visual C# utwrz pusty projekt (Empty Project), dodaj do projektu


nowy plik i zapisz w nim kod wiczenia 1 . 1 .
Po utworzeniu projektu, analogicznie jak w wiczeniu 1 . 3 , nale y
z menu Project wybra pozycj Add New Item. W kolejnym oknie trzeba
zaznaczy ikon Code File, w polu Name wpisa nazw pliku, w ktrym
chcemy umieci kod programu, i klikn Add (iysunek 1 . 5). Nastpnie
w edytorze naley wprowadzi instrukcje z wiczenia 1 . 1 . Utworzony
w ten sposb projekt kompilujemy w sposb opisany w wiczeniu 1 . 3 .
Add New Item - Project2

Sort by:

Installed Te m piates

Default

Search Imtalled Templates

Type:

Visual (# ltems
ADO.NET EntityObject G. Visual C# ltems
Oni me Templates

Visual C# Items

A blank

C# code file

ADO.NET Self-Tracking E. Visual C# ltems

Application Configuratio. Visual C# Items

Application Manifest File

Visual('# ltems

Assembly Information File Visual C# ltems

I EJ

ame:

Code File

Visual C# ltems

DataSet

Visual C# !tenis

progr.am.c.s

Rysunek 1 . 5. Tworzenie nowego pliku z kodem rd!owym w Visual Studio

22

C#

WICZENIE

w i cz e n i a

Tworzenie projektu konsolowego

W Visual C# utwrz projekt konsolowy C# (C onsole Application)


i zapisz w nim kod realizujcy zadanie z wiczenia 1 . 1 .
Tym razem po uruchomieniu Visual C# z menu File rwnie wybiera
my pozycj New Project, jednak zamiast ikony Empty Project odszuku
jemy Console Application i klikamy przycisk OK. Utworzony zostanie
szkielet aplikacji (rysunek 1 . 6) . Pomi dzy znakami nawiasu klam
rowego wystpujcego za stat i c vo i d Ma i n ( stri ng [ J a rgs ) wpisujemy
instrukcj :
Con sol e . W ri teli n e ( " Mj p i erwszy p rogram l " ) :

Kompilacj i uruchomienie programu wykonujemy tak, jak w po


przednich dwch wiczeniach.
ConsoleApplicationl - Microsoft Visual(# 2010 Express
file

!'_dit

lf_iew

Eroject

.S.uil'd

JO "'-l

Qebug
-

D9_ta

Iools

- "' -

!::!elp

OJ.;'Jc:;;J : : C'

!;; Solution 'ConsoleAppli cationl ' (1 project)

Busing system;

usi ng System.Collections.Generic;

using Syst,em. Linq;


using System.Text;

I{
I
El

!fil ConsoleApplicatiorntI

Bnamespace ConsoleApplicationl

El

1/- X

Properties

References

Program,cs

class Program

} }

static void Main(string[]

args)

Rysunek 1.6. Wygenerowany przez Visual Studio szldelet aplikacji konsolowej

R o zd z i a 1.

P i e rwsza a p l i k a c j a

23

Dyrektywa usi ng
We wszystkich dotychczasowych wiczeniach na pocztku kodu pro
gramu pojawiaa si dyrektywa us i ng System . Oznacza ona, e program
bdzie korzysta z klas zdefiniowanych w przestrzeni nazw System .
Przypomina to nieco instrukcj i mpo rt znan z Javy. Dziki takiemu
zapisowi kompilator wie", gdzie ma szuka klasy Conso l e i metody
Wri tel i ne, ktre wykorzystalimy do wywietlenia napisu na ekranie .

24

C#

w i cz e n i a

2
Zm ien ne i typy d a nych
Typy da nych
Zmienna to miejsce w programie, w ktrym mona przechowywa
jakie dane, np . liczby czy cigi znakw. Kada zmienna ma swoj
nazw, ktra j jednoznacznie identyfikuje, oraz typ okrelajcy, jakiego
rodzaju dane moe ona przechowywa . Przykadowo zmienna typu
i nteger moe przechowywa liczby cakowite, a zmienna typu fl oat
liczby rzeczywiste .

Typy danych moemy podzieli na typy wartociowe (ang. value types),


do ktrych zaliczymy typy proste (inaczej podstawowe, ang. primitive
types, simple types), wyliczeniowe (ang. enum types) i strukturalne (ang .
struct types) oraz typy odnonikowe (referencyjne, ang. reference types),
do ktrych zaliczamy typy klasowe, interfejsowe , delegacyjne oraz
tablicowe . Nie naley si jednak przeraa t mnogoci. Na poczt
ku nauki wystarczy zapozna si z podstawowymi typami : prostymi
arytmetycznymi, typem bool ean oraz stri ng .

Typy arytmetyczne
Typy arytmetyczne, bdce podzbiorem typw prostych, mona po
dzieli na typy cakowitoliczbowe (ang . integral types) oraz typy
zmiennoprzecinkowe (zmiennopozycyjne, ang. floating-point types).

C#

26

w i cz e n i a

Pierwsze su do reprezentacji liczb cakowitych, drugie - liczb


rzeczywistych (z czci uamkow) . Typy cakowitoliczbowe w C# to :
D

s byte,

byte,

c h a r,

s ho rt,

us hort,

i nt,

u i nt,

l ong,

ul ong .

Zakresy moliwych do przedstawiania za ich pomoc liczb oraz ilo


bitw, na ktrych s one zapisywane, przedstawione zostay w tabeli
2 . 1 . Okrelenie ze znakiem" odnosi si do wartoci, ktre mog by
dodatnie lub ujemne , natomiast bez znaku" - do wartoci nie
ujemnych.
Tabela 2.1. Typy calkowitoliczbowe w C#
Nazwa typu

Zakres reprezentowanych liczb

Znaczenie

sbyte

od- 1 28 do 1 27

8-bitowa liczba
ze znakiem

by te

char

od O do 2 5 5
u+oooo to u+FFFF

8-bitowa liczba
bez znaku
1 6-bitowy znak
Unicode

s h ort

u s hort
1 nt

u1 nt

od - 3 2 7 68 (- 215 ) do 3 2 7 67 ( 215- 1)
od O do 65 5 3 5 ( 216 - 1)
od - 2 1 47 48 3 648 (- 231 )

1 6-bitowa liczba
ze znakiem
1 6-bitowa liczba
bez znaku
3 2-bitowa liczba

do 2 1 47 48 3 647 ( 231- 1)

ze znakiem

od O do 4 29 4 9 67 29 5 ( 232 - 1)

3 2-bitowa liczba
bez znaku

R o z d z i a 2.

Zm i e n n e i t y p y d a n y ch

Tabela 2.1. Typy calkowitoliczbowe w C#

27

cig dalszy

Nazwa typu

Zakres reprezentowanych liczb

Znaczenie

l ong

od -9 2 2 3 37 2 0 3 6 8 5 4 77 5 8 08

64-bitowa liczba

(- 263 ) do9 223 37 2 0368 54 77 5 8 07

ze znakiem

( 263_ 1)

ul ong

od O do 18 4467 44 07 3 7 09 5 5 1 61 5

64-bitowa liczba
bez znaku

Typ c h a r suy do reprezentacji znakw, przy czym w C# jest on 16bitowy i zawiera znaki Unicode ( Unicode to standard pozwalajcy na
zapisanie znakw wystpujcych w wikszoci jzykw wiata) . Po
niewa kod Unicode to nic innego jak 1 6-bitowa liczba, zosta zali
czony do typw arytmetycznych cakowitoliczbowych .
Typy zmiennoprzecinkowe wystpuj tylko w trzech odmianach:
o

fl oat,

doubl e,

dec i ma l .

Zakres oraz precyzja liczb , jakie mona za ich pomoc przedstawi,


przedstawione s w tabeli 2 . 2 . Typ dec i ma l suy do reprezentowania
wartoci, dla ktrych waniejsza jest precyzja, a nie maksymalny za
kres reprezentowanych wartoci (np . danych finansowych) .
Tabela 2.2. Typy zmiennoprzecinkowe w C#
Nazwa typu

Zakres reprezentowanych liczb

fl oat

od - 3 I 4x 1 038do + 3 I 4x 1 038

doubl e

od 5,0 X 1 0-324 do

dec i ma l

od-7 ,9x 1 0-28do +7 .9x 1 028

0
1 ,7 X 1 03 8

Precy zja
7 miejsc po przecinku
1 5 I ub 1 6 cyfr
28 lub 29 cyfr

Typ bool (Boolean)


Zmienne tego typu mog przyjmowa tylko dwie wartoci : true i fa l s e
(prawda i fasz) . S one uywane przy konstruowaniu wyrae logicz
nych, porwnywania danych oraz wskazywania, czy dana operacja
zakof1czya si sukcesem. Uwaga dla osb znajcych C albo C++:

C#

28

w i cz e n i a

wartoci true i fa l s e nie maj przeoenia na wartoci liczbowe, tak


jak w wymienionych jzykach. Oznacza to, e poniszy fragment
kodu jest niepoprawny.
i n t zmi enna
i f(zmi enna ) {

O:

//instrukcje

W takim przypadku bd zostanie zgoszony ju na etapie kompilacji,


bo nie istnieje domylna konwersja z typu i nt na typ boo l wymagany
przez instrukcj i f.

Dekla rowa nie zm ien nych


Aby w programie uy jakiej zmiennej, wpierw trzeba j zadeklarowa,
tzn. poda jej typ oraz nazw . Oglna deklaracja wyglda w sposb
nastpujcy:
typ_zmi enneJ nazwa_zmi enneJ :

Po takim zadeklarowaniu zmienna jest ju gotowa do uycia, tzn. mo


na jej przypisywa rne wartoci bd te wykonywa na niej rne
operacje, np . dodawanie . Pierwsze przypisanie wartoci zmiennej
nazywa si inicjalizacj zmiennej lub inicjacj zmiennej.
Jeli chcemy wywietli zawarto zmiennej na ekranie, wystarczy
uy, tak jak w wiczeniu 1 . 1 , instrukcji Consol e . Wri teli ne, podajc
nazw zmiennej jako parametr:
Con sol e . Wri tel i n e ( nazwa_zmiennej ) ;

Jeeli jednak chcemy rwnoczenie wywietli jaki acuch znakw


(napis), moemy wykona to w sposb nastpujcy:
Con sol e . W ri teli n e ( " n api s " + nazwa_zmienneJ ) :

Jeeli zmiennych jest kilka i maj wystpowa w rnych miejscach


acucha znakowego, najlepiej zastosowa kolejn instrukcj :
Con sol e . W ri tel i n e ( "zml {O} . zm2 { l } " , zml . zm2) :

W takiej sytuacji w miejsce cigu znakw {O} zostanie wstawiona war


to zmiennej zml, natomiast w miejsce { 1} - warto zmiennej zm2.

R o z d z i a 2.

WICZENIE

Zm i e n n e i t y p y d a n y ch

29

Wywietlanie wartoci zmiennych arytmetycznych

Zadeklaruj dwie zmienne cakowite i przypisz im dowolne wartoci .


Wywietl wartoci zmiennych na ekranie, tak jak na rysunku 2 . 1 .
u s i n g Sy stem ;
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

i n t pi erwszali czba ;
i n t drugal i czba ;
pi erws z a l i czba
10 ;
drugal i czba
20 ;
Con sol e . Wr i teli n e ( " P i erwsza l i czba : " + pi erws z a l i czba ) ;
Con sol e . Wr i tel i n e ( " D ruga l i czba : " + d ruga li czba ) ;
=

111 C:\Windows\system32\cmd.exe

Rysunek 2.1. Wynik dziaania programu z wiczenia 2. 1


W programie powstay dwie zmienne typu i nt, czyli mogce prze
chowywa wartoci cakowite : pi erws zal i czba i d ruga l i czba . Pierwszej
z nich przypisana zostaa warto 1 0, a drugiej - warto 20. W ostat
nich dwch instrukcjach wartoci zmiennych zostay wywietlone na
ekranie . Uyty zosta opisany wyej sposb , w ktrym napis ujty
w znaki cudzysowu jest czony ze zmienn (wartoci zmiennej) za
pomoc znaku +.

Warto zmiennej mona przypisa ju w trakcie deklaracji (mamy


wtedy do czynienia z jednoczesn deklaracj i inicjalizacj), piszc :
typ_zmi ennej nazwa_zmi ennej

warto ;

C#

30

w i cz e n i a

Mona rwnie zadeklarowa wiele zmiennych danego typu, oddziela


jc ich nazwy przecinkami . Cz z nich moe te by od razu zaini
cjalizowana :
typ_zmi ennej nazwal . nazwa2 . nazwa3 :
typ_zmi ennej nazwal
wartol . nazwa2 . nazwa3
=

warto2 :

Zmienne w C#, podobnie jak w Javie, C czy C + + , ale inaczej ni


w Pascalu, mona deklarowa praktycznie w dowolnym miejscu pro
gramu, czyli wtedy, gdy s faktycznie potrzebne .
WICZENIE

Jednoczesna deklaracja i inicjalizacja zmiennych

Zadeklaruj i jednoczenie zainicjalizuj dwie zmienne typu cakowitego.


Wywietl ich wartoci na ekranie .
u s i n g Sy stem ;
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

i n t pi erwszali czba
10 ;
i n t drugal i czba
20 ;
Con sol e . Wr i teli n e ( " P i erwsza l i czba : " + pi erws z a l i czba ) ;
Con sol e . Wr i tel i n e ( " D ruga l i czba : " + d ruga Li czba ) ;
=

Rozwizanie wiczenia jest bardzo podobne do poprzedniego przy


kadu. Tym razem jednak deklaracje zmiennych zostay poczone z ich
inicjalizacj (przypisaniem pierwotnych wartoci) .

Naley zwrci uwag , e - co prawda - zmienna nie musi by


zainicjalizowana w momencie deklaracji, ale musi by zainicjalizo
wana przed pierwszym jej uyciem. Jeli tego nie zrobimy, zostanie
zgoszony bd kon1pilacji (rysunek 2 . 2) . Sprawdzin1y to, wykonujc
kolejne wiczenie .

R o z d z i a 2.

Zm i e n n e i t y p y d a n y ch

31

iii C:\Windows\system32\ cmd .exe

Rysunek 2.2. Prba wykorzystania niezainicjalizowanej zmiennej powoduje


blqd kompilacji

WICZENIE

Konieczno inicjalizacji zmiennych przed uyciem

Zadeklaruj kilka zmiennych typu cakowitego w je dnym wierszu .


Cz z nich zainicjalizuj . Sprbuj wywietli wartoci wszystkich
zmiennych na ekranie .
u s i n g Sy stem ;
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

i n t pi erwszali czba
10 , druga l i czba
20 , i , j , k ;
Con sol e . Wr i teli n e ( " p i erws z a l i czba : " + p i e rwsza l i czba ) :
Con sol e . Wr i teli n e ( " d ruga l i czba : " + drugal i czba ) ;
Con sol e . Wr i teli n e ( "zmi enn a i : " + i ) ;
Con sol e . Wr i teli n e ( "zmi enn a j : " + j ) ;
Con sol e . Wr i teli n e ( "zmi enn a k : " + k ) ;
=

Zgodnie z przewidywaniami, przedstawionego programu nie udao


si skompilowa, co jest widoczne na rysunku 2 . 2 . Powodem jest
brak przypisania wartoci zmiennym i , j oraz k poczony z prb
odczytu ich zawartoci (w programie mona pozostawi niezainicja
lizowane zmienne, jeli nie nastpi prba ich uycia, cho zwykle nie
ma to sensu) .

C#

32

WICZENIE

w i cz e n i a

lnicjalizacja zmiennych

Popraw kod z wiczenia 2 . 3 tak, aby nie wystpoway bdy kompi


lacji. Skompiluj i uruchom otrzymany kod (rysunek 2 . 3 ) .
u s i n g Sy stem ;
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

i n t pi erwszali czba
10 , druga l i czba
20 , i , j , k
i
o;
j
o;
k
O;
Con sol e . Wr i teli n e ( " p i erws z a l i czba : " + p i e rwsza l i czba ) ;
Con sol e . Wr i teli n e ( " d ruga l i czba : " + drugal i czba ) ;
Con sol e . Wr i teli n e ( "zmi enn a i : " + i ) ;
Con sol e . Wr i teli n e ( "zmi enn a j : " + j ) ;
Con sol e . Wr i tell n e ( "zmi enn a k : " + k ) ;
=

ii C:\Windows\system32\cmd.exe

Rysunek 2.3. Prawidlowo zainicjalizowane zmienne mog zasta uyte


w programie

Nazewnictwo zmien nych


Przy nazywaniu zmiennych obowizuj pewne zasady. Nazwa taka
moe skada si z duych i maych liter oraz cyfr i znakw pokrelenia,
ale nie moe si zaczyna od cyfry . Stosowanie polskich znakw
(oglniej : wszelkich znakw narodowych) jest dozwolone, cho z reguy

R o z d z i a 2.

Zm i e n n e i t y p y d a n y ch

33

nie korzysta si z tej moliwoci, ograniczajc si wycznie do zna


kw alfabetu aciskiego (zaley to jednak od danego projektu pro
gramistycznego; czsto te stosuje si nazwy wywodzce si z jzyka
angielskiego) . Nazwa zmiennej powinna take odzwierciedla funkcj
penion w programie . Jeeli np . okrela ona liczb punktw w jakim
zbiorze, najlepiej j nazwa l i czba Pun ktow lub nawet l i czba P un ktow
4WZbi orze. Mimo e tak duga nazwa moe wydawa si dziwna, po
prawia jednak bardzo czytelno programu oraz uatwia jego analiz .
Naprawd warto ten sposb stosowa . Czsto przyjmuje si te, co
rwnie jest bardzo wygodne, e nazw zmiennej rozpoczynamy ma
liter, a poszczeglne czony tej nazwy (wyrazy, ktre si na ni ska
daj) piszemy wielk liter (tzw. zapis Iower camel case), dokadnie
tak, jak w powyszych przykadach.

Typy od noni kowe


Typy odnonikowe, nazywane rwnie referencyjnymi, su do de
klarowania zmiennych, ktre s odwoaniami do obiektw. Samymi
obiektami zajmiemy si dopiero w rozdziale 4 . , w tej chwili przyj
rzyjmy si tylko, w jaki sposb deklarujemy tego rodzaju zmienne .
Czynno ta jest wykonywana, podobnie jak w przypadku zmiennych
typw podstawowych, za pomoc instrukcji w postaci:
typ_zmi ennej nazwa_zmi ennej ;

lub :
typ_zmi ennej nazwa_zmi ennej_l . nazwa_zmiennej_2 . nazwa_zmi ennej_3 ;

W ten sposb zdeklarowane zostao jednak tylko tzw. odniesienie (ang .


reference) do zmiennej obiektowej , a nie sama zmienna . Takiemu
odniesieniu przypisana jest domylnie warto pusta (nul l ), czyli prak
tycznie nie mona wykonywa na niej adnej operacj i. Dopiero po
utworzeniu odpowiedniego obiektu w pamici mona powiza go z tak
zadeklarowan zmienn. Jeli zatem napiszemy :
i nt a ;

mamy gotow do uycia zmienn typu cakowitego . Moemy jej


przypisa np. warto 1 0 . eby jednak mona byo skorzysta z tabli
cy, musimy zadeklarowa zmienn odnonikow typu tablicowego,
utworzy obiekt tablicy i powiza go ze zmienn. Dopiero wtedy
bdziemy mogli swobodnie odwoywa si do kolejnych elementw.
Piszc zatem:

C#

34

w i cz e n i a

i n t [ ] tab l i ca ;

zadeklarujemy odniesienie do tablicy, ktra bdzie zawieraa elementy


typu i nt, czyli 32-bitowe liczby cakowite . Sama tablica powstanie do.
.
.
p1ero po przyp1san1u:
i n t [ ] tab l i ca = new i nt [ wie lko_tab l i cyJ ;

Tym tematem zajmiemy si bliej w rozdziale 5 .

Typ stri ng
Typ stri ng suy do reprezentacji ai1cuchw znakowych, inaczej
napisw. Jeli chcemy umieci w programie acuch znakw, napis,
naley go uj w cudzysw, czyli na jego pocztku i kocu umieci
znaki cudzysowu, np . :
"To j e s t n ap i s "

Nie jest to jednak typ bezporednio wbudowany w jzyk, jak ma to


miejsce w Pascalu, ale, podobnie jak w Javie, typ referencyjny (odno
nikowy) . Nie ma koniecznoci jawnego wywoywania konstruktora
klasy Stri ng, czyli zmienne mona deklarowa, tak jak zmienne typw
prostych, np . :
s t r i ng zmienna = "nap is " ;

Po takiej deklaracji utworzony zostanie jednak ob iekt klasy (typu)


stri ng, zatem na zmiennej zmienna moemy wykonywa dowolne opera
cje moliwe do wykonania na klasie str i ng 1

Typ object
Typ object jest typem nadrzdnym, z ktrego wyprowadzone s
wszystkie inne typy danych. Nazwa object jest aliasem dla typu Object
zdefiniowanego w przestrzeni nazw System (System . Obj ect) . Nie b
dziemy zagbia si w niuanse wewntrznej realizacji typw w C#,

1 Dokadniej rzecz ujmujc, sowo stri n g jest uywanym w C# aliasem dla

klasy Stri ng zdefiniowanej w przestrzeni nazw System i bdcej bezporednim


odwzorowaniem typu wsplnego S t r i n g wystpujcego w platformie .NET.
Rwnie pozostae typy proste s aliasami dla struktur z przestrzeni nazw
Sy stem.

R o z d z i a 2.

Zm i e n n e i t y p y d a n y ch

35

warto jedynie wspomnie, e w rzeczywistoci nawet typy proste s


typami referencyjnymi, a zmienne tych typw zachowuj si (cho
z pewnymi ograniczeniami) jak zmienne typw obiektowych! Oznacza
to np . , e mona dla takiej zmiennej wywoa metody danej klasy
(bd struktury) . Oto przykad :
i nt a
10 ;
s t r i ng b
a . ToStri n g ( ) ;
=

Co wicej, moliwe jest rwnie zastosowanie konstrukcji:


s t r i ng b

10 . ToSt ri n g ( ) ;

Te wiadomoci nie s jednak niezbdne na pocztku nauki C # .


Podane tu wyjanienia stan si te bardziej zrozumiae p o przeczy
taniu rozdziau 4.

Wa rto n u l l
Jest to pewien specjalny typ danych, ktry oznacza po prostu nic
(nul l ) . Wartoci te uywane s, gdy trzeba wskaza, e dana zmienna
referencyjna jest pusta, czyli nie zosta do niej przypisany aden
obiekt. Typ nul l wystpuje w wikszoci obiektowych jzykw pro
gramowania, w Object Pascalu (jzyku, na ktrym oparte jest rodo
wisko Delphi) zamiast nul l stosuje si sowo ni l .

O peratory
Poznalimy ju zmienne, musimy jednak wiedzie, jakie moemy
wykonywa na nich operacje . Operacje s wykonywane za pomoc
rnych operatorw, np . odejmowania, dodawania, przypisania itd .
Operatory te mona podzieli na nastpujce grupy:
D

arytmetyczne ,

bitowe,

logiczne,

przyp1san1a,

porwnania,

pozostae .

C#

36

w i cz e n i a

Ope rato ry arytmetyczne


Wystpujce w C# operatory arytmetyczne zostay przedstawione
w tabeli 2 . 3 . W praktyce korzystanie z wikszoci tych operatorw
sprowadza si do wykonywania typowych dziaa znanych z lekcji
matematyki. Jeli zatem chcemy doda do siebie dwie zmienne lub
liczb do zmiennej, wykorzystujemy operator +; gdy chcemy co po
mnoy - operator * itp . Oczywicie, operacje arytmetyczne wykonuje
si na zmiennych typw arytmetycznych .
Tabela 2.3. Operatory arytmetyczne
Operator
*

C#

Wy kony wane dziaanie


Mnoenie

Dzielenie

Dodawanie
Odejmowanie

Dzielenie modulo ( reszta z dzielenia)

++

l nkrementacja ( zwikszanie)
Dekrementacja ( zmniejszanie)

WICZENIE

Proste operacje arytmetyczne

Zadeklaruj dwie zmienne typu cakowitego . Wykonaj na nich kilka


operacji arytmetycznych. Wyniki wywietl na ekranie .
u s i n g Sy stem ;
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

i nt a . b . c ;
a = 10 ;
b = 25 ;
c = b - a;
Con sol e . Wr i teli n e ( " a = " + a ) ;
Con sol e . Wr i teli n e ( " b = " + b ) ;
Con sol e . Wr i teli n e ( " b - a = " + c ) ;

R o z d z i a 2.

Zm i e n n e i t y p y d a n y ch

37

c = a * b:
Con sol e . Wr i tell n e ( " a * b = " + c ) ;

Deklarujemy tu trzy zmienne typu cakowitoliczbowego o nazwach


a , b i c . Zmiennym a i b przypisujemy wartoci liczbowe, odpowied
nio 10 i 25, zmiennej c za wynik odejmowania b
a, czyli zawiera
ona bdzie liczb 15. Kolejne kroki to wywietlenie wynikw do
tychczasowych dziaa i przypisa na ekranie. Nastpnie przypisujemy
do zmiennej c wynik mnoenia a * b (czyli liczb 250) i warto tego
dziaania rwnie wywietlamy na ekranie .
-

Do operatorw arytmetycznych naley rwnie znak %, przy czym


nie oznacza on obliczania procentw, ale dzielenie modulo (reszt
z dzielenia) . Przykadowo wynik dziaania 12 % 5 wynosi 2 (bo 5 mieci
si w 1 0 dwa razy i pozostawia reszt 2) .
WICZENIE

Dzielenie modulo

Zadeklaruj kilka zmiennych . Wykonaj na nich operacje dzielenia


modulo. Wyniki wywietl na ekranie .
u s i n g Sy stem :
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

i nt a . b , c :
a = 10 ;
b = 25 ;
c = b % a;
Con sol e . Wr i teli n e ( " b % a = " + c ) ;
Con sol e . Wr i teli n e ( " l l % 3 = " + 1 1 % 3 ) ;
c = a * b;
Con sol e . Wr i tell n e ( " ( a * b ) % 120 = " + c % 120 ) ;

W kodzie wykonywane s w sumie trzy rne operacje dzielenia


modulo (uzyskiwania reszty z dzielenia) . Pierwsza obejmuje dwie
zmienne (b % a), druga - bezporednio dwie wartoci liczbowe (11 % 3),

C#

38

w i cz e n i a

a trzecia - zmienn i liczb (c % 120) . Uzyskujemy wic trzy rne


wyniki ( 5 , 2 i 1 O) , ktre s wywietlane na ekranie .

Kolejne operatory typu arytmetycznego to operator inkrementacji


i dekrementacji. Operator inkrementacji, czyli zwikszania, powoduje
przyrost wartoci zmiennej o jeden. Ma on posta ++ i moe wyst
powa w formie przyrostkowej bd prze drostkowej . Oznacza to,
e jeli istnieje zmienna o nazwie x, form przedrostkow bdzie ++x,
natomiast przyrostkow - x++.
Oba te wyraenia zwiksz warto zmiennej x o jeden, jednak wcale
nie s one rwnowane . Ot x++ zwiksza warto zmiennej po jej
wykorzystaniu, natomiast ++x przed wykorzystaniem. Takie rozr
nienie moe by niekiedy bardzo pomocne przy pisaniu programu.
WICZENIE

Operator inkrementacji

Przeanalizuj poniszy kod. Nie uruchamiaj programu, ale zastanw


si, jaki bdzie wywietlony cig liczb . Nastpnie po uruchomieniu
kodu sprawd swoje przypuszczenia .
u s i n g Sy stem :
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

{
/*] */
1*2 *1
1*3 *I
1*4 *1
1*5 *1
1*6 *1
1*7 *1
1*8 *1

1. y;
i nt X
Con sol e . W r i tel i n e ( ++x ) :
Con so l e . W r i tel i n e ( x++ ) :
Con sol e . W r i tel i n e ( x ) :
y
x++ :
Con so l e . W r i tel i n e ( y ) :
y
++x :
Con sol e . W r i tel i n e ( ++y ) :
=

Dla uatwienia poszczeglne kroki w programie zostay oznaczony


kolejnymi liczbami. Wynikiem dziaania tego kodu bdzie cig liczb
2 , 2, 3 , 3, 6 . Dlaczego? Na pocztku zmienna x przyjmuje warto 1 .
W kroku 2 . wystpuje operator ++x, zatem najpierw jest ona zwikszana
o jeden (x = 2), a dopiero potem wywietlana na ekranie . W wierszu

R o z d z i a 2.

Zm i e n n e i t y p y d a n y ch

39

o numerze 3 jest odwrotnie . Najpierw jest wywietlana warto


zmiennej x (x = 2), a dopiero potem zwikszana o 1 (x = 3) . W wier
szu 4. po prostu wywietlamy warto x (x = 3) . W wierszu 5 . naj
pierw zmiennej y przypisywana jest dotychczasowa warto x (x = 3,
y = 3), a nastpnie warto x jest zwikszana o jeden (x = 4) . W wier
szu 6 . wywietlamy warto y (y = 3) . W wierszu 7 . najpierw zwik
szamy warto x o jeden (x = 5), a nastpnie przypisujemy t warto
zmiennej y . W wierszu 8 . , ostatnim, zwikszamy y o jeden (y = 6)
i wywietlamy na ekranie .

Operator dekrementacji, czyli -- , dziaa analogicznie do ++ , ale zamiast


zwiksza wartoci zmiennych - zmniejsza je, oczywicie, zawsze
o jeden.
WICZENIE

Operator dekrementacji

Zmieli kod z wiczenia 2 . 7 tak, aby operator ++ zosta zastpiony


operatorem - - . Nastpnie przeanalizuj dziaanie powstaego programu
i sprawd, czy otrzymany wynik jest taki sam jak na ekranie po uru
chomieniu kodu .
u s i n g Sy stem ;
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

I* I */
1*2 *1
1*3 *1
1*4 *1
/*5 */
1*6 *1
/*7*/
1*8 *1

i nt X = l , y ;
Con sol e . W r i tel i n e ( - - x ) ;
Con sol e . W r i tel i n e ( x - - ) ;
Con sol e . W r i tel i n e ( x ) ;
y = X- - ;
Con so 1 e . W r i tel i n e ( y ) ;
y = - -x ;
Con sol e . W r i tel i n e ( - -y ) ;

Tym razem wynikiem dziaania programu bdzie cig liczb O , O , - 1 ,


-1, -4. Na pocztku zmienna x przyjmuje warto 1 . W kroku 2 . wyst
puje operator --x, zatem najpierw jest ona zmniejszana o jeden (x = O),
a dopiero potem wywietlana na ekranie. W wierszu o numerze 3 jest

C#

40

w i cz e n i a

odwrotnie . Najpierw warto zmiennej x jest wywietlana (x = O ) ,


a dopiero potem zmniejszana o 1 (x = - 1) . W wierszu 4 . p o prostu
wywietlamy warto x (x = - 1) . W wierszu 5 . najpierw zmiennej y
przypisywana jest dotychczasowa warto x (x = - 1 , y = - 1) , a na
stpnie warto x jest zmniejszana o jeden (x = -2) . W wierszu 6 . wy
wietlamy warto y (y = - 1) . W wierszu 7 . najpierw zmniejszamy
warto x o jeden (x = -3), a nastpnie przypisujemy t warto
zmiennej y. W wierszu 8 . , ostatnim, zmniejszamy y o jeden (y = -4)
i wywietlamy na ekranie .

Do operatorw arytmetycznych mona take zaliczy jednoargumen


towe operatory zmiany znaku, ktre zapisujemy jako + i - . Ich dzia
anie jest zgodne z zasadami matematyki, a wic zapis +wa rto nie
powoduje adnej zmiany [np . + 1 to plus jeden, natomiast + (-1 ) to
minus jeden] , natomiast -wa rto powoduje zmian wartoci na prze
ciwn [np . -(-1) to plus jeden, a -( + 1) i -(1) to minus jeden] .
Dziaania operatorw arytmetycznych na liczbach cakowitych nie
trzeba chyba dokadniej wyjania, z dwoma moe wyjtkami. Ot,
co si stanie, jeeli wynik dzielenia dwch liczb cakowitych nie b
dzie liczb cakowit? Odpowied - na szczcie - jest prosta : wynik
ten zostanie zaokrglony w d (odrzucona bdzie cz uamkowa) .
Zatem wynikiem dziaania 7/2 w arytmetyce liczb cakowitych bdzie 3
(prawdziwym" wynikiem jest 3 , 5 , ktra to warto jest zaokrglana
w d do najbliszej liczby cakowitej, czyli 3 ) .
WICZENIE

Dzielenie cakowitoliczbowe

Wykonaj dzielenie zmiennych typu cakowitego . Sprawd rezultaty


w sytuacji, gdy rzeczywisty wynik jest uamkiem.
u s i n g Sy stem ;
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

i nt
a
b
c
=

a. b. c;
8;
3;
2;

R o z d z i a 2.
Con sol e . Wr l tell n e ( " a
Con sol e . Wr l tell n e ( " b
Con sol e . Wr l tel1 n e ( " c
Con sol e . Wr l tell n e ( " a
Con sol e . Wr l tell n e ( " a
Con sol e . Wr l tell n e ( " b

=
=
=
I
I
I

Zm i e n n e i t y p y d a n y ch

41

" + a) :
" + b) :
" + c) :
b = " + a I b) :
c = " + a I c) ;
c = " + b I c) ;

Wykonywane s tu trzy rne dzielenia. Pierwsze to a I b, czyli 8/3 .


Jego rzeczywistym wynikiem jest 2 , (6), jednak ze wzgldu na uycie
arytmetyki cakowitoliczbowej na ekranie pojawi si 2, bowiem
cz uamkowa bdzie utracona. Drugie dzielenie to a I c , czyli 8/2 .
Ono nie budzi adnych wtpliwoci. Wynikiem jest po prostu 4 .
W trzecim przypadku wykonywana operacja to b I c, czyli 3/2 . Wa
ciwym wynikiem jest - oczywicie - 1 , 5 , jednak w wyniku zaokr
glenia powstanie warto 1 .

Drugim problemem jest to, co si stanie, jeeli przekroczmy zakres


jakiej zmiennej . Pamitamy np . , e zmienna typu s byte jest zapi
sywana na 8 bitach i przyjmuje wartoci od -1 28 do 1 2 7 (tabela 2 . 1) .
Sprbujmy zatem przypisa zmiennej tego typu warto 1 2 8 .
WICZENIE

Przekroczenie dopuszczalnego zakresu zmiennej


na etapie kompilacji kodu

Zadeklaruj zmienn typu s byte . Przypisz jej warto 1 2 8 . Sprbuj


wykona kompilacj otrzymanego kodu.
u s 1 n g Sy stem ;
publ 1 c cl a s s ma 1 n

publ 1 c stat1 c vo1 d M a 1 n ( )

sbyte zm1 en n a ;
zm1 enna = 1 28 ;
Con sol e . Wr l tell n e ( "zm1 enn a = " + zm1 en n a ) ;

42

C#

w i cz e n i a

Kompilacja tego przykadu nie powiedzie si (rysunek 2 .4) . Kompi


lator wykryje, e prbujemy przekroczy dopuszczalny zakres dla war
toci typu byte i nie pozwoli na to. Mona powiedzie, e w tego typu
sytuacji nie ma problemu.
ii C:\Windows\system32\cmd.exe

Rysunek 2.4. Prba przekroczenia dop uszczalnego zakresu zmiennej


powoduje blqd kompilacji

Niestety, kompilator nie zawsze wykryje tego typu bd. Moe si


zdarzy, e zakres przekroczymy nie w trakcie kompilacji, ale pod
czas wykonywania programu. Co si wtedy stanie? Mona si o tym
przekona, wykonujc kolejne wiczenie .
WICZENIE

Przekroczenie dopuszczalnego zakresu zmiennej


na etapie wykonania programu

Zadeklaruj zmienn typu sbyte i przypisz jej warto 127. Nastpnie wy


konaj operacj arytmetyczn zwikszajc warto zmiennej, a zatem
powodujc przekroczenie dopuszczalnej wartoci. Wywietl wynik
na ekranie .
u s i n g Sy stem :
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

sbyte zmi en n a :
zmi enna = 1 2 7 :
zmi enna++ :
Con sol e . Wr i teli n e ( "zmi enn a = " + zmi en n a ) :

R o z d z i a 2.

Zm i e n n e i t y p y d a n y ch

43

Po uruchomieniu kodu okae si, e zmienna ma warto . . . -1 2 8 .


Skd ten wynik, wszak 1 2 7 + 1 to z pewnoci nie jest -1 28? Ponie
wa maksymaln wartoci dla typu s byte jest 1 2 7 , zmienna takiego
typu nie moe przyj prawidowej wartoci, czyli 1 2 8 . Std nast
puje, mona powiedzie, przekrcenie licznika" , co zobrazowano na
rysunku 2 . 5 .

,,

-128 -127 -126

"

z ak r e s

127

typu

128

129

s byte

Rysunek 2.5. Przekroczenie dop uszczalnego zakresu dla -typu sbyte

Ope rato ry bitowe


Operatory bitowe , jak sama nazwa wskazuje, su do wykonywania
operacji na bitach. Przypomnijmy zatem podstawowe wiadomoci
o systemach liczbowych. W systemie dziesitnym wykorzystywanych
jest dziesi cyfr, od O do 9, w systemie szesnastkowym dodatkowo
litery od A do F, a w systemie semkowym cyfry od O do 7 . W sys
temie dwjkowym bd zatem wykorzystywane jedynie dwie cyfry,
O i 1 . Kolejne liczby budowane s z tych dwch cyfr dokadnie tak
samo jak w systemie dziesitnym, przedstawiono to w tabeli 2 .4 . Wida
wyranie, e np . 4 dziesitnie to 1 00 dwjkowa, a 1 0 dziesitnie, to
1 0 1 0 dwjkowa.
Tabela 2.4. Reprezentacja liczb w systemie dwjkowym i dziesitnym
sy stem dwjkow y

sy stem dziesitny

10

11

1 00

C#

44

w i cz e n i a

Tabela 2.4. Reprezentacja liczb w systemie dwjkowym i dziesitnym


-

ciqg dalszy

sy stem dwjkow y

sy stem dziesitny

1 01

1 1o

111

1 000

1 001

1 01 0

10

1 01 1

11

1 1 oo

12

1 1 01

13

1 1 1o

14

1111

15

Na tak zdefiniowanych liczbach mona wykonywa znane ze szkoy


operacje bitowe , takie jak AND (iloczyn bitowy), OR (suma bitowa) , XOR (bi
towa alternatywa wykluczajca) oraz negacj a bitowa. Symbolem opera
tora AND jest znak ampersand (&) , operatora OR - pionowa kreska ( I ) ,
operatora XOR - daszek, strzaka w gr ('') , negacji - tylda (-) . Do
datkowo dostpne s take operacje przesuni bitw w prawo i w le
wo. Zestawienie tych operacji przedstawione jest w tabeli 2 . 5 .
Tabela 2. 5. Operatory bitowe
Rodzaj dziaania

Sy mbol w C#

bitowe AND

&

bitowe OR
bitowe XOR
bitowa negacja
przesunicie bitowe w lewo

<<

przesunicie bitowe w prawo

>>

R o z d z i a 2.

Zm i e n n e i t y p y d a n y ch

45

Ope rato ry logiczne


Argumentami operacji takiego typu musz by wyraenia posiadaj
ce warto logiczn, czyli true lub fa l se (prawda lub fasz) . Przyka
dowo wyraenie 10 < 20 jest niewtpliwie prawdziwe (10 jest mniejsze
od 20), zatem jego warto logiczna jest rwna true. W grupie tej wy
rniamy trzy operatory: logiczne AND (&&, &) , logiczne OR ( 1 1 , I ) i lo
giczn negacj ( ! ) .
Warto zauway, e w czci przypadkw stosowania operacji lo
gicznych, aby otrzyma wynik, wystarczy obliczy tylko pierwszy
argument. Wynika to - oczywicie - z waciwoci operatorw, bo
jeli wynikiem obliczenia pierwszego argumentu jest warto true,
a wykonujemy operacj OR, to niezalenie od stanu drugiego argumentu
wartoci caego wyraenia bdzie t r u e . Podobnie przy stosowaniu
operatora AND, jeeli wartoci pierwszego argumentu bdzie fa l se, to
i wartoci caego wyraenia rwnie bdzie fa l s e .
Dlatego te w C # mamy p o dwa operatory sumy oraz iloczynu. Jeli
uyjemy symboli & i I , przetwarzane jest cae wyraenie niezalenie od
stanu argumentw, natomiast dla symboli && i 1 1 uywane jest opisane
wyej skrcone przetwarzanie wyraei1 (jeeli obliczenie jednego ar
gumentu umoliwia ustalenie wyniku, pozostae argumenty nie s
przetwarzane) .

Ope rato ry przypisania


Operacje przypisania s dwuargumentowe i powoduj przypisanie
wartoci argumentu znajdujcego si z prawej strony do umieszczo
nego z lewej . Najprostszym operatorem tego typu jest klasyczny znak
rwnoci, np . : zmi enna = 3 . Oprcz niego mamy do dyspozycji opera
tory czce klasyczne przypisanie z innym operatorem arytmetycznym
bd bitowym. Operatory przypisania wystpujce w C# zostay
przedstawione w tabeli 2 . 6 .

C#

46

w i cz e n i a

Tabela 2. 6. Operatory przypisania i ich znaczenie w C#

Argument1

Operator

X
X

+=

Argument2

Znaczenie

= y

+ y

*=

* y

/=

I y

%=

% y

&=

& y

i=
A

I y

A y

<<=

<< y

>>=

>> y

Ope ratory porwnania (relacyj ne)


Operatory porwnania su do porwnywania argumentw. Wyni
kiem takiego porwnania jest warto logiczna true (jeli jest ono
prawdziwe) lub fa l s e (jeli jest faszywe), np . wyraenie 2 < 3 ma
warto true, bo 2 jest mniejsze od 3 , a wyraenie 4 < 1 ma warto
fa l s e, bo 4 jest wiksze , a nie mniejsze od 1 . Do dyspozycji mamy
operatory porwnania zawarte w tabeli 2 . 7 .
Tabela 2. 7. Operatory porwnania w C#

Operator

Opis
Zwraca true , jeli argumenty s sobie rwne.

!=

Zwraca true , jeli argumenty s rne.

>

Zwraca t r u e , jeli argument lewostronny jest wikszy


od prawostronnego.

<

Zwraca true , jeli argument lewostronny jest mniejszy


od prawostronnego.

>=

Zwraca true , jeli argument lewostronny jest wikszy


lub rwny prawostronnemu.

<=

Zwraca true , jeli argument lewostronny jest mniejszy


lub rwny prawostronnemu.

R o z d z i a 2.

Zm i e n n e i t y p y d a n y ch

47

Operato r wa ru nkowy (?)


Operator warunkowy ma skadni nastpujc:
warunek ? wartol : warto2 :

Zapis ten naley rozumie tak: jeeli wa runek jest prawdziwy, wyra
enie przybiera wa rtoI , w przeciwnym przypadku
wa rto2. Aby
lepiej sobie to uzmysowi, wykonamy proste wiczenie .
-

WICZENIE

Uycie operatora warunkowego

Wykorzystaj operator warunkowy do zmodyfikowania wartoci do


wolnej zmiennej typu cakowitego (i nt) .
u s i n g Sy stem :
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

i nt X = l , y ;
y = ( X == 1 ) ? 1 0 : 20 ;
Con sol e . Wr i teli n e ( "y = " + y ) :

W powyszym wiczeniu najwaniejszy jest wiersz :


y = ( X == 1 ) ? 10 : 20 ;

ktry oznacza : jeeli x jest rwne 1, przypisz zmiennej y warto 1 0 ,


w przeciwnym przypadku przypisz zmiennej y warto 2 0 . Poniewa
zmienn x zainicjalizowalimy wartoci 1, na ekranie zostanie wy
wietlony cig znakw y = 1 0 . Nawias okrgy uyty w wyraeniu
nie jest formalnie konieczny, ale zwiksza czytelno kodu progra
mu i z reguy jest stosowany. Formalnie prawidowa byaby rwnie
instrukcja:
y = X == 1 ? 1 0 : 20 :

48

C#

w i cz e n i a

Pozostae operatory
Oprcz operatorw wymienionych wczeniej, w jzyku C# wyst
puje jeszcze kilkanacie innych, ktrych dokadne omwienie wy
kracza poza ramy tej ksiki. Zostay one jednak uwzgldnione w ta
beli w punkcie Priorytety operatorw" .

Priorytety ope rato rw


Skoro znamy ju operatory, musimy jeszcze wiedzie, w jakiej kolej
noci s wykonywane . Wiadomo np . , e mnoenie jest silniejsze"
od dodawania, zatem najpierw mnoymy, potem dodajemy. W C#
jest podobnie , sia kadego operatora jest cile okrelona. Przedsta
wiono to w tabeli 2 .82. Im wysza pozycja w tabeli, tym wyszy priory
tet operatora. Operatory znajdujce si na jednym poziomie (w jednym
wierszu) maj ten sam priorytet.
Tabela 2.8. Priorytegr operatorw w C#

Operatory

Sy mbole

wybr skadowej, wywoanie funkcji,

, ( ) , [ ] , ++, - - , new, typeof,


checked, unchecked , del egate

indeksowanie tablicy, inkrementacja

i dekrementacja przyrostkowa, tworzenie


obiektw, kontrola typw, delegacje
ustalenie znaku wartoci, negacje,

+, - , 1 , - , ++, - - , ( ), s i zeof

inkrementacja i dekrementacja przedrostkowa,


rzutowanie typw, ustalenie rozmiaru

mnoenie, dzielenie, dzielenie modulo

*, I , %

dodawanie, odejmowanie

+' -

przesunicia bitowe

<< , >>

relacyjne, testowanie typw

< , >, <=, >=, i s, a s

porwnania

== I I. =

bitowe AND

&

W tabeli uwzgldniono rwnie operatory wystpujce w C # ,


ale nieomawiane w ksice.

R o z d z i a 2.

Zm i e n n e i t y p y d a n y ch

Tabela 2.8. Priorytegr operatorw w C#

49

cig dalszy

Operatory

Sy mbole

bitowe XOR

bitowe OR
logiczne AND

&&

logiczne OR

1 1

obsuga przypisania null (nufl-coalescing)

??

warunkowy

przypisania, lambda

= , += , -= , *=, !=, %=, >>= , <<=,


&= , A = , I = , =>

Komenta rze
Komentowanie tekstu rdowego programu jest wane ze wzgldu na
zachowanie przejrzystoci. Zaniechanie tej czynnoci powoduje zwy
kle, e sam programista po pewnym czasie musi powici duo czasu
na analizowanie wasnego kodu. Oczywicie, w krtkich programach,
takich jakie prezentowane s w tej ksice, zazwyczaj nie trzeba uywa
komentarzy, naley jednak wiedzie, w jaki sposb mona je stosowa .
W C# istniej dwa sposoby zastosowania komentarza. Oba zapoy
czone z jzykw programowania C , C + + czy Java. Pierwszy typ
skada si z dwch ukonikw ( I ! ) , komentarz zaczyna si wtedy od
miejsca wystpienia tych dwch znakw i obowizuje do koi1ca danej
linii.
Drugi rodzaj komentarza zaczyna si od sekwencji znakw /*, a ko
czy sekwencj */ . Jest to tzw. komentarz blokowy, jako e cay blok
tekstu znajdujcy si pomidzy wymienionymi sekwencjami znakw
jest ignorowany przez kompilator.
Naley pamita , e komentarzy blokowych nie wolno zagnieda .
Uycie sekwencji w postaci :
/*Komentarz blokowy
/*Komentarz zagniedony*/
*/

C#

50

w i cz e n i a

spowoduje bd kompilacji. Nic nie stoi natomiast na przeszkodzie ,


aby wewntrz komentarza blokowego uy komentarza skadajcego
si z dwch ukonikw:
/*Komentarz blokowy
I/Komentarz wewntrzny
*/

WICZENIE

Komentarz wierszowy

Uyj komentarza skadajcego si z dwch ukonikw do opisania


fragmentu kodu programu.
u s i n g Sy stem :
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

{
//inicjalzacja zmiennych

i nt X = l , y ;

//stwierdzenie, czy xjest rwne I

y = ( X == 1 ) ? 10 : 20 ;

//wypisanie wynikw na ekranie

Con sol e . Wr i teli n e ( "y = " + y ) :

WICZENIE

Komentarz blokowy

Uyj komentarza blokowego w kodzie programu z wiczenia 2 . 1 2 .


u s i n g Sy stem :
publ i c cl a s s ma i n

publ i c stati c voi d M a i n ( )

i nt X = l , y ;
I*
Przykad uycia komentarza blokowego.
W tym miejscu korzystamy z wyraenia warunkowego.
*/

y = ( X == l ) ? 10 : 20 ;
Con sol e . Wr i teli n e ( "y = " + y ) :

3
I nstru keje
I nstrukcje wa run kowe
I nstru kcja if. .. else
Bardzo czsto w programie trzeba sprawdzi jaki warunek i od tego,
czy jest on prawdziwy, czy faszywy, zaley dalsze wykonywanie
rnych instrukcji. Do takiego sprawdzania suy wanie instrukcja
warunkowa i f... e l s e . Ma ogln posta :
i f ( wyraen i e warunkowe )

{
//instrukcje do wykonania, jeeli warunekjest prawdziwy

el s e

{
//instrukcje do wykonania, jeeli warunekjestfaszywy

}
Sprbujmy zatem wykorzysta tak instrukcj do sprawdzenia, czy
zmienna cakowita jest mniejsza od O .

52

C#

WICZENIE

w i cz e n i a

Wykorzystanie instrukcji if

Wykorzystaj instrukcj warunkow i f... el se do zweryfikowania, czy


warto zmiennej arytmetycznej jest mniejsza od O. Wywietl odpo
wiedni komunikat na ekranie .
u s i n g Sy stem :
publ i c cl a s s Program

publ i c stati c voi d Mai n ( str i n g [ J a rg s )

i n t zmi enna = - 5 :
i f ( zmi enna < 0 )

Con s o l e . W r i tel i n e ( " Zmi enna j e st mn i ej s za od zera . " ) :

el se

Con s o l e . W r i tel i n e ( " Zmi enna n i e j est mn i ej s za od zera . " ) :

Zawarta w kodzie instrukcja i f bada warunek zmi enna < O . Jeeli wa


runek jest prawdziwy (czyli warto zapisana w zm i enna jest mniejsza
od O) , wykonywana jest instrukcja z bloku i f. Gdy warunek jest fa
szywy (czyli warto zapisana w zmi enna nie jest mniejsza od O), wy
konywana jest instrukcja z bloku el se. Poniewa na pocztku zmiennej
zmi enna zostaa przypisana warto -5 , zostanie wykonany blok i f i na
ekranie pojawi si odpowiedni napis.

A teraz co nieco bardziej skomplikowane . Zajmijmy si klasycznym


przykadem obliczania pierwiastkw rwnania kwadratowego. Mamy
rwnanie w postaci :
A x x2 + B x x + C

O,

Aby obliczy jego rozwizanie, liczymy tzw. delt () , ktra rwna jest:
B2 - 4 x A x C .

Rozdzi a 3 .

I n stru kcj e

53

Jeeli delta jest wiksza od O, mamy dwa pierwiastki :


xl = - B +

./i

2xA

= -B-

.J"i

---

2xA

Jeeli delta jest rwna O, istnieje tylko jedno rozwizanie :


x =

-B

--

2xA

W przypadku trzecim, jeeli delta jest mniejsza od O , rwnanie nie


ma rozwiza w zbiorze liczb rzeczywistych . Skoro jest tutaj tyle
warunkw do sprawdzenia, to doskonay przykad do potrenowania
zastosowania instrukcji i f... e l s e . Aby nie komplikowa zagadnienia,
nie bdziemy si w tej chwili zajmowa wczytywaniem parametrw
rwnania z klawiatury, ale podamy je bezporednio w kodzie .
Przed przystpieniem do realizacji tego zadania trzeba si jeszcze
dowiedzie, w jaki sposb uzyska pierwiastek z danej liczby? Na
szczcie, nie jest to wcale skomplikowane, wystarczy skorzysta
z konstrukcji Math . Sqrt ( warto ) . Aby zatem dowiedzie si, jaki jest
pierwiastek kwadratowy z liczby 4, naley napisa :
Math . Sqrt ( 4 ) ;

Oczywicie, zamiast liczby mona te poda w takim wywoaniu


zmienn, a wynik dziaania wypisa na ekranie np . :
i n t pi erws z a l i czba = 4 ;
doubl e druga li czba = Math . Sqrt ( pi erws z a l i czba ) ;
Con sol e . W ri teL i n e ( druga L i czba ) ;

WICZENIE

Obliczanie pierwiastkw rwnania kwadratowego

Wykorzystaj operacje arytmetyczne oraz instrukcje i f.e l se do obli


czenia pierwiastkw rwnania kwadratowego o parametrach poda
nych bezporednio w kodzie programu . Wyniki wywietl na ekranie
(rysunek 3 . 1 ) .

C#

54

w i cz e n i a

u s i n g Sy stem :
publ i c cl a s s P i e rwi a stek

publ i c stati c voi d Mai n ( str i n g [ J a rg s )

doubl e parametrA = 1 . p a r amet rB =

pa rametrC = 4 :

Con sol e . Wr i teli n e ( " Pa rametry rwn a n i a : \n " ) ;


Con sol e . Wr i teli n e ( "A = " + pa ramet rA + " , B = " + pa rametrB +
" C = " + pa rametrC + " \ n " ) ;
i f ( pa rametrA == 0 )

Con so l e . W r i tel i n e ( "To n i e j es t rwn a n i e kwad r atowe : A = Q I " ) ;

el se

doub l e del ta = p a r ametr B * pa rametrB


i f ( del ta < 0 )

4 * pa ramet rA * pa rametrC :

Con sol e . Wri teL i n e ( " De l ta < O . " ) ;


Con sol e . Wr i tel i n e (
" Brak rozwi za w zbi orze l i czb rzeczywi stych " ) ;

el se

doub l e wyn i k ;
i f ( de l ta == 0 )

wyn i k = - pa rametrB I ( 2 * p a rametrA ) ;


Con s o l e . Wr i tel i n e ( " Rozwi zan i e : x = " + wyn i k ) ;

el se

wyn i k = ( - p a r ametr B + Math . Sqrt ( del ta ) ) I ( 2 * pa ramet rA ) ;


Con s o l e . Wr i te ( " Rozwi za n i e : xl = " + wyn i k ) ;
wyn i k = ( - p a r ametr B - Math . Sqrt ( del ta ) ) I ( 2 * pa ramet rA ) ;
Con s o l e . Wr i tel i ne ( " . x2 = " + wyn i k ) :

Na pocztku kodu s definiowane zmienne okrelajce parametry


rwnania, a ich wartoci wywietlane na ekranie . Nastpnie za po
moc pierwszej instrukcji warunkowej i f badany jest stan parametru A,
czyli zmiennej pa rametrA. Po stwierdzeniu, e zmienna pa rametrA

Rozdzi a 3 .

I n stru kcj e

55

rwna jest O, wywietlana jest informacja, e nie mamy do czynienia


z rwnaniem kwadratowym. W przeciwnym przypadku wykonywa
ne s instrukcje bloku el s e . Jest w nim obliczana delta, a nastpnie
wykonywana kolejna instrukcja i f badajca, czy delta jest mniejsza
od O . Jeli jest mniejsza, wywietlana jest informacja o braku rozwi
zai1. W przeciwnym razie (delta wiksza od O bd rwna O) w bloku
el s e jest wykonywana kolejna instrukcja warunkowa badajca tym
razem, czy delta jest rwna O . Gdy jest rwna O , jedyny wynik jest
obliczany i wywietlany na ekranie . W przeciwnym przypadku (delta
wiksza od O) obliczane s dwa pierwiastki i oba rozwizania poja
wiaj si na ekranie .
Rysunek 3.1.

Wynik dziaania
program u
obliczajcego
pierwiastki
rwnania
kwadratowego

I nstru kcja if. .. else if


Jak pokazano w wiczeniu 3 . 2 , instrukcj warunkow mona za
gnieda , tzn . po jednym i f moe wystpowa kolejne, po nim na
stpne itd. Jednake taka budowa kodu powoduje, e przy wielu za
gniedeniach staje si bardzo nieczytelny. Aby tego unikn, mona
wykorzysta instrukcj i f. .. e l s e i f. Zamiast tworzy mniej wygodn
konstrukcj, tak jak przedstawiona poniej :
i f ( warunekl ) {
//instrukcje I

el s e {
i f ( warunek2) {
//instrukcje2

el se {
i f ( warunek3 ) {
//instrukcje3

C#

56

w i cz e n i a

el se {
//instrukcje4

cao mona zapisa duo prociej i czytelniej w nastpujcej postaci:


i f ( wa runek] ) {

//instrukcje 1

e l s e i f ( warunek2 ) {
//instrukcje 2

e l s e i f ( warunek3 ) {
//instrukcje 3

el s e {
//instrukcje 4

}
WICZENIE

Wykorzystanie instrukcji if. .. else if

Zmodyfikuj program napisany w wiczeniu 3 2 tak, aby uywana


bya instrukcja i f... e l s e i f.
.

u s i n g Sy stem ;
publ i c cl a s s P i e rwi a stek
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
doubl e parametrA = 1 . p a r amet rB = 5
-

pa rametrC = 4 ;

Con sol e . Wr i teli n e ( " Pa rametry rwn a n i a : \n " ) ;


Con sol e . Wr i teli n e ( "A = " + pa ramet rA + " , B = " + pa rametrB +
" C = " + pa rametrC + " \ n " ) ;
i f ( pa rametrA == 0 )
{
Con s o l e . W ri teli n e ( "To n i e j est rwn an i e kwad r atowe : A = O ! " ) :

el se
{
doub l e del ta = p a r ametr B * pa rametrB
doub l e wyn i k :
i f ( de l ta < 0 )
{

4 * pa ramet rA * pa rametrC :

Rozdzi a 3 .

I n stru kcj e

57

Con sol e . Wr l tell n e ( " De l ta < O . " ) ;


Con sol e . Wr 1 tel 1 n e (
" Brak rozw1 za w zb1 orze 1 1 czb rzeczyw1 stych " ) ;

el se 1 f ( del ta == 0 )
{
wyn 1 k = - p a r amet rB I ( 2 * pa rametrA ) ;
Con sol e . Wr l teL1 n e C " Rozw1 zan 1 e : x = " + wyn 1 k ) ;

el se
{
wyn 1 k = ( - pa rametrB + Math . Sqrt ( de l ta ) ) I ( 2 * pa rametrA ) ;
Con sol e . Wr l te ( " Rozw1 zan 1 e : xl = " + wyn 1 k ) ;
wyn 1 k = ( - pa rametrB - Math . Sqrt ( de l ta ) ) I ( 2 * pa rametrA ) ;
Con sol e . Wrl tell n e ( " . x2 = " + wyn 1 k ) ;

I nstru kej a switch


Kiedy do sprawdzenia jest wiele warunkw, instrukcja swi tch po
zwala wygodnie zastpi cigi instrukcji i f... el se i f. Jeli mamy przy
kadowy fragment kodu :
1 f ( 1 1 czba == l ) {
//instrukcje I

e l s e 1 f C l 1 czba == 2 ) {
//instrukcje2

e l s e 1 f ( 1 1 czba == 3 ) {
//instrukcje3

el s e {
/linstrukcje4

}
moemy zastpi go poniszym:
sw1 tch ( 1 1 czba ) {
case 1 :
//instrukcje I;
brea k ;
case 2 :
//instrukcje2;

brea k ;

C#

58

w i cz e n i a

case 3 :
//instrukcje3;

brea k ;
defa u l t :
//instrukcje4,

brea k ;

}
Sprawdzamy tu po kolei, czy zmienna l i czba jest rwna 1 , potem 2
i w ko11cu 3 . Jeeli zgodno zostanie stwierdzona, wykonywane s
instrukcje po odpowiedniej klauzuli c a s e . Jeeli warto zapisana
w l i czba nie jest rwna adnej z wymienionych liczb , wykonywane
s instrukcje po sowie defa ul t . Instrukcja b r e a k powoduje wyjcie
z bloku swi tc h . Jeli zatem l i czba bdzie rwna 1 , zostan wykonane
instrukcje i nstrukcj el, jeli l i czba bdzie rwna 2 , zostan wykonane
instrukcje i nstrukcje2, jeli l i czba bdzie rwna 3 , zostan wykonane
instrukcje i nstrukcj e3 . Gdyby l i czba nie bya rwna ani 1 , ani 2, ani 3 ,
zostan wykonane instrukcje i nstrukcje4.
WICZENIE

Uycie instrukcji switch

Zadeklaruj zmienn typu cakowitego i przypisz jej dowoln war


to . Korzystajc z instrukcji swi tch, sprawd, czy warto ta rwna
jest 1 lub 2 . Wywietl odpowiedni komunikat na ekranie .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
i n t l i czba
1:
swi tch ( l i czba ) {
case 1 :
Con sol e . Wr i tel i n e ( " l i czba
l" ) ;
brea k :
case 2 :
Con sol e . Wr i tel i n e ( " l i czba
2" ) :
brea k :
defa u l t :
Con so l e . Wri tel i n e ( " Zmi enna l i czba n i e j est rwn a ani 1 . ani 2 . " ) ;
brea k :
=

Rozdzi a 3 .

I n stru kcj e

59

Warto w tym miejscu zauway, e w C#, inaczej ni w jzykach,


takich jak C , C + + czy Java, nie mona pomin instrukcji break po
wodujcej wyjcie z instrukcji swi tch . Prba taka skoczy si bdem
kompilacji (rysunek 3 .2) . cilej rzecz ujmujc, nie musi by to do
kadnie instrukcja brea k , ale dowolna instrukcja, w wyniku ktrej zo
stanie opuszczony blok swi tc h . Dokadniejsze wyjanienie i przykad
takiej konstrukcji znajduje si przy opisie instrukcji goto .
iii

C:\Windows\system32\cmd.exe

Rysunek 3.2. Prba pominicia instrukcji break ko11czy si bldem kompilacji

Ptl e
Ptle w jzykach programowania pozwalaj na wykonywanie powta
rzajcych si czynnoci. Dokadnie w ten sam sposb dziaaj one
rwnie w C # . Jeli chcemy np . wypisa na ekranie 1 0 razy napis C#,
moemy zrobi to, piszc 10 razy Consol e . Wri tel i ne( " C#" ) ; . Lepiej jednak
wykorzysta w tym celu ptle .

Ptla fo r
Ptla typu fo r ma nastpujca skadni :
for ( wyraen ie pocztkowe : wyraen i e warunkowe : wyraen i e modyfi kujce )
{
//instrukcje do wykonania

}
jest stosowane do zainicjalizowania zmiennej uy
wanej jako licznik liczby wykona ptli; wyraenie wa runkowe okrela
warunek, jaki musi by speniony, aby wykona kolejne przejcie w p
tli; wyraenie modyfikujce uywane jest zwykle do modyfikacji zmiennej
bdcej licznikiem.
wyraenie pocz tkowe

C#

60

WICZENIE

w i cz e n i a

Prosta ptla typu for

Wykorzystujc ptl typu fo r, napisz program wywietlajcy na ekranie


1 00 razy napis C#.
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
fo r ( i nt i = l ; i <= 100 ; i ++ )
{
Con so l e . W r i te ( " C# " ) ;

Wynik dziaania tego prostego programu widoczny jest na rysunku


3 . 3 . Zmienna i to tzw. zmienna iteracyjna, ktrej na pocztku przy
pisujemy warto 1 (i nt i = 1) . Nastpnie w kadym przebiegu ptli
jest ona zwikszana o 1 (i ++) i wykonywana jest instrukcj a Conso1 e . W r i t e ( " C# " ) : Wszystko trwa tak dugo, a i osignie warto 100
(i <= 1 0 0 ) . Warto zwrci uwag, e zamiast Consol e . Wrti eli ne uyty
zosta zapis Consol e . Wri te. Dziki temu kolejne napisy wywietlane s
obok siebie, bez przechodzenia za kadym razem do nowego wiersza
(przejcie jest wykonywane tylko wtedy, gdy napisy nie mieszcz si
w danym wierszu) .
mi C:\Win dows\system32\ c md.exe

c:I

C : \cs>program . exe
l!I
Cit ctt Cit ctt Cit ctt Cit ctt Cit ctt Cit ctt Cf! Cf! Cf! ctt Cf! Cf! ctt Cf! ctt Cit ctt Cit ctt Cit cIii
Cit ctt Cf! Cf! Cf! Cf! Cf! Cf! Cf! Cf! Cf! Cit ctt Cit ctt Cf! ctt Cit c tt Cf! ctt Cit ctt Cf! Cf! Cf!
# Cf! C# C# C# C# C# C# C# C # C# C# C# C# C# C# C# C# C# C# C# C# C# C# C# C# C
C# ctt C# ctt C# ctt C# ctt C# ctt C# C# C# C# C# C# C# C# Cli C#
C : \cs>_

Rysunek 3.3. Wynik dziaania ptli for z wiczenia

3.5

Wyraenie modyfikujce jest zwykle uywane do modyfikacji zmiennej


iteracyjnej . Tak modyfikacj mona je dnak wykona rwnie we
wntrz ptli. Struktura tego typu wyglda nastpujco :

Rozdzi a 3 .

I n stru kcj e

61

for ( wyraen ie pocztkowe ; wyraen i e warunkowe ; )


{
//instrukcje do wykonania
//wyraenie modyfikujce

}
WICZENIE

Wyraenie modyfikujce w bloku instrukcji

Zmodyfikuj ptl typu fo r z wiczenia 3 . 5 tak, aby wyraenie mody


fikujce znalazo si w bloku instrukcji fo r .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
fo r ( i nt i = l ; i <= 100 : )
{
Con so l e . W r i te ( " C# " ) ;
i ++ ;

Naley zwrci uwag, e mimo i wyraenie modyfikujce w wicze


niu 3 .6 jest wewntrz ptli, rednik znajdujcy si po i < = 100 jest nie
zbdny! Jeli o nim zapomnimy, kompilator zgosi bd (rysunek 3 .4) .
'5111 C:\Windows\system32\ c m d .exe

Rysunek 3.4. Pominicie rednika w ptli for powoduje blqd kompilacji

Kolejn ciekaw moliwoci jest poczenie wyraeil warunkowego


i modyfikujcego. Konkretnie naley spowodowa, aby wyraenie wa
runkowe byo jednoczenie wyraeniem modyfikujcym. Tworzenie
takich konstrukcji umoliwiaj np . operatory inkrementacji i de
krementacji.

C#

62

WICZENIE

w i cz e n i a

Poczenie wyraenia warunkowego i modyfikujcego

Napisz tak ptl typu fo r, aby wyraenie warunkowe byo jedno


czenie wyraeniem modyfikujcym.
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
fo r ( i nt i = l ; i ++ <= 10 0 ; )
{
Con s o l e . Wri te ( " C# " ) ;

Tak jak w poprzednich przykadach mona si w pozby rwnie


wyraenia pocztkowego. Naley je przenie przed ptl . Schematycz
na konstrukcja wyglda nastpujco :
wyraen i e pocztkowe ;
for ( ; wyraen i e warunkowe ; )
{
//instrukcje do wykonania

wyraen ie modyfi kujce

}
WICZENIE

Wyraenie pocztkowe przed ptl

Zmodyfikuj ptl typu fo r w taki sposb , aby wyraenie pocztkowe


znalazo si przed ptl, a wyraenie modyfikujce - wewntrz ptli.
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
i nt i = l ;
fo r ( ; i <= 100 ; )
{
Con so l e . W r i te ( " C# " ) ;

Rozdzi a 3 .

I n stru kcj e

63

i ++ ;

Skoro zaszlimy ju tak daleko w pozbywaniu si wyrae11 sterujcych,


usumy rwnie wyraenie warunkowe, bo i to jest moliwe !
WICZENIE

Usunicie wszystkich wyrae

Zmodyfikuj ptl typu fo r w taki sposb, aby wyraenie pocztkowe


znalazo si przed ptl, natomiast wyraenie modyfikujce i warun
kowe wewntrz ptli.
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
i nt i = l ;
fo r ( ; ; )
{
Con so l e . W r i te ( " C# " ) ;
i f ( i ++ >= 100 ) brea k ;

Jak wida, i tak ptl mona utworzy . Ponownie trzeba tu przy


pomnie, e redniki (tym razem ju dwa) w nawiasie wystpujcym
po fo r s niezbdne ! Warto te zwrci uwag na zmian kierunku
nierwnoci. Wczeniej sprawdzalimy, czy i jest mniejsze bd rwne
1 0 0 , a teraz, czy jest wiksze bd rwne . Dzieje si tak dlatego, e
we wczeniejszych wiczeniach kontrolowane byo, czy ptla ma si
dalej wykonywa, natomiast w obecnym sprawdzamy, czy ma si
zakoticzy . Przy okazji w przykadzie zostao pokazane, w jaki spo
sb wykorzystuje si instrukcj break w ptli (wczeniej bya uyta
w instrukcji swi tc h ; wiczenie 3 .4) . Suy ona do natychmiastowego
przerwania wykonywania ptli. Gdy zatem wystpi brea k, ptla ko
czy dziaanie .

C#

64

w i cz e n i a

Kolejna przydatna instrukcja, conti nue, powoduje rozpoczcie nastpnej


iteracji ptli - w miejscu jej wystpienia wykonywanie biecej
iteracji jest przerywane i rozpoczyna si kolejny przebieg . Najlepiej
zobaczy to na konkretnym przykadzie .
WICZENIE

Instrukcja continue w ptli for

Napisz program wywietlajcy na ekranie liczby od 1 do 20, ktre nie s


podzielne przez 2. Skorzystaj z ptli fo r i instrukcji conti nue.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
fo r ( i nt i = 1 : i <= 20 : i ++ )
{
i f ( i % 2 == 0 ) conti n u e :
Con so l e . W r i tel i n e ( i ) :

Wynik dziaania takiej aplikacji widoczny jest na rysunku 3 . 5 . Jak


pamitamy, % to operator dzielenia modulo - dostarcza reszt z dzie
lenia. W kadym przebiegu sprawdzamy, czy i modulo 2 jest rwne O
(czy reszta z dzielenia i przez 2 jest rwna O) . Jeli jest (zatem i jest
podzielne przez 2), przerywamy biec iteracj instrukcj conti nue
(tym samym rozpoczynamy kolejn iteracj) . W przeciwnym przy
padku (i modulo 2 jest rne od O) wykonujemy instrukcj Conso l e .
4-Wri tel i ne ( i ) . Ostatecznie na ekranie otrzymamy wszystkie liczby
od 1 do 20, ktre nie s podzielne przez 2 .

Oczywicie, ten sam program mona napisa bez uycia instrukcji


conti nue, co zostao pokazane w wiczeniu 3 . 1 1 .

Rozdzi a 3 .

I n stru kcj e

65

Rysunek 3.5.

Program
wywietlajcy
liczby od 1 do 20
niepodzielne
przez 2

WICZENIE

Liczby niepodzielne przez 2 bez instrukcji continue

Zmodyfikuj kod z wiczenia 3 .1 O tak, aby nie byo koniecznoci uycia


instrukcji cont i nue.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
fo r ( i nt i = l ; i <= 20 : i ++ ) {
if (i % 2 I= 0)
{
Con sol e . Wr i teli n e ( i ) :

Tym razem instrukcja wywietlajca warto i jest wykonywana tylko


wtedy, gdy prawdziwy jest warunek i % 2 ! = O, a wic wtedy, gdy
reszta z dzielenia i przez 2 jest rna od O (co oznacza, e warto i
jest nieparzysta) . Dziki takiej konstrukcji zosta osignity taki sam
efekt jak w wiczeniu 3 . 1 0, ale bez uycia instrukcji conti nue.

C#

66

w i cz e n i a

Ptla wh ile
Ptla typu for suy raczej do wykonywania z gry znanej liczby opera
cji (-wprowadzonej bezporednio lub zalenej np . od stanu zmiennej) ,
w ptli wh i l e zwykle nie jest ona znana (moe by np . wynikiem
dziaania pewnej funkcji) . Nie jest to - oczywicie - podzia obli
gatoryjny. Ptl wh i l e mona napisa tak, by bya dokadnym funk
cjonalnym odpowiednikiem ptli fo r, a ptl fo r tak, by bya odpo
wiednikiem ptli wh i l e . Oglna konstrukcja ptli typu wh i l e jest
nastpujca:
wh i l e ( wyraen i e warunkowe )
{
ins trukcje :

}
Instrukcje s wykonywane dopty, dopki wyraenie warunkowe jest
prawdziwe . Oznacza to, e gdzie w ptli musi nastpi modyfikacja
warunku bd te instrukcja break (oglniej mwic, dowolna instrukcja
powodujca opuszczenie ptli) . Inaczej ptla bdzie si wykonywaa
w nieskof1czono !
WICZENIE

Wykorzystanie ptli while

Napisz przy uyciu ptli typu wh i l e program wywietlajcy na ekra


nie 100 razy napis C#.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
i nt i = 1 :
wh i l e ( i <= 10 O )
{
Con s o l e . W r i teC " C# " ) ;
i ++

Rozdzi a 3 .

I n stru kcj e

67

Taka ptla dziaaa, dopki prawdziwy jest warunek i < = 1 0 0 . Po


niewa pocztkow wartoci i jest 1, a we wntrzu ptli warto tej
zmiennej w kadym przebiegu jest zwikszana o 1 ( i ++) , ptla (a tym
samym instrukcja Consol e . Wr i te ( " C# " ) ; ) zostanie wykonana dokad
nie 100 razy.
WICZENIE
3. 1 3

Poczenie wyraenia modyfikujcego i warunkowego

Zmodyfikuj kod z wiczenia 3 . 1 2 tak, aby wyraenie warunkowe


zmieniao jednoczenie warto zmiennej i .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
i nt i = 1 :
wh i l e ( i ++ <= 10 0 )
{
Con so l e . W r i te ( " C# " ) :

WICZENIE
3. 1 4

Ptla while i liczby nieparzyste

Korzystajc z ptli wh i l e, napisz program wywietlajcy na ekranie


liczby od 1 do 20 niepodzielne przez 2 .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
i nt i = 1 :
wh i l e ( i <= 20 )
{
if (i % 2 I= 0)
{
Con sol e . Wr i teli n e ( i ) :

C#

68

w i cz e n i a

i ++ ;

Naley zauway, e w tym przypadku nie mona skorzysta z kon


strukcji takiej jak w poprzednim wiczeniu. Tym razem zmienna ite
racyjna i jest modyfikowana we wntrzu ptli. Dzieje si tak dlatego,
e wewntrz korzystamy z wartoci zapisanej w i . Gdybymy zatem
napisali ptl t w postaci wh i l e ( i ++ < = 20 ) , otrzymalibymy na
ekranie liczby od 2 do 21 niepodzielne przez 2, co byoby niezgodne
z zaoeniami programu (cho mona zmieni konstrukcj kodu, tak aby
moliwa bya modyfikacja zmiennej i w wyraeniu warunkowym) .

Ptla do

wh ile

Oprcz przedstawionej ju ptli wh i l e, istnieje inna jej odmiana; jest


to do.wh i l e . Jej konstrukcja jest nastpujca :
do
{

ins trukcje ;

wh i l e ( warunek ) :

Zapis ten oznacza : wykonuj inst rukcje dopty, dopki wa runek jest
prawdziwy. Sprbujemy zatem wykona zadanie przedstawione w wi
czeniu 3 . 1 2 , ale skorzystamy z ptli typu do ...wh i l e .
WICZENIE

Wykorzystanie ptli do . . . while

Napisz przy uyciu ptli do...wh i l e program wywietlajcy na ekranie


1 00 razy napis C#.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
i nt i
l;
=

Rozdzi a 3 .
do
{

I n stru kcj e

69

Con so l e . W r i te ( " C# " ) ;

wh i l e ( i ++ < 100 ) ;

Mogoby si wydawa, e to przecie to samo, co zwyka ptla wh i l e .


Wydaje si wrcz, e to po prostu odwrcona ptla wh i l e . Jest jednak
pewna rnica powodujca, e wh i l e i do wh i l e nie s dokadnymi od
powiednikami . W ptli do wh i l e instrukcje wykonane bd co najmniej
raz, nawet wtedy, kiedy warunek jest na pewno faszywy. Dzieje si
tak dlatego, e sprawdzenie warunku zakoczenia ptli odbywa si
dopiero po jej pierwszym przebiegu.
...

...

WICZENIE
3. 1 6

Ptla do while z faszywym warunkiem


.

Zmodyfikuj kod z wiczenia 3 . 15 w taki sposb, aby wyraenie warun


kowe na pewno byo faszywe. Zaobserwuj wyniki dziaania programu.
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
i nt i
10 1 ;
do
{
Con so l e . W r i te ( " C# " ) ;
=

wh i l e ( i ++ < 100 ) ;

Tym razem, mimo e warunek by faszywy (pocztkowa warto


zmiennej i to 1 0 1 , ktre na pewno jest wiksze ni uyte w wyrae
niu warunkowym 1 0 0 ) , na ekranie pojawi si jeden napis C#.

Jeszcze dobitniej fakt wykonania jednego przebiegu ptli niezalenie


od prawdziwoci warunku mona pokaza, stosujc konstrukcj :

C#

70
do
{

w i cz e n i a

Con s o l e . W r i te ( " C# " ) ;

wh i l e ( fa l s e ) :

W tym przypadku ju na pierwszy rzut oka wida , e warunek jest


faszywy. Mimo to, instrukcja z wntrza ptli zostanie wykonana je
den raz.

Ptla fo reach
Ptla typu foreach suy do przegldania zawartoci tablicy lub ko
lekcji obiektw. Jej opis zostanie podany w rozdziale 5 .

I nst rukcja goto


Instrukcja goto, czyli instrukcja umoliwiajca skok do okrelonego
miejsca w programie, od dawna jest uznawana za niebezpieczn i po
wodujc wiele problemw. Niemniej w C# jest obecna, cho zaleca
si jej stosowanie jedynie w przypadku blokw swi tch.case oraz wy
chodzenia z zagniedonych ptli, w ktrych to sytuacjach jest fak
tycznie uyteczna. Schemat jej uycia jest nastpujcy:
goto etyk i eta ;

gdzie etykieta jest zdefiniowanym miejscem w programie . Nie mona


jednak w ten sposb wskoczy" do bloku instrukcji, tzn . nie jest
moliwa konstrukcja:
for ( i n t j = O : j < 500 : j ++ )
{
i f( j == 100 ) goto l abel l ;

for ( i n t i = O : i < 1 0 0 0 : i ++ )
{
l abe 1 1 : ;

}
Nic jednak nie stoi na przeszkodzie , aby zdefiniowa etykiet przed
1ub za drug ptl, piszc :

Rozdzi a 3 .

I n stru kcj e

71

for ( i n t j = O : j < 5 0 0 : j ++ )
{
i f( j == 1 0 0 ) goto l abel l :
}
l abel l :
for ( i n t i = O : i < 1 0 0 0 : i ++ )
{
}

Taki kod jest ju jak najbardziej poprawny.


WICZENIE

Przerwanie zagniedonej ptli za pomocq goto

Napisz przykadowy program, w ktrym instrukcja goto jest wyko


rzystywana do wyjcia z zagniedonej ptli fo r.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
fo r ( i n t i = O ; i < 5 0 0 ; i ++ )
{
fo r ( i n t j = O ; j < 1 0 0 0 ; j++ )
{
i f ( ( i == 1 0 0 ) && ( j > 200 ) )
{
go to l abe 1 1 :
}
}
}
return :
l a bel l :
Con sol e . Wr i teli n e ( " Ptl a zosta a p rzerwan a I " ) ;
}
}

Wykorzystujemy tutaj dwie ptle, zewntrzn, gdzie zmienn itera


cyjn jest i , oraz wewntrzn, gdzie zmienn iteracyjn jest j . We
wntrz drugiej ptli znajduje si warunek, ktry naley odczytywa
nastpujco : jeeli i rwne jest 1 0 0 oraz j jest wiksze od 2 0 0 , id do
miejsca w kodzie oznaczonego etykiet l abel 1 . Zatem po osigniciu
warunku ptle zostan przerwane, na ekranie zostanie wywietlony
napis Ptl a zosta a przerwa na, a aplikacja zakoczy dziaanie .

C#

72

w i cz e n i a

Naley zauwazyc , e przed etykiet znajduje si instrukcja return


powodujca zakoi1czenie dziaania funkcji (metody) Ma i n, co jest rwno
znaczne z zakoczeniem dziaania programu. Gdyby jej nie byo, na
pis o przerwaniu ptli wywietlany byby zawsze , niezalenie od
spenienia warunku wewntrz ptli. Oczywicie, w tym przypadku
warunek zawsze zostanie speniony, take return nie jest niezbdne,
ale ju w prawdziwej aplikacji zapomnienie o tym drobnym z pozoru
fakcie moe przysporzy wielu problemw.

Sprbujmy teraz wykorzysta instrukcj goto w drugim z zalecanych


przypadkw jej uycia, tzn . w bloku swi tch ... case.
WICZENIE

Instrukcja goto w bloku switch ... case

Napisz przykadowy kod, w ktrym instrukcja goto jest wykorzysty


wana w poczeniu z blokiem swi tch ... case.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Random r = n ew Random ( ) :
i n t i = r . Next ( 5 ) :
Con sol e . Wr i tel i n e ( "Wyl osowano warto i : " + i ) ;
swi tch ( i )
{
case 1 :
Con sol e . Wr i teli n e ( " i j e st mn i ej s ze od 3 . " ) ;
brea k :
case 2 :
goto c a s e 1 :
case 3 :
Con sol e . Wr i teli n e ( " i j e st mn i ej s ze od 6 . " ) ;
goto defa u l t :
case 4 :
goto c a s e 3 :
case 5 :
goto c a s e 3 :
defa u l t :
Con sol e . Wr i tel i n e (
" N i e zosta wykonany a n i bl o k c a s e 1 . a n i bl ok c a s e 2" ) ;

Rozdzi a 3 .

I n stru kcj e

73

brea k :
}
}
}

Przykadowe wyniki dziaania tej prostej aplikacji widoczne s na


rysunku 3 . 6 . Zmiennej i typu i nt przypisujemy losow liczb ca
kowit z zakresu O - 5 . Odpowiada za to linia i nt i = r . N ext ( 5 ) : , gdzie r
jest zmienn wskazujc na obiekt typu Random . Klasa ta suy wanie
do generowania losowych, a dokadniej pseudolosowych liczb .
Rysunek 3.6.

Przykadowe
wyniki dziaania
program u
z wiczenia 3. 1 8

Nastpnie w bloku swi tch ... c a s e rozpatrywane s nastpujce sytuacje :


O i jest rwne O - wywietlamy napis N i e zosta wykonany a n i
bl ok case 1 . a n i bl ok case 2 ;
O i jest rwne l lub 2 - wywietlamy napis i j est mni ej sze od 3;
O i jest rwne 3, 4 lub 5 - wywietlamy napis i jest mni ejsze od 6
oraz n i e zosta wykonany a n i bl ok case 1 . a n i bl ok case 2.

Wprowadza nie da nych


Wiadomo ju, jak wyprowadza dane na konsol, czyli po prostu jak
wywietla je na ekranie . Bardzo przydaaby si jednak moliwo ich
wprowadzania do programu. Nie jest to bardzo skomplikowane za
danie , cho napotkamy pewne trudnoci zwizane z koniecznoci
wykonywania konwersji typw danych.

C#

74

w i cz e n i a

Argumenty wiersza pol ece


Przekazywanie danych do aplikacji jako argumentw w wierszu po
lece przy wywoywaniu programu jest sposobem dobrze znanym
wikszoci programistw. Taka moliwo wystpuje w wikszoci
popularnych jzykw programowania . Nie inaczej jest w C#, gdzie,
aby z tych danych skorzysta, naley odpowiednio zadeklarowa
funkcj M a i n . Konkretnie deklaracja powinna wyglda nastpujco :
publ i c stat i c voi d M a i n ( stri n g [ J a rgs )
{
//instrukcje

Jak wida, argumenty s przekazywane do aplikacji w postaci tablicy


obiektw typu string. Poniewa w C#, podobnie jak w Javie, tablice s
obiektami, nie trzeba dodatkowo przekazywa argumentu okrelajcego
liczb argumentw, jak ma to miejsce w C i C + + . Rozmiar tablicy
okrelany jest przez waciwo Length (wicej informacji o tablicach
mona znale w rozdziale 5 . ) .
WICZENIE

Odczytanie argumentw z wiersza polece

Wywietl na ekranie wszystkie argumenty wywoania programu podane


przez uytkownika w wierszu polece .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
Con sol e . Wr i tel i n e (
" L i czba wprowa dzonych a rgumentw : { O }" , a rgs . Length ) ;
fo r ( i n t i
O : i < a rgs . Length : i ++ )
{
Con so l e . W r i tel i ne ( " a rgument n r { O } : { l }" , i . a rgs [ i J ) ;
}
}
}
=

Dane s wyprowadzane na ekran (wywietlane na ekranie) przy uy


ciu typowej ptli fo r . Przykadowy efekt dziaania programu widoczny
jest na rysunku 3 . 7 .

Rozdzi a 3 .
Rysunek 3. 7.

Program
wywietlajcy
argumenty podane
w wierszu polecei1

I n stru kcj e
.

75

- -

C : \cs>progr am . exe j eden dwa t rzy cztery p1 c


l i czba wpr owadzonych argu ment w : 5
argu ment nr O : jeden
argu ment nr 1 : dwa
argu ment nr 2 : t rzy
argu ment nr 3 : cztery
argu ment nr 4 : pi
C : \cs>_

Przy pracy z argumentami przekazywanymi z wiersza polece napo


tkamy pewien problem. Zamy, e chcemy napisa program, ktry
dodaje do siebie dwie liczby cakowite i wywietla wynik tego dzia
ania na ekranie . Wydawa by si mogo, e najprostsze rozwizanie
wyglda tak, jak na poniszym listingu :
u s i n g Sy stem :
publ i c cl a s s ma i n
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
i f ( a rg s . Length < 2 )
{
Con s o l e . Wri teli n e (
" N a l ey poda dwa a rgumenty w wi erszu pol ece l " ) :
retu rn :
}
Con sol e . Wr i tel i n e (
"Wyn i k i em dzi a a n i a j e s t : { O }" , a rgs [ O J + a rg s [ l ] ) ;
}
}

Najpierw sprawdzamy, czy zostay przekazane co najmniej dwa argu


menty. Jeli tak nie jest (waciwo Length tablicy a rgs ma warto
mniejsz ni 2) , wywietlamy stosowny komunikat na ekranie i opusz
czamy metod Ma i n za pomoc instrukcji return (co jest rwnoznaczne
z zakoi1czeniem dziaania programu) . Jeeli jednak s co najmniej
dwa argumenty, dodajemy je do siebie za pomoc operatora doda
wania (a rgs [ O J + a rgs [ l J ) , a wynik wywietlamy na ekranie (wynik
zostanie wstawiony w miejscu oznaczonym { O } ) . Gdy uruchomimy
taki program, moe nas spotka niespodzianka . Przykadowe wyniki
zostay przedstawione na rysunku 3 .8 .

C#

76
Rysunek 3. 8.

W wyniku dodawania
zostaly zlqczone
argumenty
przekazane
do programu

w i cz e n i a

. ;,,. -

C : \cs>progr am . exe 12 8
Wyni ki em dzi aani a j est : 128
c : \cs>progr am . exe j eden dwa
Wyni ki em dzi aani a j est : j edendwa
C : \cs>_

Oczywicie, nie s prawidowe. Powodem jest to, e argumenty po


brane z wiersza polece zawsze s cigami znakw (przecie tablica
a rgs jest typu stri ng ! ) i w rzeczywistoci wykonujemy operacje na
dwch napisach, a nie dwch liczbach ! Zatem wynikiem dodawania
1 2 i 8 bdzie w powyszym programie 1 2 8 zamiast spodziewanego
2 0 . Aby aplikacja dziaaa poprawnie, naley najpierw wykona
konwersj argumentw z typu s t r i ng do typu i nt, a dopiero potem
wykonywa dziaanie . Tak konwersj wykonamy za pomoc nast
pujcej konstrukcji:
i n t zmi enna = I n t32 . Pa r s e ( "zap is l i czby" ) :

WICZENIE

Konwersja danych wprowadzanych w wierszu polece

Napisz program wykonujcy dodawanie dwch liczb podanych jako


parametry w wierszu polece.
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
i nt a . b :
i f ( a rg s . Length < 2 )
{
Con so l e . W r i tel i n e (
" N a l ey poda dwa a rg umen ty w wi erszu pol ece ! " ) ;
return :
}
try
{
11
I nt32 . Pa r s e ( a rgs [ O J ) :
12
I nt32 . Pa r s e ( a rgs [ l J ) :
=

Rozdzi a 3 .

I n stru kcj e

77

}
c a tch ( Except 1 on )
{
Con so l e . W r 1 tel 1 n e (
"J eden z a rgumentw n 1 e j es t poprawn 1 1 czb l " ) ;
return :
}
Con sol e . Wr l tel l n e ( "Wyn 1 k 1 em dz1 a an 1 a j e s t : { O }" , 1 1 + 1 2 ) ;
}
}

Za konwersj z typu stri ng (cig znakw) na typ i nt (warto cako


wita) odpowiada wspomniana wyej instrukcja I nt32 . Parse 1 Odczy
tane wartoci s zapisywane w zmiennych pomocniczych 1 1 i 1 2 .
Dodatkowo poprzez zastosowanie bloku try.catch sprawdzane jest
rwnie, czy operacja ta zakoczya si sukcesem. Jeeli konwersja
si nie uda, zostan wykonane instrukcje z bloku catch (wywietle
nie komunikatu i zakoczenie dziaania programu) . Dokadniejsze
wytumaczenie znaczenia bloku try.catch znaj duje si w rozdziale 6 . ,
w ktrym opisano stosowanie wyjtkw. Jeli konwersja si uda,
warto dodawania 1 1 do 1 2 jest wywietlana na ekranie .

Powrmy teraz do aplikacji powstaej w wiczeniach 3 . 2 i 3 . 3 . Obli


czaa ona pierwiastki rwnania kwadratowego, jednak argumenty tego
rwnania byy podawane bezporednio w kodzie . Za kadym razem,
kiedy nastpowaa konieczno ich zmiany, trzeba byo ponownie
kompilowa program. Wygoda tamtego rozwizania pozostawiaa wic
wiele do yczenia. Teraz, kiedy wiadomo ju, w jaki sposb stosowa
argumenty, podajc je w wierszu polece, i jak wykona konwersj
danych, mona pokusi si o spore usprawnienie tamtej aplikacji.
WICZENIE

Rozwiqzywanie rwna kwadratowych

Napisz program obliczajcy pierwiastki rwnania kwadratowego,


w ktryn1 paran1etry rwnania s wprowadzane w wierszu polece
(rysunek 3 . 8) .

1 Dokadniej rzecz ujmujc, jest to wywoanie statycznej metody P a r s e


struktury I n t32 zdefiniowanej w przestrzeni nazw Sy stem.

C#

78

w i cz e n i a

u s i n g Sy stem :
c l a s s P i erwi a stek
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
doubl e parametrA . pa ramet r B . pa rametrC :
i f ( a rg s . Length < 3 )
{
Con so l e . W r i tel i n e (
" Wywo a n i e programu : p i erw i a s tek . exe p a rametrA p a r a m e t r B
4pa rametrC " ) :
return :
}
try
{
pa rametrA = Doubl e . P a rs e ( a rg s [ O J ) ;
pa rametrB = Doubl e . P a rs e ( a rgs [ l J ) ;
pa rametrC = Doubl e . Pa rs e ( a rgs [2J ) ;
}
c a tch ( Except i on )
{
Con so l e . W r i tel i n e (
"J eden z p a r amet rw rwn a n i a n i e j est poprawn l i czb l " ) ;
return ;
}
Con sol e . Wr i tel i n e ( "Wprowa dzon e par amet ry rwn an i a : \ n " ) ;
Con sol e . Wr i teli n e ( "A : " + p a r ametrA + " B : " + pa rametrB +
" C : " + pa rametrC + " \ n " ) ;
i f ( pa rametrA == 0 )
{
Con so l e . W r i tel i n e ( "To n i e j es t rwn a n i e kwad r atowe : A = Q I " ) ;
}
el se
{
doub l e del ta = p a r ametr B * pa rametrB
4 * pa ramet rA * pa rametrC :
doub l e wyn i k :
-

i f ( de l ta < 0 )
{
Con sol e . Wr i teli n e ( " De l ta < O . " ) ;
Con sol e . Wr i tel i n e (
" Brak rozwi za w zbi orze l i czb rzeczywi stych . " ) ;
}
el se i f ( del ta == 0 )
{

Rozdzi a 3 .

I n stru kcj e

79

wyn 1 k = - p a r amet rB I ( 2 * pa rametrA ) :


Con sol e . Wr l teL1 n e C " Rozw1 zan 1 e : x = " + wyn 1 k ) :
}
el se
{
wyn 1 k = C - pa rametrB + Math . Sqrt C del ta ) ) I ( 2 * pa rametrA ) :
Con sol e . W r1 te C " Rozw1 za n 1 e : xl = " + wyn 1 k ) ;
wyn 1 k = C - pa rametrB - Math . Sqrt C del ta ) ) I ( 2 * pa rametrA ) ;
Con sol e . W rl tell n e C " . x2 = " + wyn 1 k ) ;
}
}
}
}

W kodzie za pomoc pierwszej instrukcji i f badane jest, czy z wier


sza polece zostay przekazane co najmniej 3 argumenty. Jeeli ar
gumentw jest zbyt mao (warto a rgs . Length mniejsza ni 3), in
formujemy o tym uytkownika za pomoc komunikatu i kof1czymy
dziaanie programu przez wywoanie instrukcji return . Jeeli liczba
argumentw jest waciwa (s co najmniej 3), nastpuje prba prze
tworzenia ich na wartoci typu Doubl e. Odbywa si to w sposb ana
logiczny do przedstawionego w wiczeniu 3 . 20, z t rnic, e zo
staa uyta struktura Doubl e zamiast I nt32 . Dziki temu cigi znakw
uzyskane z wiersza polece s przetwarzane na wartoci rzeczywiste
(typu doubl e) , a nie cakowite (typu i nt) . Podobnie jak w wiczeniu
3 . 20, zosta te uyty blok try.catch, zatem zostanie obsuona sytuacja,
w jakiej program wywoano z cigami znakw, ktre nie reprezen
tuj prawidowych liczb . Obliczenia pierwiastkw rwnania s na
tomiast wykonywane na zasadach przedstawionych w wiczeniach
3 . 2 i 3 . 3 . Efekt przykadowego wywoania programu zosta zaprezen
towany na rysunku 3 . 9 .
Rysunek 3. 9.

Rwnania
kwadratowe
o parametrach
podanych
w wierszu polecez1

Naley zwrci uwag, e sposb wprowadzania liczb rzeczywistych


z separatorem dziesitnym zaley od ustawief1 regionalnych systemu.

C#

80

w i cz e n i a

Konkretnie od tego, jaki symbol zosta ustalony jako separator dzie


sitny. W ustawieniach polskich domylnie jest to przecinek, przy
ustawieniach angielskich - kropka .

I nstru kcja Read line


Wprowadzanie danych do programu w wierszu polece nie zawsze
jest wygodne. Czsto chcielibymy wykonywa t czynno ju w trak
cie dziaania aplikacji. Jest to moliwe przy uyciu instrukcji2 Consol e .
4Readl i ne ( ) , ktra zwraca wprowadzon przez uytkownika jedn
lini tekstu (cig znakw zakoczony znakiem koca linii) .
WICZENIE

Wczytywanie wierszy tekstu

Napisz program, ktry w ptli wczytuje kolejne wiersze tekstu wprowa


dzane przez uytkownika i wywietla je na ekranie . Program powinien
zakoczy dziaanie po odczytaniu cigu znakw qui t.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
s t r i ng str :
wh i l e ( ( str
Con sol e . Readl i n e ( ) ) 1
{
Con s o l e . W r i tel i n e ( str ) :
}
}
}
=

" q u i t" )

W kodzie zostaa zadeklarowana pomocnicza zmienna str typu stri ng,


a za ni znajduje si ptla typu wh i l e odczytujca linie tekstu wpro
wadzane z klawiatury. Warunek ptli wh i l e ma tu skondensowan
form . Wykonywanych jest kilka operacji. Najpierw nastpuje odczyt
jednej linii tekstu (Conso l e . Readl i ne( ) ), nastpnie uzyskany cig znakw
przypisywany jest zmiennej str (str = Conso l e . Readl i ne( ) ) , w kolejnej
fazie warto tej zmiennej jest porwnywana z cigiem znakw qui t .
2

Dokadniej: dziki statycznej metodzie Readl i n e z klasy Con sol e .

Rozdzi a 3 .

I n stru kcj e

81

Jeeli zatem odczytany cig znakw (zawarty w zmiennej str) jest


rny od cigu qui t, zostanie wykonana instrukcja z wntrza ptli
wywietlajca odczytane dane na ekranie . Jeli natomiast z klawiatu
ry zosta wprowadzony cig qui t, ptla, a tym samym cay program,
zostan zakoczone .

Naley w tym miejscu zwrci rwnie uwag, e zapis, taki jak w wi


czeniu 3 . 2 2 , moe w pewnych sytuacjach spowodowa nieprawi
dow reakcj aplikacji. Dlaczego? Ot wywoanie Readl i ne ( ) w sy
tuacji, gdy nie ma ju nic wicej do odczytania, zamiast cigu znakw
zwrci warto nu l l . Przy odczycie z konsoli ma to miej sce po
wciniciu kombinacji Ctrl+Z i zatwierdzeniu klawiszem Ente?. Jest
to sygna do zakoczenia odczytu danych. Zaprezentowany program
reaguje tylko na cig qui t, nie respektuje sygnau Ctrl+Z. Mona to
je dnak zmieni po przebudowie ptli .
WICZENIE

Odczyt danych z rozpoznawaniem sekwencji specjalnej

Popraw kod z wiczenia 3 .22 tak, aby reagowa na kombinacj Ctrl+Z.


u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
s t r i ng str :
wh i l e ( t rue )
{
str = Con sol e . Readli n e ( ) :
i f( s tr == "qui t " 1 1 str == nu l l )
{
brea k :
}
Con s o l e . W r i tel i n e ( str ) :
}
}
}

Odpowiada to pojawieniu si w standardowym wejciu znaku kontrolnego


o kodzie lA (26 dziesitnie) .

82

C#

w i cz e n i a

W porwnaniu z kodem z wiczenia 3 .22 wystpuje tu sporo rnic .


Zupenie inna jest konstrukcja ptli. Poniewa wyraeniem warun
kowym jest true, ptla nie zakoczy si samoczynnie i konieczne bdzie
jej przerwanie . Wewntrz ptli cig znakw odczytany z konsoli
(z reguy: wprowadzony przez uytkownika z klawiatury) jest odczyty
wany i zapisywany w zmiennej str. Nastpnie badane jest, czy w str
znajduje si cig qui t oraz czy str jest rwne nul l (oznaczaoby to, e
w cigu wejciowym znalaz si znak specjalny Ctrl+Z) . Po spenie
niu jednego z tych warunkw naley zakoczy ptl, jest wic wy
konywana instrukcja brea k . Je eli jednak oba warunki s faszywe ,
odczytane dane (zapisane w zmiennej str) pojawi si na ekranie .

Skoro wiadomo ju, jak wczytywa dane z klawiatury, mona pokusi


si o zmodyfikowanie programu do obliczania pierwiastkw rwna
nia kwadratowego tak, aby parametry byy wprowadzane w trakcie
jego dziaania. W programie bdziemy teraz prosi uytkownika
o podanie kolejnych liczb i podstawimy je pod zmienne pa rametrA,
pa ramet rB i pa rametrC .
Oczywicie, przed przypisaniem danych do wspomnianych zmiennych
trzeba wykona konwersj z typu stri ng na typ doubl e (lub te i nt,
jeli decydujemy si na obsug wycznie wartoci cakowitych) . Co
jednak naley zrobi, kiedy uytkownik nie poda prawidowej liczby,
ale np . wpisze dowoln kombinacj znakw? Najlepiej byoby po
prosi o ponowne wprowadzenie parametru . Jak to wykona? Naj
wygodniej bdzie skorzysta z ptli wh i l e 1ub do wh i l e i prosi uyt
kownika o wprowadzanie liczby tak dugo, a poda poprawn.
...

Skoro jednak mamy trzy zmienne, a tym samym trzy parametry do


wprowadzenia, nie ma sensu pisa trzech ptli wygldajcych prak
tycznie tak samo . Lepiej utworzy dodatkow funkcj (metod) , ktrej
zadaniem bdzie dostarczenie prawidowej liczby rzeczywistej wpro
wadzonej przez uytkownika .
WICZENIE

Rwnania kwadratowe o parametrach podawanych


w trakcie dziaania aplikacji

Napisz program obliczajcy pierwiastki rwnania kwadratowego, w kt


rym parametry s wprowadzane w trakcie jego dziaania.

Rozdzi a 3 .

I n stru kcj e

83

u s i n g Sy stem :
c l a s s P i erwi a stek
{
publ i c stati c doub l e pobi erzli czbe ( stri n g pa ram )
{
doubl e l i czba = O :
bool su kces :
do
{
Con s o l e . W r i te ( " P rosz poda { O } p a r amet r rwnan i a : "
try
{
l i czba = Doubl e . Parse ( Con sol e . Rea d l i n e ( ) ) ;
s u k ces = true :
}
catch ( Except i on )
{
Con sol e . Wr i tel i n e (
"To n i e j e s t prawi d owa l i czba rzeczywi s ta l " ) ;
s u k ces = fa l se :
}
}
wh i l e ( 1 sukces ) ;
return l i cz ba ;
}
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
doubl e parametrA = pobi erzli czbe ( " p i erwszy " ) ;
doubl e pa rametrB = pobi erzli czbe ( " drugi " ) ;
doubl e pa rametrC = pobi erzli czbe ( " trzeci " ) ;

p a r am ) :

Con so l e . Wri tel i n e ( "Wprowa dzon e par amet ry rwn a n i a : \ n " ) ;


Con sol e . Wr i teli n e ( "A = " + pa ramet rA + " , B = " + pa rametrB +
" C = " + pa rametrC + " \ n " ) ;
i f ( pa rametrA == 0 )
{
Con so l e . W r i tel i n e ( "To n i e j es t rwn a n i e kwad r atowe : A = 0 1 " ) ;
}
el se
{
doub l e del ta = p a r ametr B * pa rametrB
4 * pa ramet rA * pa rametrC ;
doub l e wyn i k ;
-

i f ( de l ta < 0 )
{
Con sol e . Wr i teli n e ( " De l ta < 0 " ) ;
Con sol e . Wr i tel i n e (
" Brak rozwi za w zbi orze l i czb rzeczywi stych . " ) ;

C#

84

w i cz e n i a

}
el se 1 f ( del ta == 0 )
{
wyn 1 k = - pa rametrB I 2 * parametrA ;
Con sol e . Wr l tel1 n e ( " Rozw1 zan 1 e : x = " + wyn 1 k ) :
}
el se
{
wyn 1 k = ( - pa rametrB + Math . Sqrt ( de l ta ) ) I ( 2 * pa rametrA ) ;
Con sol e . Wr l te ( " Rozw1 zan 1 e : xl = " + wyn 1 k ) :
wyn 1 k = ( - pa rametrB - Math . Sqrt ( de l ta ) ) I ( 2 * pa rametrA ) :
Con sol e . Wr l tel1 n e ( " , x2 = " + wyn 1 k ) :
}
}
}
}

Za pobieranie wartoci liczbowych od uytkownika odpowiada


osobna funkcja (metoda; dokadne wyjanienie tego terminu znajdzie
si w rozdziale 4 . ) o nazwie pobi erzL i czbe . Otrzymuje ona jeden ar
gument typu stri ng (cig znakw) , ktry zostanie uyty w komuni
kacie wywietlanym na ekranie . Wewntrz funkcji zostay zadeklaro
wane dwie zmienne: l i czba oraz sukces . W pierwszej bdzie zapisywana
warto odczytana z klawiatury w postaci liczby typu doubl e, druga
bdzie sygnalizowaa, czy odczytany cig udao si przetworzy na
liczb (s ukces = true) , czy te nie (s ukces = fa l s e) .
Odczyt wartoci przeprowadzany jest w ptli do.wh i l e. Najpierw wy
wietlany jest komunikat zawierajcy okrelenie (pobrane z argumentu
pa ram) , ktry z parametrw jest aktualnie wczytywany. Nastpnie
w bloku try wykonywana jest zoona instrukcja:
1 1 czba = Doubl e . P a r s e ( Con sol e . Readl1 n e ( ) ) ;

To odczytanie z konsoli wiersza tekstu, przeksztacenie go na warto


typu doubl e oraz przypisanie tej wartoci zmiennej l i cz ba . Zmiennej
s ukces jest te przypisywana warto true. To oznacza, e jeli kon
wersja cigu znakw na liczb powiedzie si, ptla zostanie zakof1czona (warunek kontynuacji ptli to ! s ukces, a wic gdy zmienna
sukces ma warto true, ptla jest koczona) , a warto zapisana
w l i czba staje si wynikiem dziaania funkcji (odpowiada za to in
strukcja return l i czba : ) .
Jeeli jednak konwersja cigu pobranego z klawiatury nie uda si,
zostanie wykonany blok catc h . To oznacza, e na ekranie pojawi si
komunikat z informacj o bdnych danych, a zmienna sukces otrzyma

Rozdzi a 3 .

I n stru kcj e

85

warto fal se. Skoro tak, ptla do.wh i l e bdzie kontynuowana, a uyt
kownik zobaczy ponown prob o podanie wartoci liczbowej .
Zawarto metody Ma i n, od ktrej rozpoczyna si wykonywanie kodu
programu, jest prawie taka sama jak we wczeniejszych przykadach
dotyczcych rozwizywania rwnaf1 kwadratowych - zasady obli
cze si przecie nie zmieniy . Rnice dotycz samego pocztku
kodu. Wartoci zmiennych pa rametrA, parametrB i pa rametrC s po prostu
pobierane z opisanej wyej funkcji pobi erzl i czbe . Zapis :
doubl e parametrA

pobi erzli czbe ( " p i erwszy " ) :

oznacza, e ma zosta zdeklarowana zmienna o nazwie pa rametrA


oraz typie doubl e i ma jej by przypisana warto wynikajca z dziaania
funkcji po bi erzl i czbe, ktrej zosta przekazany cig znakw pi erwszy.
Dokadne zasady budowy wasnych funkcji (waciwie metod) oraz
zwracania przez nie wartoci zostay opisane w kolejnym rozdziale .

Na tym mona by zakoczy wiczenia z wprowadzania danych i roz


wizywania rwnaf1 kwadratowych, ale warto wykona jeszcze jeden
przykad. Wygodnie byoby, gdyby program umoliwia podawanie
parametrw zarwno w wierszu polece, jak i w trakcie jego dziaania.
Uytkownik mgby wybra wygodniejszy sposb . C o wicej , jeli
przy podawaniu danych w wierszu polece pomyliby si, aplikacja
pozwoli na ponowne ich wprowadzenie .
Nie jest to przecie skomplikowane zadanie . Wystarczy poczy kod
z wiczenia 3 . 21 z kodem z wiczenia 3 . 24.
WICZENIE

Rwnania kwadratowe o parametrach rzeczywistych

Napisz program rozwizujcy rwnanie kwadratowe o zadanych pa


rametrach, bdcych dowolnymi liczbami rzeczywistymi. Parametry
mog by wprowadzane zarwno w trakcie dziaania programu, jak
i w wierszu polece .
u s i n g Sy stem :
c l a s s P i erwi a stek
{
publ i c stati c doub l e pobi erzli czbe ( stri n g pa ram )
{

C#

86

w i cz e n i a

I/Tutaj tre metody pobierzLiczbe z listingu 3. 24.

}
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
bool l i n i a Komend = true :
doubl e parametrA = O . p a r amet rB = O . p a rametrC = O :
i f ( a rg s . Length < 3 )
{
l i n i a Komen d = fa l se :
}
i f ( l i n i a Komend )
{
try
{
p a rametrA = Doubl e . P a r s e ( a rgs [ O J ) :
p a r ametrB = Doub l e . P a r s e ( a rgs [ l ] ) :
pa rametrC = Doubl e . P a r s e ( a rgs [ 2J ) :
}
catch ( Except i on )
{
Con sol e . Wr i teL i n e C "J eden z wprowadzonych pa ramet rw n i e j es t
'+pop rawn l i czb ! " ) :
l i n i aKomend = fa l se : :
}
}
i f ( l l i n i aKomend )
{
pa rametrA = pobi erzli czbe ( " p i erwszy" ) :
pa rametrB = pobi erzli czbe ( " drugi " ) :
pa rametrC = pobi erzli czbe ( " trzec i " ) :
}
Con so l e . Wri tel i n e ( "Wprowa dzon e par amet ry rwn a n i a : \ n " ) ;
Con sol e . Wr i teli n e ( "A = " + pa ramet rA + " B = " + pa rametrB +
" . C = " + pa rametrC + " \ n " ) :
,

I/Tutaj dalsza tre metody Main z listingu 3. 24.

}
}

Zarwno tre n1etody po bi erzl i czbe, jak i cz n1etody Ma i n wyko


nujca obliczenia pozostay bez zmian w porwnaniu z poprzednimi
przykadami, dlatego te nie zostay uwzgldnione na listingu. Mo
dyfikacjom uleg natomiast pocztek kodu wykonywalnego (pierwsza
cz metody Mai n) . Pojawia si nowa zmienna o nazwie l i n i a Komend
wskazujca, czy argumenty maj by pobierane z wiersza polecei1 .
Jej pocztkowa warto wynosi true.

Rozdzi a 3 .

I n stru kcj e

87

Za deklaracj ami zmiennych znajduje si instrukcja warunkowa


sprawdzajca liczb argumentw otrzymanych z wiersza polece .
Jeeli jest ich mniej ni 3 , stan zmiennej l i n i a Komend zmienia si na
fal se. Tym samym wspomniane argumenty zostan pominite, a pro
gram poprosi o ich rczne wprowadzenie . Jeeli jednak s przynajm
niej 3 argumenty, wartoci zmiennej pozostaje true, a wic wyko
nywane s instrukcje przetwarzajce dane z tablicy a rgs . Gdyby przy
przetwarzaniu danych zawartych w a rgs wystpi bd, wykonany
bdzie blok catc h , a tym samym stan zmiennej l i ni a Komend zmieni si
na fa l s e .
Kolejna instrukcja warunkowa bada warto zapisan w l i n i a Komend .
Warto true oznacza, e w wierszu polece zostay podane co naj
mniej 3 argumenty i udao si je przetworzy na wartoci rzeczywiste.
Skoro tak, blok i f jest pomijany i program przystpuje do oblicze .
Z kolei warto fa l se oznacza, e argumenty nie zostay przekazane
lub s bdne (nie s wartociami rzeczywistymi) . Wtedy parametry
rwnania s pobierane podobnie jak w wiczeniu 3 .24, czyli za po
moc metody pobi erzL i czbe .
Przykadowy efekt dwch rnych wywoa programu zosta przed
stawiony na rysunku 3 . 1 0 . Jeeli w wierszu polece podane zostay 3
parametry i kady z nich jest prawidow liczb, zostan one uyte
do rozwizania rwnania (pierwsze wywoanie na rysunku) . Jeli
jednak parametrw jest mniej lub przy wprowadzaniu ktregokol
wiek z nich zosta popeniony bd (drugie wywoanie na rysunku) ,
aplikacja prosi o ponowne ich wprowadzenie.
m

(:\Wi ndow<\system32\cmd.exe

Rysunek 3. 10. Parametry rwnania mog by podawane w postaci liczb

rzeczywistych

88

C#

w i cz e n i a

II
Prog ra mowa n i e obiektowe

90

C#

w i cz e n i a

4
Kl asy i o b iekty
Kl asy
Kady program w C# skada si z klas . Dotychczas uywalimy tylko
jednej klasy, ktra nazywaa si P rog ram lub Pi erwi astek . Wrmy za
tem do pierwszego programu z wicze, wywietlajcego na ekranie
napis . Kod wyglda nastpujco :
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d Mai n ( str i n g [ J a rg s )
{
Con so l e . W r i tel i ne ( " Mj pi erwszy program i " ) :
}
}

Zostao wtedy przyjte zaoenie, e szkielet kolejnych aplikacji, su


cych do nauki struktur jzyka programowania, ma wanie tak wygl
da . Teraz nadszed czas, aby wyjani, dlaczego. Wszystko stanie si
jasne po przeczytaniu tego wanie rozdziau .
W klasach zawarty jest kod wykonywalny, ktry realizuje przypisane
mu zadania . Klasy s take opisami obiektw, a kady obiekt jest in
stancj, czyli wystpieniem danej klasy. Oznacza to, e klasa definiuje
typ danego obiektu.

92

C#

w i cz e n i a

Dla osoby nieobeznanej z programowaniem obiektowym brzmi to


zapewne cakowicie niezrozumiale, nie naley si jednak przejmowa,
w rzeczywistoci nie ma w tym nic skomplikowanego. Skoro klasa de
finiuje typ obiektu, przypomnijmy sobie, czym jest typ . Typ okrela
rodzaj wartoci, jakie moe przyjmowa dany byt programistyczny, np .
zmienna. Jeli zatem typem zmiennej jest i nt, moe ona przyjmowa
wartoci typu i nt, czyli liczb cakowitych z danego przedziau.
Czym s obiekty? Mona je okreli jako byty programistyczne, ktre
potrafi przechowywa jakie wartoci oraz wykonywa pewne ope
racje. Klasy natomiast to wanie opisy takich obiektw. Obrazowo
mona powiedzie, e klasa to pewnego rodzaju plan, na podstawie
ktrego w programie tworzone s obiekty. Aby jednak nie poprze
stawa na suchych definicjach, sprbujemy wykona konkretny przy
kad. Zamy, e chcemy w programie zapisa dane dotyczce punk
tw na ekranie . Taka klasa, nazwiemy j Punkt, powinna przechowywa
dwie wsprzdne : x i y.
WICZENIE

Prosta klasa

Napisz kod klasy, w ktrej mona bdzie przechowywa dane doty


czce punktw ekranowych .
publ i c cl a s s Punkt
{
pub l i c i n t x :
publ i c i nt y :
}

Skadowymi klas s pola i metody. Pola to atrybuty, w ktrych mo


na przechowywa dane dotyczce klasy. Metody to kod wykonywal
ny, za pomoc ktrego mona przeprowadza rne operacje . W tym
przypadku klasa zawiera tylko dwa pola, x i y, ktre opisuj pooe
nie punktu na ekranie . Sowo publ i e oznacza, e zarwno do klasy,
jak i do pl nie ma ogranicze dostpu. Zostanie to dokadniej wyja
nione w podrozdziale Specyfikatory dostpu" .

Zadeklarujmy teraz zmienn typu Punkt. Jest to bardzo proste :


Punkt nowyPunkt :

Rozdzi a 4.

Kl a s y i o b i e k t y

93

Jak wida, najpierw podaje si nazw klasy, a potem nazw zmiennej,


podobnie jak dla zmiennych poznanych ju wczeniej typw podsta
wowych. Tak zadeklarowana zmienna jest jednak pusta (dokadniej
mwic, powstaa w ten sposb jedynie referencja, inaczej odniesienie
(ang . ref erence ), do obiektu klasy Punkt) , ale mona jej przypisa obiekt
klasy Punkt. Aby to zrobi, naley go najpierw utworzy. Wykorzystu
jemy w tym celu operator new w postaci:
new N a zwaKl a sy ( ) ;

W omawianym przypadku caa konstrukcja bdzie wygldaa nast


pu1co :
Punkt nowyPunkt = new Punkt( ) ;

Mona te najpierw zadeklarowa referencj, a dopiero potem utwo


rzy i przypisa jej obiekt danej klasy:
Punkt nowyPunkt ;
nowyPunkt = new Pun k t ( ) ;

Warto zwrci uwag, e np. w C + + jest inaczej ! Znaczy to, ze JUZ


nap1san1e :
Punkt nowyPunkt ;

spowodowaoby utworzenie obiektu typu Punkt, a nie tylko referencji


do niego . Jeeli kto jest przyzwyczajony do c + + , powinien o tym
pamita, gdy jest to czsta przyczyna bdw.
Gdy powstanie obiekt typu Punkt, mona odwoywa si do jego pl,
stosujc konstrukcj :
nazwa_ob i ektu . nazwa _po 7 a

Jeeli zatem zmiennej o nazwie nowyPunkt zosta przypisany obiekt


typu Punkt (np . za pomoc z jednej z pokazanych wyej instrukcji) , to
aby przypisa warto 1 00 polu x, naley uy instrukcji:
nowyPu n k t . x = 100 ;

Aby z kolei odczyta warto pola x i zapisa j w zmiennej l i czba ,


trzeba skorzysta z instrukcji:
i n t l i czba = n owyPun kt . x ;

C#

94

w i cz e n i a

M etody
Metody, jak ju zostao wspomniane, zawieraj kod operujcy na polach
danej klasy bd te na dostarczonych z zewntrz danych (oglniej
- mog wykonywa dowolnie zaprogramowane zadanie) . Metody
wywoujemy za pomoc operatora . (znak kropki), poprzedzajc go na
zw zmiennej odnonikowej (referencyjnej) . Wyglda to nastpujco :
nazwa_zmiennej . nazwa_metody( argumen ty_metody) :

W nawiasie okrgym po nazwie metody podaje si argumenty, o ile


s wymagane (w ten sposb mona przekaza metodzie jakie dane) .
W klasie Punkt mona np . utworzy dwie metody, ktre zwracayby
odpowiednio wsprzdn x i wsprzdn y punktu .
WICZENIE

Metody zwracajqce wartoci pl

Do klasy Punkt dodaj metody podajce wsprzdn x oraz wsp


rzdn y.
publ i c cl a s s Punkt
{
pub l i c i n t x :
publ i c i nt y ;
publ i c i nt GetX ( )
{
return x :
}
publ i c i nt GetY ( )
{
return y :
}
}

Wewntrz klasy, oprcz pl x i y, zostay umieszczone metody GetX


i GetY . Pierwsza zwraca warto pola x, a druga - warto pola y. War
toci pl s zwracane za pomoc wartoci return (instrukcja return
powoduje przerwanie wykonywania danej metody i, ewentualnie,
zwrcenie przez ni wartoci wymienionej po return) . Jeli, majc tak
klas, utworzymy nowy obiekt typu Punkt i zapiszemy go w zmiennej
punkt:
P u n k t punkt = new Punkt( ) :

Rozdzi a 4.

Kl a s y i o b i e k t y

95

to aby uzyska informacj o wartoci wsprzdnej x, bdziemy mogli


napisa :
punkt . X ;

lub te :
punkt . GetX ( ) ;

np . tak:
i n t wsp rzdn a X = punkt . X ;
i n t wspX = pun k t . GetX ( ) ;

Naley zwrci uwag, e po wywoaniu metody (zapis punkt . GetX ( )


oznacza wywoanie metody GetX nalecej do obiektu wskazywanego
przez zmienn punkt) w miejsce wystpienia tego wywoania jest
podstawiana warto zwrcona przez t metod za pomoc instruk
cji return . To dlatego moliwe jest przypisanie wspX = punkt . GetX ( ) .
WICZENIE

Ustawianie i pobieranie wartoci pl

Do klasy Punkt dodaj metod ustawiajc wsprzdne oraz metod


zwracajc wsprzdne .
publ i c cl a s s Punkt
{
publ i c i nt x ;
publ i c i nt y ;
publ i c vo i d Us tawWs pol rzedn e ( i n t wspX . i nt wspY )
{
x = wspX ;
y = wspY ;
}
publ i c Punkt Pobi e rzWspol rzedne ( )
{
Punkt punkt = new Punkt( ) ;
punkt . X = x ;
punkt . y = y ;
return pun k t ;
}
}

Przedstawiona tu wersja klasy zawiera dwa pola typu i nt o nazwach


x i y, ktre su do przechowywania wsprzdnych danego punktu,
oraz dwie metody. Pierwsza zajmuje si ustawieniem pl danego
obiektu, druga pobiera wartoci . Przed metod Us tawWs pol rzedne ( )

C#

96

w i cz e n i a

znajduje si sowo vo i d, co oznacza, e metoda nie zwraca adnej


wartoci . Ma natomiast dwa argumenty, wspX i wspY, oba typu i nt .
W ciele (we wntrzu) tej metody polu x przypisywana jest warto
parametru wspX, a polu y
warto parametru wspY. Zatem po wykona
niu nastpujcej instrukcji :
-

punkt . Us tawWspol rzedne ( 1 , 10 ) :

pole x obiektu punkt przyjmie warto 1, a pole y

warto 1 0 .

Przed drug metod


pobi e r z P u n k t
znaj duje si sowo Punkt.
Oznacza to, e zwraca ona referencj do obiektu typu Punkt. Mona
zatem napisa tak oto instrukcj :
-

Punkt i n nyPunkt = punkt . Pobi e rzWspol rzedne ( ) ;

W ciele tej metody najpierw tworzony jest nowy obiekt typu P u n k t ,


a nastpnie odpowiednim polom tego obiektu przypisywane s
wartoci pl x i y obiektu biecego . Obiekt punkt ( a dokadniej refe
rencja do tego obiektu) jest zwracany za pomoc instrukcji return .

Najwyszy czas wykorzysta tak utworzony kod w konkretnym przy


kadzie . Napiszemy program korzystajcy z klasy Punkt. Bdzie si
skada z dwch klas : Punkt i P rogram. Mona je zapisa albo w jed
nym pliku (np . o nazwie program .es), albo te w dwch. Wybierzemy
to drugie rozwizanie . Kod klasy P u n k t z wiczenia 4 . 3 zapiszemy
w pliku Punkt.es, natomiast kod programu korzystajcego z tej klasy
(kod z wiczenia 4 .4), w pliku Program .es (nazwy plikw rozpoczy
naj si wielk liter, jako e bd to te nazwy jedynych klas zawar
tych w tych plikach; nie ma to jednak formalnego znaczenia, nazwy
plikw mona dobra dowolnie) .
WICZENIE

Wykorzystanie klasy Punkt

Napisz program korzystajcy z obiektw klasy Punkt.


u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Punkt punkt = new Punkt( ) ;

Rozdzi a 4.

97

Kl a s y i o b i e k t y

Punkt pomoc n 1 czy Pun kt :


pomocn 1 czy Punkt
punkt . Pob 1 e rzWspol rzedne ( ) :
=

Con sol e . Wrl tel 1 n e ( " P rzed us taw1 en 1 em wartoc1 : " ) ;


Con sol e . Wr l tel l n e ( "W sp rzdn a x
" + pomocn 1 czyPun kt . x ) :
Con sol e . Wr l tel l n e ( "W sp rzdn a y
" + pomocn 1 czyPun kt . y ) ;
=

punkt . U s tawWspol rzedne ( 1 , 2 ) :


pomocn 1 czy Punkt
punkt . Pob 1 e rzWspol rzedne ( ) ;
=

Con sol e . Wr l teL1 n e ( " \ n Po u staw1 en 1 u wa rtoc 1 : " ) ;


Con sol e . Wr l tel l n e ( "W sp rzdn a x
" + pomocn 1 czyPun kt . x ) :
Con sol e . Wr l tel l n e ( "W sp rzdn a y
" + pomocn 1 czyPun kt . y ) ;
=

}
}

Oba pliki (Program.es oraz Punl<l.cs) umieszczamy w jednym katalogu


i kompilujemy w wierszu polecei1, wydajc komend :
c s c Program . es Punkt . e s

Powstanie wtedy plik wynikowy o nazwie Program .exe, ktry bdzie


mona uruchomi . W efekcie dziaania programu na ekranie zobaczy
my widok zaprezentowany na rysunku 4 . 1 .
Ci! C:\Windows\sys:tem32\ c m d .exe

Rysunek 4. 1. Wynik dziaania programu z wiczenia

4.4

Jak dziaa przedstawiony program? Na pocztku tworzymy zmienn


o nazwie punkt i przypisujemy jej nowy obiekt klasy Punkt oraz drug
zmienn
pomocni czyPunkt. Poniewa metoda Po bi erzWs po l rzedne ( )
zwraca referencj do obiektu typu Punkt, mona wykona przypisanie :
-

pomocn 1 czy Punkt

punkt . Pob1 e rzWspol rzedne ( ) ;

Wartoci pl x i y obiektu pomocni czyPunkt s wywietlane na ekranie .


Bd to dwa zera . Wynika to z tego, e pola te nie zostay zainicjali
zowane, a niezainicjalizowane pola typu i nt przyjmuj warto O .

98

C#

w i cz e n i a

Oglniej rzecz ujmujc : kade niezainicjalizowane pole typu arytme


tycznego przyjmuje warto O . Znaczy to, e mona takiego pola uy
(to rnica w stosunku do zmiennych stosowanych w rozdziale 3 . ; nie
zainicjalizowanej zmiennej nie mona byo wykorzysta) .
Nastpnie zostaa uyta metoda UstawWs pol rzedne obiektu punkt:
punkt . Us tawWspol rzedne ( 1 . 2 ) :

Oznacza to, e polu x zostaa przypisana warto 1, a polu y - war


to 2 . Te wartoci rwnie zostay pobrane w postaci obiektu typu
Punkt, przypisane zmiennej pomocni czyPunkt i wywietlone na ekranie .

Analizujc kod wiczenia 4 .4, mona zauway, e zmienna pomocn i czy


4Punkt wcale nie jest konieczna do prawidowego dziaania programu.
Z rwnie dobrym skutkiem mona wykona odwoanie bezpored
nie . Modyfikacji naleaoby - oczywicie - podda metod Ma i n .
Bdzie to jednak skutkowao zmniejszeniem czytelnoci kodu .
WICZENIE

Odwoania do pl z pominiciem zmiennej pomocniczej

Zmodyfikuj kod metody Ma i n z wiczenia 4 .4 tak, aby nie trzeba byo


uywa zmiennej pomocni czyPunkt.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Punkt punkt = new Punkt( ) :
Con sol e . Wri tel i n e ( " P rzed us tawi en i em wartoci : " ) :
Con sol e . Wr i tel i n e (
"Wsp rzdna x = " + punkt . Pobi erzWspol rzedn e ( ) . x ) ;
Con sol e . Wr i tel i n e (
"Wsp rzdna y
" + punkt . Pobi erzWspol rzedn e ( ) . y ) ;
=

punkt . Us tawWspol rzedne ( 1 . 2 ) :


Con sol e . Wr i teLi n e ( " \ n Po u stawi en i u wartoci : " ) :
Con sol e . Wr i tel i n e (
"Wsp rzdna x = " + punkt . Pobi erzWspol rzedn e ( ) . x ) :

Rozdzi a 4.
Con sol e . Wri teli n e (
"Wsp rzdna y

Kl a s y i o b i e k t y

99

" + punkt . Pobi erzWspol rzedn e ( ) . y ) :

}
}

Poniewa w miejsce vvywoania metody Pobi erzWs pol rzedne jest pod
stawiany wynik jej dziaania, czyli zwrcony ob iekt, mona zasto
sowa odwoanie typu:
punkt . Pobi erzWspol rzedne ( ) . x

Trzeba jednak pamita, e w tym przykadzie znajduje si dwu


krotnie wicej wywoali metody Pobi erzWs po l rzedne (ni w wiczeniu
4 .4), co nie pozostaje bez wpywu na wydajno dziaania kodu.
Oczywicie, w tak prostym przypadku nie ma to znaczenia, jednak
przy bardzo duej liczbie wywoali mona si spodziewa spadku
wydajnoci.

Dlaczego wykonujemy t na pozr karkoomn konstrukcj, tworzc


najpierw w metodzie Po bi erzWs po l rzedne ( ) nowy obiekt typu Punkt
(wiczenie 4 . 3) , przypisujc mu odpowiednie wartoci x oraz y i do
piero potem zwracajc novvy byt? Odpowied jest prosta. Nie mona
jednoczenie zwrci wsprzdnej x i wsprzdnej y. Metoda moe
zwraca tylko jedn warto typu podstawowego lub referencyjnego
( odnonikowego) .
Mona co najvvyej napisa dwie dodatkowe metody, ktre bd osobno
zwracay warto x, a osobno warto y, tak jak zostao to wykonane
w wiczeniu 3 .2. Podobnie mona utworzy dwie metody ustawiajce
osobno wartoci x i y.
Moe si to okaza bardzo przydatne, gdy gdzie w programie bdziemy
chcieli zmodyfikowa tylko jedn ze wsprzdnych . Zamy, e
chcemy zmodyfikowa tylko x, ustawiajc jego warto na 5. W obecnej
sytuacji, gdyby do dyspozycji byy tylko metody z wiczenia 4 . 3
operujce na polach (przy zaoeniu, e nie chcemy lub nie moemy
odwoa si bezporednio do pl) , musielibymy zastosowa kon
strukcj :
punkt . Us tawWspol rzedne ( 5 . punkt . Pobi e rzWspol rzedne ( ) . y ) ;

Dopisujemy wic brakujce metody, niech bd to : UstawX , Us tawY,


Po bi erzX, Po bi erzY .

C#

1 00

WICZENIE

w i cz e n i a

Brakujce metody klasy Punkt

Zmodyfikuj klas Punkt, dodajc metody umoliwiajce niezalene


ustawianie i odczytywanie wsprzdnych .
publ i c cl a s s Punkt
{
pub l i c i n t x ;
publ i c i nt y ;
publ i c vo i d Us tawWs pol rzedn e ( i n t wspX , i nt wspY )
{
x = wspX ;
y = wspY ;
}
publ i c Punkt Pobi e rzWspol rzedne ( )
{
Punkt punkt = new Punkt( ) ;
punkt . x = x ;
punkt . y = y ;
return pun k t ;
}
publ i c vo i d Us tawX ( i n t wspX )
{
x = wspX ;
}
publ i c vo i d Us tawY ( i n t wspY )
{
y = wspY ;
}
publ i c i nt Pobi e rz X ( )
{
return x ;
}
publ i c i nt Pob i erzY ( )
{
return y ;
}
}

Metody UstawWs pol rzedne i Pobi erzWs pol rzedne maj tak sam posta
jak w wiczeniu 4 . 3 . Metoda UstawX przyjmuje jeden argument typu
i nt (ws pX) i przypisuje jego warto polu x. Metoda UstawY dziaa ana
logicznie, z tym e przypisuje warto otrzymanego argumentu polu y.
Metody Pobi erzX i Pobi erzY po prostu zwracaj wartoci odpowiednich
pl za pomoc instrukcji return (podobnie jak w wiczeniu 4.2) .

Rozdzi a 4.

Kl a s y i o b i e k t y

1o1

Istnieje jeszcze jedna moliwo rwnoczesnego uzyskania wartoci


x i y - mona metodzie pobi erzPunkt ( ) przekaza argument. Wyglda
to nastpujco :
publ i c voi d Pobi erzWspol rzedn e ( Punkt punkt )
{
pun k t . x = x :
pun k t . y = y :
}

Wtedy po wykonaniu metody pola obiektu wskazywanego przez ar


gument punkt przyjm wartoci z pl x i y.
Zatrzymajmy si tu na chwil . Przecie jeeli dopiszemy do klasy
Punkt tak metod, bdzie ona zawieraa dwie metody o takiej samej
nazwie - Pobi erzWs pol rzedne. Czy jest to dopuszczalne? Ot tak,
pod jednym wszake warunkiem - metody te musz si od siebie
rni argumentami wywoania. Sytuacj tak nazywamy przecianiem
metod (ang. method overloading) lub funkcji (ang . Junction overlo
ading). W naszym przypadku jedna metoda nie ma adnych argumen
tw wywoania, druga jako argument przyjmuje referencj do typu
P u n k t . Wszystko zatem jest zgodne z zasadami.
WICZENIE

Przeciqianie metod

Docz do klasy Punkt przecion metod Pobi erzWs pol rzedne.


publ i c cl a s s P u n k t
{
pub l i c i n t x ;
publ i c i nt y ;
publ i c vo i d Us tawWs pol rzedn e ( i n t wspX , i nt wspY )
{
x = wspX :
y = wspY ;
}
publ i c Punkt Pobi e rzWspol rzedne ( )
{
Punkt punkt = new Punkt( ) ;
punkt . X = x ;
punkt . y = y ;
return pun k t ;
}
publ i c vo i d Pobi erzWspol rzedn e ( Punkt pun k t )
{
punkt . x = x ;

C#

1 02

w i cz e n i a

punkt . y = y ;
}
I / Tutaj pozos ta e metody k l asy Punkt z wi czen i a 4 . 6
}

Aby si przekona , e dwie metody o tej samej nazwie faktycznie


mog si znajdowa w jednej klasie i nie spowoduje to kolizji w ich
dziaaniu, napiszemy testow klas P rog ram, ktra bdzie korzystaa
z najnowszej wersji klasy Punkt z wiczenia 4 . 7 .
WICZENIE

Wykorzystanie przecionych metod

Napisz klas P rog ram korzystajc z przecionych metod klasy Punkt.


u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Punkt punkt = new Punkt( ) ;
Punkt pomoc n i czyPunkt = n ew P u n k t ( ) ;
punkt . Pobi erzWspol rzedn e ( pomocn i czyPun k t ) ;
Con sol e . Wr i teli n e ( " Przed us tawi en i em wartoci : " ) ;
Con sol e . Wr i tel i n e (
"Wsp rzdna x = " + pomoc n i czyPun k t . Pob i erz X ( ) ) ;
Con sol e . Wr i tel i n e (
"Wsp rzdna y = " + pomoc n i czyPun k t . Pob i erzY ( ) ) ;
punkt . Us tawWspol rzedne ( l O O . 20 0 ) :
pomocn i czy Punkt = punkt . Pob i e rzWspol rzedne ( ) :
Con sol e . Wri tel i n e ( " \ n Po u stawi en i u wartoci : " ) :
Con sol e . Wr i tel i n e (
"Wsp rzdna x = " + pomoc n i czyPun k t . Pob i erz X ( ) ) :
Con sol e . Wr i tel i n e (
"Wsp rzdna y = " + pomoc n i czyPun k t . Pob i erzY ( ) ) ;
}
}

Na pocztku powstay dwa obiekty typu P u n k t , czyli punkt i pomocni czy


'-+Pun k t . Instrukcja :
punkt . Pobi erzWspol rzedn e C pomocn i czyPun k t ) :

Rozdzi a 4.

Kl a s y i o b i e k t y

1 03

spowodowaa wywoanie metody Pobi erzWs pol rzedne obiektu punkt


i przekazanie jej w postaci argumentu obiektu pomo c n i czyPun k t . To
oznacza, e biece wartoci pl x i y obiektu punkt zostan przypi
sane polom x i y obiektu pomocni czyPunkt. Metoda Pobi erzWs po l rzedne
zostaa te ponownie wywoana po zmianie wsprzdnych obiektu
punkt (za pomoc metody UstawWspol rzedne) . W tym drugim przypadku
bya to przeciona wersja metody nieprzyjmujca argumentw, za
to zwracajca wynik typu Punkt (warto zwrci uwag, e tym samym
pierwotna zawarto zmiennej pomocni czyPunkt zostaa utracona, zo
sta jej natomiast przypisany obiekt typu Punkt powstay w metodzie
pobi erzPunkt; to inna sytuacja ni przy pierwszym wywoaniu tej me
tody, gdy obiekt pozosta ten sam, ale zmieniy si wartoci jego pl) .
W obu przypadkach biece wartoci wsprzdnych zapisanych w po
mocni czyPunkt s wywietlane na ekranie, dziki czemu mona si prze
kona, e wszystko dziaa zgodnie z opisem. Jak wic wida , metoda
pobi erzPunkt przyjmujca argument dziaa bez problemw, mimo e
w klasie Punkt istnieje jej wersja nieprzyjmujca argumentw i zacho
wujca si w nieco inny sposb .

Konstruktory
Zwykle polom danego obiektu chcemy przypisa jakie wartoci po
cztkowe. Jeeli pola te zawieraj zmienne referencyjne, trzeba
wrcz utworzy przypisane im obiekty. Czasami te przed uyciem da
nego obiektu naley wykona bardziej zoony kod. Mona - oczy
wicie - napisa w tym celu dodatkow zwyk metod i uywa jej
np . nastpujco :
Kl a s a obi ekt = n ew K l a s a ( ) ;
obi ekt . I n i c j u j Zmi enn e ( ) :

Zakadajc, e nowo tworzonym obiektom znanej ju dobrze klasy


Punkt miayby by przypisywane pocztkowe wartoci x = 800, y = 600,
metoda ta wygldaaby tak:
voi d I n i cj u j Zmi enne ( )
{
X = 800 ;
y = 600 ;
}

1 04

C#

w i cz e n i a

Gdybymy chcieli nadawa tym polom rne wartoci, w zalenoci


od obiektu, zapewne skorzystalibymy z metody UstawWs pol rzedne
wywoywanej tu po powoaniu obiektu do ycia. Zatem wygldaoby
to tak:
Punkt punkt = new Punkt( ) :
punkt . Us tawWspol rzedne ( 8 0 0 . 60 0 ) :

Czynnoci te mona jednak wykonywa automatycznie . Su do tego


specjalne metody zwane konstruktorami (ang . constructors). Metody
te s wykonywane zawsze przy tworzeniu nowego obiektu. Konstruktory
s publiczne i bezrezultatowe (tzn., e nie mog zwraca wyniku) oraz
maj nazw identyczn z nazw klasy, ktrej dotycz. Mog mie rne
argumenty, moe te istnie kilka konstruktorw dla danej klasy.
Schemat budowy klasy z konstruktorem jest nastpujcy :
publ i c cl a s s nazwa k l asy
{
publ i c nazwa k l asy ( argumenty)
{
//kod konstruktora

}
}

Napiszmy dwa konstruktory dla klasy Punkt. Jeden bdzie bezargu


mentowy i bdzie ustawia wartoci x i y odpowiednio na 800 i 60 0 .
Drugi ustawi wsprzdne na wartoci podane przez uytkownika
w postaci argumentw.
WICZENIE

Konstruktory dla klasy Punkt

Utwrz dwa konstruktory dla klasy Punkt. Jeden powinien by bezar


gumentowy i przypisywa polom klasy wartoci 800 i 60 0 . Drugi ma
przyjmowa dwa argumenty typu i nt.
publ i c cl a s s Punkt
{
pub l i c i n t x :
publ i c i nt y ;
publ i c Punkt ( )
{
X = 800 ;
y = 600 :
}
publ i c Punkt ( i nt wspX . i nt wspY )

Rozdzi a 4.
{

Kl a s y i o b i e k t y

1 05

x = wspX :
y = wspY :

}
I/Tutaj pozostae metody klasy Punkt

Pierwszy konstruktor ma bardzo prost budow . Zgodnie z podanym


wyej schematem nie zwraca adnej wartoci (nie ma te przed nim
sowa voi d !) . We wntrzu polu x przypisywana jest warto 800, a polu y
- warto 600 . Tak wic bd to pocztkowe wartoci kadego obiektu
typu Punkt. Drugi konstruktor dziaa na takiej samej zasadzie jak metoda
UstawWspo l rzedne prezentowana we wczeniejszych wiczeniach. Otrzy
muje argumenty wspX oraz ws pY i przypisuje ich wartoci polom x i y.
Pozostae metody pozostaj takie same jak w poprzednich wiczeniach,
dlatego te nie zostay ponownie zaprezentowane .

Naley zauwazyc , e jeli przetestujemy tak przygotowan klas


Punkt, korzystajc z klasy Prog ram powstaej w wiczeniu 4 . 8 , dwoma
pierwszymi wynikami bd liczby 8 0 0 i 6 0 0 (rysunek 4 . 2 ) , a nie dwa
zera, jak miao to miejsce, kiedy uylimy klasy Punkt z wiczenia 4 . 7 .
Wida wic wyranie, e konstruktor faktycznie zosta wykonany.
Rysunek 4. 2.

Wykorzystanie
klasy Program
z wiczenia 4. 8
w polqczeniu
z klasq Punkt
z wiczenia 4.9

--

C : \cs>Program . exe
Przed ustawi eni em wartosc1 :
800
Ws p r zdna x
Ws p r zdna x = 600
Po ustawi eni u wartoci :
Ws p r zdna x
1
Ws p r zdna y = 2
C : \cs>_

Warto te zwrci uwag, e oba zaprezentowane konstruktory w rze


czywistoci dubluj kod przecionych metod UstawWspol rzedne. Skoro
tak, to dobrym pomysem jest po prostu wywoywanie odpowiednich
wersji tych metod w konstruktorze .

C#

1 06

WICZENIE

w i cz e n i a

Wywoywanie metod w konstruktorach

Zmodyfikuj kod konstruktorw z wiczenia 4 . 9 w taki sposb , aby


korzystay z metody UstawWs pol rzedne.
publ i c cl a s s P u n k t
{
pub l i c i n t x ;
publ i c i nt y ;
publ i c Punkt ( )
{
Us tawWspol rzedne ( 80 0 , 60 0 ) ;
}
publ i c Punkt ( i nt x , i n t y )
{
Us tawWspol rzedne ( x . y ) ;
}
I/Tutaj pozostae metody klasy Punkt

Na zakoi1czenie tego podrozdziau wykonamy jeszcze wiczenie, w kt


rym zostan wywoane oba gotowe konstruktory klasy Punkt, te z wi
czenia 4 . 9 lub 4 . 1 0 . Efekt ich dziaania bdzie taki sam, mimo e osi
gnity w nieco inny sposb .
WICZENIE

Wykorzystanie konstruktorw

Napisz klas korzystajc z obu konstruktorw klasy Punkt powstaych


w wiczeniu 4 . 9 lub 4 . 1 0 .
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Punkt punktl = new P u n k t ( ) ;
Punkt punkt2 = new Punkt ( lOO . 1 0 0 ) ;
Con sol e . Wr i tel i n e (
" Punkt l : Wsp rzdn a x = " + pun k t l . Pobi erzX ( ) ) ;

Rozdzi a 4.

1 07

Kl a s y i o b i e k t y

Con sol e . W ri tel i n e (


" Punkt l : Wsp rzdn a y = " + pun k t l . Pobi erzY ( ) ) ;
Con sol e . Wr i tel i n e (
" Punkt2 : Wsp rzdn a x = " + punkt2 . Pobi erzX ( ) ) :
Con sol e . Wr i tel i n e (
" Punkt2 : Wsp rzdn a y = " + punkt2 . Pobi erzY ( ) ) :
}
}

Powstay dwa obiekty: punktl i punkt2 . W pierwszym przypadku zo


sta uyty konstruktor bezargumentowy, a wic wartoci pola x b
dzie 800, a pola y - 60 0 . W drugim przypadku uyto konstruktora
dwuargumentowego, a wic polom zostan przypisane wartoci przeka
zane w postaci argumentw (czyli x bdzie rwne 1 0 0 i y rwnie b
dzie rwne 100) . Zatem po uruchomieniu programu zobaczymy widok
przedstawiony na rysunku 4 . 3 .
Rysunek 4. 3.

Efekt uycia
konstruktorw
klasy Punkt
w wiczeniu 4. 1 1

OI

. - -

c : \cs>Program . exe
Punkt l : Wsprzdna X
Punkt l : Wsprzdna y
Punkt 2 : Wsprzdna X
Punkt 2 : Wsprzdna y

=
=
=

800
600
100
100

C : \cs >_

Specyfi kato ry dostpu


W dotychczasowych wiczeniach przed sowem cl a s s pojawiao si
zwykle sowo publ i e . Jest to tzw. specyfikator dostpu (lub modyfi
kator dostpu, ang . access modifier), ktry oznacza, e dana klasa
jest publiczna, czyli dostp do niej nie jest ograniczony. Jeeli mody
fikator pub l i c nie pojawi si przed sowem cl as s , taka klasa bdzie
wewntrzna, czyli bdzie si zachowywaa tak, jakby znajdowa si
przed ni modyfikator i nterna l (patrz niej) .
Specyfikatory dostpu pojawiaj si jednak nie tylko przy klasach,
ale take przy skadowych klas (polach, metodach i innych) . Kade
pole oraz metoda (dotyczy to take innych rodzajw skadowych,
ktre nie byy omawiane w ksice) mog by :

1 08

C#

w i cz e n i a

O publiczne (publ i e),


O chronione (proteeted),
O wewntrzne ( i nterna l ),
O wewntrzne chronione (p roteeted i nterna l ) ,
O prywatne (pri vate) .
Publiczne skadowe klasy okrela si sowem pub l i e, co oznacza, e
wszyscy maj do nich dostp i s dziedziczone przez klasy pochodne
(dziedziczenie zostanie opisane w kolejnym podrozdziale) . Do ska
dowych prywatnych (pri vate) mona dosta si tylko z wntrza da
nej klasy, natomiast do skadowych chronionych (proteeted) mona
si dosta z wntrza danej klasy oraz klas potomnych (pochodnych) .
Znaczenie tych specyfikatorw dostpu jest praktycznie takie samo
jak w innych jzykach obiektowych, np . w Javie .
W C# do dyspozycji s jednak dodatkowo specyfikatory i nternal i pro
teeted i nterna l . Sowo i nterna l oznacza, e dana skadowa klasy bdzie
dostpna dla wszystkich klas z danego zestawu. Z kolei proteeted i nter
nal , jak atwo si domyli , jest kombinacj p roteeted oraz i nternal
i oznacza, e dostp do skadowej maj zarwno klasy potomne, jak
i klasy z danego zestawu. Tymi dwoma specyfikatorami nie bdziemy
si bliej zajmowa, jako e nie bd przydatne przy dalszych wi
czeniach . Spotkamy si natomiast ze specyfikatorami publ i e, pri vate
i proteeted .
Zobaczmy, jak to wyglda w praktyce. Wrmy do przykadowej klasy
Punkt. Pola oznaczajce wsprzdne x i y dotychczas byy okrelane
jako publiczne . Oznacza to, e mona si do nich odwoywa bezpo
rednio . Co si jednak stanie, jeli dostp zmieni si na prywatny?
WICZENIE

Skadowe prywatne

Zmodyfikuj kod klasy Punkt z wiczenia 4 . 2 tak, aby skadowe x i y


byy zadeklarowane jako prywatne .
publ i c cl a s s Punkt
{
pri vate i n t x :
pri vate i n t y ;
publ i c i nt GetX ( )
{
return x :

Rozdzi a 4.

Kl a s y i o b i e k t y

1 09

}
publ i c i nt GetY ( )
{
return y :
}
}

WICZENIE

Prba odwoania do skadowych prywatnych

Napisz klas Prog ram, w ktrej nastpi bezporednie odwoanie do


skadowych klasy Punkt z wiczenia 4 . 1 2 . Sprbuj skompilowa otrzy
many kod.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Punkt punkt = new Punkt( ) :
punkt . X
10 :
punkt . y
20 :
Con sol e . Wr i tel i n e ( " Wsp rzdn a x = " + pun k t . X ) :
Con sol e . Wr i tel i n e ( " Wsp rzdn a y
" + pun k t . y ) ;
}
}
=

Kod klasy wyglda standardowo . Utworzony zosta obiekt typu


Punkt, a nastpnie polom x i y zostay przypisane wartoci oraz na
stpio ich wywietlenie na ekranie . Prba kompilacji tego programu
(w poczeniu z klas Punkt z wiczenia 4 . 12) spowoduje jednak wy
cznie wywietlenie czterech komunikatw o bdach (widocznych
na rysunku 4 .4) - po jednym na kade z odwoa do pl klasy - bo
skoro pola te s prywatne, to spoza klasy nie mona si do nich od
woywa ani przy zapisie , ani przy odczycie .

Pamitamy jednak, e w celu ustawiania oraz pobierania wartoci


pl w wykonywanych wczeniej wiczeniach zdefiniowalimy od
powiednie metody. Metody te zostay zdeklarowane jako publiczne,
zatem mamy do nich dostp z innych klas. Oczywicie, metody te (nie
zalenie od tego, czy s publiczne, prywatne, czy chronione) maj
dostp do wszystkich innych metod oraz pl klasy Punkt, poniewa
stanowi skadowe tej klasy.

11o

C#

w i cz e n i a

ii C:\Windows\ system32\cmd.exe

Rysunek 4.4. Prba bezporedniego odwoania do prywatnych skadowych

ldasy koczy si niepowodzeniem

WICZENIE

Uzyskanie dostpu do skadowych prywatnych

Zmodyfikuj kod klasy P rogram z wiczenia 4 . 1 3 oraz klasy Punkt z wi


czenia 4 . 1 2 w taki sposb, aby by moliwy dostp do skadowych x i y.
Nie zmieniaj jednak poziomu dostpu do tych skadowych (pozostaw
modyfikator pri vate) .
publ i c cl a s s Punkt
{
pri vate i n t x :
pri vate i n t y ;
publ i c i nt GetX ( )
{
return x :
}
publ i c i nt GetY ( )
{
return y :
}
publ i c vo i d SetX ( i n t wspX )
{
x
wspX :
}
publ i c vo i d SetY ( i n t wspY )
{
y
wspY :
}
}
=

publ i c cl a s s Program

Rozdzi a 4.
{

111

Kl a s y i o b i e k t y

publ i c stati c voi d M a i n ( )


{
Punkt punkt = new Punkt( ) :
punkt . SetX ( 1 0 ) ;
punkt . SetY ( 20 ) ;
Con sol e . Wr i tel i n e ( " Wsp rzdn a x = " + pun k t . Get X ( ) ) :
Con sol e . Wr i tel i n e ( " Wsp rzdn a y = " + pun k t . GetY ( ) ) ;
}

Dlaczego nie korzystamy wycznie ze skadowych publicznych?


Ot dlatego, aby nie byo bezporedniego dostpu do wntrza danej
klasy. Pozwala to ukry wewntrzn organizacj obiektu, a na ze
wntrz" udostpni jedynie interfejs umoliwiajcy wykonywanie
operacji cile okrelonych przez programist . Przydaje si to zwykle
w bardziej skomplikowanych projektach, jednak nawet na przyka
dzie tak prostej klasy jak Punkt mona pokaza, dlaczego moe by to
potrzebne .
Zamy, e mamy napisany program, ale z pewnych powodw zmie
nilimy reprezentacj wsprzdnych i teraz punkt identyfikujemy za
pomoc kta alfa oraz odlegoci punku od pocztku ukadu wsp
rzdnych (s to tzw. wsprzdne biegunowe , rysunek 4 . 5 ) . Zatem
w klasie Punkt nie ma ju pl x i y, nie maj wic sensu odwoania do
nich. Jeli w takiej sytuacji dostp do skadowych x i y byby pu
bliczny, to nie do, e we wszystkich innych klasach trzeba zmieni
odwoania, to take naley wykona niezbdne przeliczenia . Spowo
dowaoby to naprawd due komplikacje i konieczno wykonania spo
rej pracy nad adaptacj kodu .
Rysunek 4. 5.

Poloenie punktu
reprezentowane
za pomoc
wsplrzdnych
biegunowych

oy

P(x , y )

-------------------

0
'

ox

1 12

C#

w i cz e n i a

Jeeli jednak pola x i y bd prywatne, trzeba bdzie tylko przedefi


niowa metody klasy Punkt. Caa reszta programu nawet nie zauway" ,
e co si zmienio ! Przekonajmy si o tym!
WICZENIE

Zmiana sposobu reprezentacji wsprzdnych

Zmie definicj klasy Punkt z wiczenia 4.10 w taki sposb, aby pooe
nie punktu byo reprezentowane w ukadzie biegunowym.
u s i n g Sy stem :
publ i c cl a s s Punkt
{
pri vate doubl e mod ul :
pri vate doubl e s i n a l fa :
publ i c Punkt ( )
{
Us tawWspol rzedne ( 80 0 . 60 0 ) :
}
publ i c Punkt ( i nt x . i nt y )
{
Us tawWspol rzedne ( x . y ) :
}
publ i c vo i d Us tawWs pol rzedn e ( i n t wspX . i nt wspY )
{
modul = Math . Sqrt (wspX * wspX + wspY * wspY ) :
s i n a l fa = wspY I modul :
}
publ i c Punkt Pobi e rzWspol rzedne ( )
{
Punkt punkt = new Punkt( ) :
punkt . s i n a l fa = s i n a l fa :
punkt . modul = modul :
return pun k t :
}
publ i c vo i d Pobi erzWspol rzedn e ( Punkt pun k t )
{
punkt . s i n a l fa = s i n a l fa :
punkt . modul = modul :
}
publ i c vo i d Us tawX ( i n t wspX )
{
Us tawWspol rzedne (wspX . Pob i e rzY ( ) ) ;
}
publ i c vo i d Us tawY ( i n t wspY )
{
Us tawWspol rzedne ( Pobi erz X ( ) , wspY ) ;

Rozdzi a 4.

Kl a s y i o b i e k t y

1 13

}
publ i c i nt Pobi e rz X ( )
{
doubl e x
modul * Math . Sqrt ( l - s i n a l fa * s i n a l fa ) :
return ( i n t ) x :
}
publ i c i nt Pob i erzY ( )
{
doubl e y
modul * s i n a l fa ;
return ( i n t ) y ;
}
=

Przeliczenie wsprzdnych kartezjaskich (tzn. w postaci x, y) na


ukad biegunowy (czyli kt i modu) nie jest skomplikowane 1 Naj
wygodniejsza jest tu funkcja sinus, dlatego te zostaa uyta w rozwizaniu wiczenia. Zatem sinus kta alfa
, dla oznacze jak

(sin(a)

na rysunku 4. 5)2, reprezentowany przez pole o nazwie s i nal fa, jest rw-

m:du . Natomiast sam modu, reprezentowany przez pole o nazwie


modul , to x 2 y 2 .
ny

Przeliczenie wsprzdnych biegunowych na kartezjaskie jest nieco


trudniejsze. Co prawda, y to po prostu:
modu x

sin( a) ,

za to x wynika ze wzoru :
modu x

1 - sin 2 (a) .

Metoda Math . Sqrt( a rg ) oblicza pierwiastek kwadratowy (drugiego stop


nia) argumentu.
1 W celu uniknicia umieszczania w programie dodatkowych instrukcji
warunkowych zaciemniajcych sedno zagadnienia przedstawiony kod i wzory
s poprawne dla dodatnich wsprzdnych x. Zaprezentowane rozwizanie
nie bdzie take dziaao poprawnie dla punktu o wsprzdnych (0,0)
- niezbdne byoby wprowadzenie dodatkowych instrukcji warunkowych.
Odpowiednie uzupenienie klasy P u n k t w taki sposb, aby usun te
mankamenty, mona potraktowa jako wiczenie do samodzielnego
wykonania.
2

Chodzi o kt pomidzy prost przechodzc przez reprezentowany


punkt i rodek ukadu wsprzdnych a osi OX.

114

C#

w i cz e n i a

Zapis ( nazwa Typu ) zmienna, np . ( i nt ) x, oznacza konwersj zmiennej


do podanego typu - w omawianym przykadzie konwersj wartoci
typu doubl e (bdcej wynikiem oblicze) na typ i nt (niezb dny, aby
zwrci warto x i y, ktre w pierwotnej klasie miay wanie taki typ )3.
Warto te zwrci uwag, e w metodach UstawX i UstawY, jako e usta
wiaj warto tylko jednego z argumentw, konieczne byo uzyska
nie biecej wartoci drugiego argumentu. Dlatego te zostay w nich
uyte metody Pobi erzX i Pobi erzY .
WICZENIE

Testowanie nowej klasy

Wykorzystaj klas P rog ram z wiczenia 4 . 1 1 do przetestowania klasy


Punkt z wiczenia 4 . 1 5 .
Po kompilacji obu klas i uruchomieniu powstaego w ten sposb
programu okae si, e wynik dziaania jest identyczny z wynikiem
z wiczenia 4 . 1 1 , mimo e cakowicie zmienilimy reprezentacj
klasy. Co wicej, nie trzeba byo dokonywa adnych modyfikacji
metody Ma i n w klasie P rogram!

Dziedziczenie
Znamy ju dosy dobrze klas Punkt, zamy jednak, e chcieliby
my mie klas opisujc nie tylko wsprzdne punktu, ale rwnie
jego kolor. Chcielibymy mie rwnie moliwo jednoczesnego ko
rzystania z obu klas . Mona - oczywicie - utworzy now klas
typu Ko l o rowyPunkt, ktra mogaby wyglda np . tak:
publ i c cl a s s Punkt
{
publ i c i nt x . y , kol o r :
}

Nie jest to sposb w peni poprawny, gdy pozbywamy si zupenie czci


uamkowej, zamiast wykona prawidowe zaokrglenie, a w zwizku z tym
w wynikach mog si pojawi drobne niecisoci. eby jednak nie zaciemnia
przedstawianego zagadnienia dodatkowymi instrukcjami, trzeba si z t
drobn niedogodnoci pogodzi.

Rozdzi a 4.

Kl a s y i o b i e k t y

115

Trzeba by do niej dopisa wszystkie zdefiniowane wczeniej metody


klasy Punkt oraz, zapewne, dodatkowo UstawKo l o r ( ) i Po bi erzKo l o r ( ) .
W ten sposb dwukrotnie piszemy ten sam kod. Przecie klasy Punkt
i Kol o rowyPunkt robi w duej czci to samo . Dokadniej mwic ,
klasa Ko l o rowyPunkt jest swoistego rodzaju rozszerzeniem klasy Punkt,
a zatem niech Kol orowyPunkt przejmie wasnoci klasy Punkt, a dodatko
wo dodajmy do niej pole okrelajce kolor. Jest to dziedziczenie znane
m.in. z Javy i C + + . Wtedy klasa Punkt bdzie klas bazow (inaczej
nadrzdn; ang . base class, parent class, superclass), a klasa Ko l o rowy
4-Punkt
klas potomn (inaczej : pochodn, podrzdn; ang . de
rived class, child class, su bclass). Zobaczmy, w jaki sposb wyglda
to w C # . Schemat definicji jest nastpujcy:
-

publ i c cl a s s k l asa_potomna
{

k l asa bazowa

//wntrze klasy

WICZENIE

Proste dziedziczenie

Utwrz klas Kol orowyPunkt rozszerzajc klas Punkt (np . wersj z wi


czenia 4 . 1 0) o moliwo przechowywania informacji o kolorze (moesz
przyj przechowywanie tej informacji w postaci kodu koloru) .
publ i c cl a s s Kol orowyPun kt : Pun k t
{
pri vate i n t k o l o r ;
publ i c Ko l orowyPun k t ( )
{
Us tawKo l or ( 10 0 ) ;
}
publ i c Kol orowyPun k t ( i n t wspX , i nt wspY . i nt n owyKol o r )
{
Us tawX ( wspX ) ;
Us tawY ( wspY ) ;
Us tawKo l o r ( n owyKol o r ) ;
}
publ i c vo i d Us tawKol o r ( i nt n owyKol o r )
{
kol o r
nowyKo l o r ;
}
publ i c i nt Pobi e rz Kol o r ( )
{
return kol or ;
}
}
=

1 16

C#

w i cz e n i a

Klasa Kol orowyPunkt jest rozszerzeniem klasy Punkt (wiadczy o tym


umieszczenie nazwy Punkt po dwukropku za nazw Kol orowyPunkt) .
Znaczy to, e zawiera pola i metody klasy Punkt oraz dodatkowo pola
i metody zdefiniowane w Ko l o rowy P u n k t . Dopisane zostay metody
operujce na nowej skadowej o nazwie kol o r . Poniewa jest ona
prywatna, tylko dziki nim moliwe bdzie pobieranie tej wartoci
(Po bi e r z Ko l o r) oraz jej ustawianie (Us tawKo l o r) . Metody te dziaaj
analogicznie do uywanych we wczeniejszych wiczeniach Pobi erzX
i UstawX .
W klasie dostpne s rwnie dwa konstruktory : bezargumentowy
i trjargumentowy. Pierwszy ustawia warto pola kol or na 1 0 0 (to
warto przykadowa) , natomiast drugi ustawia wartoci wszystkich
pl na zgodne z przekazanymi argumentami. Uywane s przy tym
metody Us tawX i U s t awY odziedziczone z klasy Punkt oraz Us taw Ko l o r
(z klasy Kol orowyPunkt) .
WICZENIE

Uycie klasy potomnej

Napisz klas P rog ram umoliwiajc przetestowanie dziaania klasy


Kol orowyPunkt.
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Ko l o rowyPun kt punkt = n ew Kol orowy Pun k t ( l O O . 2 0 0 . 10 ) ;
Con sol e . Wr i tel i n e ( "wsp rzdn a x = " + pun k t . Pob i erz X ( ) ) ;
Con sol e . Wr i tel i n e ( "wsp rzdn a y = " + pun k t . Pob i erz Y ( ) ) ;
Con sol e . Wr i teli n e ( " k o l o r = " + pun k t . Pob i e rzKol o r ( ) ) ;
}
}

Oczywicie, z klasy Kol orowyPunkt moemy wyprowadzi kolejn kla


s, o nazwie DwuKol orowyPunkt, np . dla punktw, ktre przyjmuj dwa
rne kolory, w zalenoci od znaku wartoci wsprzdnej x. Z klasy
DwuKo l o rowyPunkt moe dziedziczy kolejna klasa itd .
Naley w tym miejscu zwrci uwag na trjargumentowy konstruktor
klasy Kol o rowyPunkt. Oprcz okrelenia koloru przyjmuje on parametry
dotyczce wsprzdnej x oraz wsprzdnej y i przypisuje je odpo-

Rozdzi a 4.

Kl a s y i o b i e k t y

117

wiednim polom. Spenia swoje zadanie, jednak wygodniej byoby po


prostu wywoa konstruktor klasy bazowej (czyli dwuargumentowy
konstruktor z klasy Punkt) . W C# stosuje si tym celu nastpujc kon
strukcj :
Kon struktorKl a sy Potomnej ( argl , arg2 ) : ba s e ( argl ) :

gdzie a rgl to argumenty (moe by ich wiele) konstruktora klasy bazowej,


a a rg2 to argumenty konstruktora klasy potomnej . W konkretnym przy
padku klasy Kol orowyPunkt wywoanie to powinno wyglda nastpujco:
publ i c Ko l orowyPun k t ( i nt wspX , i nt wspY , i n t n owyKol or ) : ba s e ( wspX . wspY )

WICZENIE

Wywoanie konstruktora klasy bazowej

Utwrz klas Ko l o rowyPunkt rozszerzajc klas Punkt o moliwo


przechowywania informacji o kolorze . W konstruktorze klasy potomnej
wywoaj konstruktor klasy bazowej .
publ i c cl a s s Kol orowyPun kt : Pun k t
{
pri vate i n t k o l o r :
publ i c Ko l orowyPun k t ( )
{
Us tawKo l or ( 10 0 ) :
}
publ i c Kol orowyPun kt( i nt wspX . i nt wspY . i nt nowyKol o r )
{
Us tawKo l o r ( n owyKol o r ) :
}
publ i c vo i d Us tawKol o r ( i nt n owyKol o r )
{
kol o r
nowyKo l o r :
}
publ i c i nt Pobi e rz Kol o r ( )
{
return kol or :
}
}

ba se (wspX , wspY )

Klasa ma prawie tak sam posta jak w wiczeniu 4 . 1 7 . Rnice do


tycz konstruktora trjargumentowego . Zostay z niego usunite
wywoania metod UstawX i UstawY, a zamiast nich, korzystajc ze
skadni ze sowem base, zastosowano wywoanie konstruktora klasy
bazowej .

1 18

C#

w i cz e n i a

5
Ta b l ice
Tablice to jedne z podstawoV\T)Tch struktur danych; znane s zapewne
nawet pocztkujcym programistom. Warto jednak w kilku sowach
przypomnie podstawowe wiadomoci i pojcia z nimi zwizane .
Tablica to stosunkowo prosta struktura danych pozwalajca na prze
chowanie uporzdkowanego zbioru elementw danego typu - mona
j sobie wyobrazi tak, jak zaprezentowano na rysunku 5 . 1 . Skada
si z ponumerowanych kolejno komrek, a kada taka komrka moe
przechowywa pewn porcj danych.
Rysunek 5. 1.

Schemat struktury
tablicy
o

Jakiego rodzaju bd to dane, okrela typ tablicy. Jeli zatem zadeklaru


jemy tablic typu cakowitoliczbowego ( i nt) , bdzie moga zawiera
liczby cakowite, a jeli bdzie to typ znakowy (ch a r) , poszczeglne
komrki bd mogy zawiera rne znaki. Naley zwrci uwag, e
w C# (podobnie jak w wikszoci wspczesnych popularnych jzykw
programowania) numerowanie komrek zaczyna si od O, czyli pierw
sza komrka ma indeks O, druga - indeks 1 itd.

120

C#

w i cz e n i a

De kl a rowa n ie ta b l ic
Przed skorzystaniem z tablicy naley zadeklarowa zmienn tablicow.
Poniewa w C# tablice s obiektami, naley rwnie utworzy od
powiedni obiekt. Schematycznie robi si to w sposb nastpujcy:
typ_tab 7 i cy [ ] nazwa_tab 7 i cy

n ew typ_ tab 7 i cy[ 7 i czba_e l emen twJ :

Oczyvvicie, deklaracj zmiennej tablicowej oraz przypisanie jej nowo


utworzonego elementu mona wykona w osobnych instrukcjach, np .
w ten sposb :
typ_tab 7 icy [ J nazwa_tab 7 icy ;
nazwa_tab 7 i cy
new typ _tab 7 icy[ 7 iczba_e 7 emen twJ :
=

Piszc zatem:
i n t tabl i ca [ ] :

zadeklarujemy odniesienie do tablicy, ktra bdzie moga zawiera


elementy typu i nt, czyli 3 2-bitowe liczby cakowite . Samej tablicy
jednak jeszcze nie bdzie (odmiennie ni w przypadku prostych typw
wartociowych, takich jak i nt, byte czy char) i konieczne jest jej utwo
rzenie .
WICZENIE

Utworzenie tablicy

Zadeklaruj i zainicjalizuj tablic elementw typu cakowitego. Przypisz


pierwszemu elementowi tablicy dowoln warto . Wywietl zawarto
tego elementu na ekranie .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ ] tabl i ca = new i nt [ 5 J :
tabl i ca [ O J
10 :
Con sol e . Wr i teli n e ( " P i erwszy e l ement tabl i cy : " + tabl i ca [ O J ) :
}
}
=

R o zd z i a 5 .

Ta b l i c e

121

Wyraenie new tabl i ca [ 5] oznacza utworzenie nowej, jednowymiarowej,


5-elementowej tablicy liczb typu i nt. Ta nowa tablica zostaa przypisa
na zmiennej odnonikowej o nazwie tabl i ca . Od miejsca tego przypi
sania mona odwoywa si do kolejnych elementw tej tablicy, piszc :
t a b l i c a [ i ndexJ

W tym przypadku pierwszemu elementowi (o indeksie O) zostaa przy


pisana warto 1 0 . O tym, e takie przypisanie faktycznie miao miej
sce, przekonalimy si, wywietlajc warto tej komrki na ekranie .

Warto w tym miejscu przypomnie , e elementy tablicy numero


wane s od O , a nie od 1 . Oznacza to, e pierwszy element tablicy
1 0-elementowej ma indeks O, a ostatni 9 (nie 10 ! ) . Co si stanie, jeli
nieprzyzwyczajeni do takiego sposobu indeksowania odwoamy si do
indeksu o numerze 10?
WICZENIE

Odwoanie do nieistniejqcego elementu tablicy

Zadeklaruj i zainicjalizuj tablic 1 0-elementow. Sprbuj przypisa


elementowi o indeksie 10 dowoln liczb cakowit.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ ] tabl i ca = new i nt [ l O J :
tabl i ca [ l O J = l ;
Con sol e . Wr i teli n e ( " E l emen t o i ndek s i e 10 to : " + tabl i ca [ l O J ) ;
}
}

Powyszy kod da si bez problemu skompilowa , jednak przy prbie


uruchomienia takiego programu na ekranie zobaczymy okno z in
formacj o wystpieniu bdu. Moe ono mie rn posta, w za
lenoci od tego, w jakiej wersji systemu zostaa uruchomiona apli
kacja. Na rysunku 5 . 2 jest widoczne okno z systemu Windows 7 .
Rwnie na konsoli (w Windows XP dopiero po zamkniciu okna
dialogowego) ujrzymy komunikat podajcy konkretne informacje o ty
pie bdu oraz miejscu programu, w ktrym wystpi (rysunek 5 . 3 ) .

1 22

C#

Rysunek 5. 2.

Prba odwoania si
do nieistniejcego
elementu tablicy
powoduje blqd
aplikacji

<

w i cz e n i a

program .exe

P rog ram p ro g ram.exe p rzesta dziaa .


Program p rzes.ta dziaa poprawn i e z p owo d u wys.t pienia
problemu. System Wi n d ows za mknie p ro g ra m i powi a d o m i
C i , j el i istni eje d o stpn e rozwi zanie.

iii C:\Win d ows\system32\cmd.exe

Rysunek 5. 3. Systemowa informacja o bdzie

Wbrew pozorom, nie stao si nic strasznego . Program, co prawda,


nie dziaa, ale bd zosta vvychvvycony przez rodowisko uruchomie
niowe . Konkretnie mwic, zosta -wygenerowany tzw. -wyjtek i aplika
cja zakoczya dziaanie . Taki -wyjtek mona jednak przechvvyci i tym
samym zapobiec niekontrolowanemu zakoczeniu -wykonywania kodu.
To jednak odrbny temat, ktry zostanie przedstawiony w rozdziale 6 .
Wane jest to, e prba odwoania si do nieistniejcego elementu zo
staa -wykryta i to odwoanie nie -wystpio! Program nie naruszy wic
obszaru pamici niezarezerwowanej dla niego.

l n icja l izacja ta b l ic
Tablic mona zainicjalizowa ju w momencie jej tworzenia . Dane ,
ktre maj si znale w poszczeglnych komrkach, podaje si w na
wiasach klamrovvych po deklaracji tablicy. Schematycznie wyglda to
nastpujco :
typ [ ] nazwa

new typ [ l i czba e l ementwJ { dana l , dana2 . . . . . danaN}

R o zd z i a 5 .

Ta b l i c e

1 23

Jeli zatem chcielibymy utworzy 5-elementow tablic liczb cakowi


tych i od razu zainicjalizowa j liczbami od 1 do 5 , moemy zrobi
to w taki sposb :
i n t [ ] tabl i ca = new i nt [ 5 J { l , 2 . 3 . 4 . 5 } :

WICZENIE

lnicjalizacja tablicy

Zadeklaruj tablic 5-elementow typu i nt i zainicjalizuj j liczbami


od 1 do 5. Zawarto tablicy wywietl na ekranie .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ ] tabl i ca = new i nt [ 5 J { l . 2 . 3 . 4 , 5 } :
fo r ( i n t i = O : i < 5 ; i ++ )
{
Con s o l e . W r i tel i ne ( "tabl i ca [ { O } J = { l }" , i , t a b l i ca [ i J ) :
}
}
}

Wynik dziaania kodu z powyszego wiczenia widoczny jest na ry


sunku 5 .4 . Nie jest niespodziank, e wywietlone zostay liczby od
1 do 5, natomiast indeksy kolejnych komrek zmieniaj si od O do 4 .
Powstaa tu bowiem 5-elementowa tablica liczb typu i nt. Skoro ma 5
elementw, to pierwszy z nich ma indeks O, a ostatni
4. Dlatego
zmienna sterujca ptli for, ktra odczytuje dane z tablicy, ma poczt
kow warto O, a warunek zakof1czenia ptli to i < 5 . Tym samym i
zmienia si te od O do 4 .
-

Rysunek 5.4.

Zawarto
kolejnych komrek
tablicy utworzonej
w wiczeniu 5. 3

1 24

C#

w i cz e n i a

Kiedy inicjalizowana jest tablica o z gry znanej liczbie elementw,


dopuszcza si pominicie fragmentu kodu zwizanego z tworzeniem
obiektu. Kompilator sam wykona odpowiednie uzupenienia . Zamiast
pisa :
typ [ ] nazwa = new typ [ 7 i czba_e 7 ementwJ { dana l . dana2 . . . . . danaN}

mona zatem rwnie dobrze uy konstrukcji :


typ [ ] nazwa = { danal . dana2 . . . . . danaN}

Oba sposoby s rwnowane i naley uywa tego, ktry jest wygod


n1e1szy.
WICZENIE

Bezporednia inicjalizacja tablicy

Zadeklaruj tablic 5-elementow typu i nt i zainicjalizuj j liczbami


od 1 do 5. Uyj drugiego z poznanych sposobw inicjalizacji. Zawarto
tablicy wywietl na ekranie .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ ] tabl i ca = { l . 2 . 3 . 4 . 5 } :
fo r ( i n t i = O : i < 5 : i ++ )
{
Con s o l e . W r i tel i ne ( "tabl i ca [ { O } J = { l }" . i . t a b l i ca [ i ] ) :
}
}
}

Rozmi a r ta b l icy
Kada tablica posiada waciwo Length, ktra okrela biec liczb
komrek. Aby uzyska t informacj, piszemy:
tab 7 i ca . Length

R o zd z i a 5 .

Ta b l i c e

1 25

Przy tym dopuszczalny jest tylko odczyt, czyli prawidowa jest kon
strukcja :
i n t rozmi a r

tabl i c a . Length ;

ale nieprawidowy jest zapis :


t a b l i c a . Length

WICZENIE

10 :

Odczyt rozmiaru tablicy

Utwrz tablic o dowolnym rozmiarze . Odczytaj warto waciwoci


Length i wywietl j na ekranie .
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ ] tabl i ca
{
10 . 9 . 8 . 7 . 6 . 5 . 4 . 3 . 2 . 1
};
Con sol e . Wr i te ( " L i czba e l ementw tabl i cy : " ) ;
Con sol e . Wr i teli n e ( tabl i ca . Length ) ;
}
}
=

WICZENIE

Waciwo Length i ptla for

Utwrz tablic zawierajc pewn liczb wartoci cakowitych. Zawar


to tablicy wywietl na ekranie za pomoc ptli fo r . Do okrelenia
rozmiaru tablicy uyj waciwoci Length .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ ] tab
{
10 . 9 . 8 . 7 . 6 . 5 . 4 . 3 . 2 . 1 .
1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . 10
=

1 26

C#

w i cz e n i a

};
fo r ( i n t i = O ; i < tab . Length : i ++ )
{
Con so l e . W r i tel i ne ( "tab [ " + i + " ] = " + tab [ i J ) :
}
}
}

Zasada odczytu danych w tym przykadzie jest taka sama jak w wi


czeniach 5 . 3 i 5 .4, z t rnic, e rozmiar tablicy jest okrelany za
pomoc waciwoci Length (tab . Length) . Dziki temu mona np . do
pisa dowoln liczb nowych danych w instrukcji inicjalizujcej ta
blic, a kod ptli for nie bdzie wymaga adnych zmian. Nowy rozmiar
zostanie uwzgldniony automatycznie .

Do zapisywania danych (podobnie jak do odczytu) w tablicach cz


sto uywa si ptli (przedstawionych w rozdziale 2 .) . Jest to wrcz
niezbdne, gdy trudno si spodziewa, aby mona byo rcznie"
zapisa wartoci z wicej ni kilkunastu czy kilkudziesiciu komrek.
Wielko tablicy nie musi te by z gry znana, moe wynika z danych
uzyskanych w trakcie dziaania programu. Z tablicami mog wsppra
cowa dowolne rodzaje ptli. W niektrych przypadkach bardzo wy
godna jest omwiona w kolejnym podrozdziale ptla foreach .
WICZENIE

Uycie ptli do zapisu danych w tablicy

Uyj ptli for do zapisania w 10-elementowej tablicy 1 0 kolejnych liczb


cakowitych.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ ] tab = new i nt [ l O J :
fo r ( i n t i = O ; i < tab . Length ; i ++ )
{
tab [ i J = i + l ;
}
Con sol e . Wr i teli n e ( " Zawa rto tabl i cy : " ) ;
fo r ( i n t i = O ; i < tab . Length ; i ++ )
{

R o zd z i a 5 .

Ta b l i c e

1 27

Con so l e . W r l tel l n e ( "tab[ { O } J = { l }" . i . tab [ i ] ) ;


}
}
}

Powstaa 10-elementowa tablica liczb typu i nt . Mamy w niej zapisa


wartoci od 1 do 10, czyli komrka o indeksie O ma mie warto 1, o in
deksie 1 - warto 2 itd. A zatem warto komrki ma by zawsze o 1
wiksza ni warto indeksu (zmiennej i ) . Dlatego instrukcja wewntrz
ptli ma posta :
tabl i ca [ i J = i + l ;

Druga ptla fo r suy tylko do wywietlania danych zawartych w ta


blicy. Jej konstrukcja jest taka sama jak w pierwszym przypadku.
Wewntrz ptli znajduje si instrukcja wywietlajca wartoci kolej
nych komrek.

Ptl a fo reach
Dotychczas poznalimy trzy rodzaje ptli : fo r, wh i l e i do.wh i l e (bya
o nich mowa w rozdziale 3 .) . W przypadku tablic (jak rwnie kolekcji,
ktre w tej ksice nie byy omawiane1) mona rwnie skorzysta
z ptli typu fo reach . Jest ona bardzo wygodna, gdy umoliwia prost
iteracj po wszystkich elementach tablicy; nie trzeba wtedy wprowa
dza dodatkowej zmiennej iteracyjnej . Ptla fo reach ma nastpujc
posta :
foreac h ( typ i dentyfi ka tor i n wyraen i e )
{
//instrukcje

Jeeli zatem mamy tablic o nazwie tab zawierajc liczby typu i nt,
moemy zastosowa konstrukcj :

1 cilej rzecz ujmujc, ptli fo rea c h mona uy z kadym obiektem


udostpniajcym tzw. iterator. Ten temat nie bdzie jednak poruszany
w ksice.

1 28

C#

w i cz e n i a

foreac h ( i n t v a l i n tab )
{
//instrukcje

Wtedy w kolejnych przebiegach ptli pod val bd podstawiane kolejne


elementy tablicy. Sowo val jest tu identyfikatorem odczytywanej
wartoci (mona je traktowa jak zmienn) . Oczywicie, mona je
zmieni na dowolne inne .
WICZENIE

Uycie ptli foreach do wywietlenia zawartoci tablicy

Wykorzystaj ptl fo r e a c h do wywietlenia wszystkich elementw


tablicy przechowujcej liczby cakowite .
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ ] tab = new i nt [ l O J ;
fo r ( i n t i = O ; i < 1 O ; i ++ )
{
tab [ i J = i ;
}
fo reach ( i n t i i n tab )
{
Con so l e . W r i tel i n e ( i ) ;
}
}
}

Tablica tab zostaa zainicjalizowana w ptli for kolejnymi liczbami od O


do 9. Do wywietlenia danych zostaa natomiast uyta ptla fo reach .
W kadym jej przebiegu pod identyfikator val jest podstawiana warto
kolejnego elementu tablicy. W pierwszym przebiegu jest to pierwszy
element (o indeksie O ) , w drugim - drugi element (o indeksie 1) itd.
Ptla koi1czy si po osigniciu ostatniego elementu (o indeksie 9) .

R o zd z i a 5 .

WICZENIE

Ta b l i c e

1 29

Zliczanie wartoci w ptli foreach

Wykorzystaj ptl fo reach do sprawdzenia, ile jest liczb parzystych,


a ile nieparzystych w tablicy z elementami typu i nt .
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ ] tab = new i nt [ l O O J ;
i n t pa rzyste = O . n i epa rzyste = O ;
Random rand = new Random ( ) ;
fo r ( i n t i = O ; i < 100 ; i ++ )
{
tab [ i J = rand . Next ( ) ;
}
fo reach ( i n t i i n tab )
{
i f ( i % 2 == o)
{
pa rzys te++ ;
}
el se
{
n i epa rzyste++ ;
}
}
Con sol e . Wr i teli n e ( " Pa rzys te : { O }" . pa rzyste ) ;
Con sol e . Wr i teli n e ( " N i epa rzyste : { O }" . n i epa rzyste ) ;
}
}

Powstaa tablica tab typu i nt, 1 00-elementowa. Do wypenienia jej


danymi zostaa uyta ptla fo r oraz obiekt rand typu Random, za pomoc
ktrego uzyskujemy wartoci pseudolosowe . Dokadniej rzecz ujmujc,
kolejn pseudolosow liczb cakowit otrzymujemy, wywoujc
metod Next tego obiektu. W ptli fo reach badamy, ktre z komrek
tablicy tab zawieraj wartoci parzyste, a ktre - nieparzyste . Aby
to stwierdzi , uywamy operatora dzielenia modulo . Gdy wynikiem
tego dzielenia jest O, dana komrka zawiera liczb parzyst (jest wtedy
zwikszana warto pomocniczej zmiennej pa rzyste) , natomiast gdy
wynik dzielenia jest rny od O, komrka zawiera warto nieparzyst

1 30

C#

w i cz e n i a

(jest wtedy zwikszana warto pomocniczej zmiennej n i epa rzys te) .


Po zakoi1czeniu ptli na ekranie wywietlany komunikat z poszuki
wan informacj (uywane s wartoci pobrane ze zmiennych pa rzyste
i ni epa rzyste) .

Ta b l ice wiel owym ia rowe


Tablice nie musz by jednowymiarowe, jak w dotychczas prezen
towanych przykadach . Tych wymiarw moe by wicej , np . dwa
- otrzymujemy wtedy struktur widoczn na rysunku 5 . 5, czyli rodzaj
tabeli o zadanej liczbie wierszy i kolumn . W tym przypadku s dwa
wiersze oraz pi kolumn . Oczywicie, aby w takiej sytuacji jedno
znacznie wyznaczy komrk , trzeba poda dwie liczby : indeks
wiersza i indeks kolumny.
Rysunek 5. 5.

Przykad tablicy
dwuwymiarowej

o
1

W jaki sposb mona zadeklarowa tego typu tablic? Zacznijmy od


deklaracji samej zmiennej tablicowej . Dla tablicy dwuwymiarowej
ma ona posta :
typ_tab l i cy[ , J nazwa_tab l i cy ;

Sam tablic tworzy si za pomoc instrukcji:


new i n t [wi ersze . ko l umny] ;

Przykadowo dvvuwymiarow tablic widoczn na rysunku 5 . 5 utwo


rzymy nastpujco (przy zaoeniu, e ma przechowywa liczby ca
kowite) :
i n t [ . ] tabl i ca = new tabl i ca [ 2 . 5 ] ;

Inicjalizacja komrek moe odbywa si, podobnie jak w przypadku


tablic jednowymiarowych, ju w trakcie deklaracji:

R o zd z i a 5 .
typ tab 7 i cy [ , J nazwa tab 7 i cy
{
( danal , dana2 ) ,
( dana3 , dana4 ) ,
-

Ta b l i c e

1 31

( danaM. danaN )
};

Zobaczmy, jak wyglda to na konkretnym przykadzie .


WICZENIE

Tworzenie tablicy dwuwymiarowej

Zadeklaruj tablic dwuwymiarow typu i nt o dwch wierszach i piciu


kolumnach i zainicjalizuj j kolejnymi liczbami cakowitymi. Zawar
to tablicy wywietl na ekranie .
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ . ] tabl i ca = new i n t [ 2 . 5 ] ;
i n t l i czn i k
O;
fo r ( i n t i
O ; i < 2 : i ++ )
{
for ( i nt j = O : j < 5 ; j ++ )
{
tabl i ca [ i . j ]
l i czn i k++ :
}
}
< 2 : i ++ )
fo r ( i n t i = O :
{
for ( i nt j = O : j < 5 ; j ++ )
{
Con sol e . Wr i tel i n e (
" tabl i ca [ { O } . { l } J
{ 2 }" . i . j , tabl i ca [ i . j J ) :
}
}
}
}
=

Jak wida, do wypeniania tablicy uyto dwch zagniedonych ptli


fo r. Pierwsza, zewntrzna, odpowiada za iteracj po indeksach wier
szy tablicy, druga za iteracj po indeksach kolumn. Zmienna l i czn i k
suy jako licznik i jest w kadym przebiegu zwikszana o jeden, dziki
czemu w kolejnych komrkach uzyskujemy kolejne liczby cakowite . Po
wypenieniu danymi tablica przyjmie posta widoczn na rysunku 5 . 6 .

1 32

C#

Rysunek 5. 6.

Tablica z wiczenia 5. 1 0
po wypelnianiu danymi

w i cz e n i a
o

Do wywietlenia danych uywana jest analogiczna konstrukcja z dwo


ma zagniedonymi ptlami. Po uruchomieniu kodu na ekranie zo
baczmy widok przedstawiony na rysunku 5 . 7 . Jak wida, dane te
zgodne s ze struktur przedstawion na rysunku 5 . 6 .
Rysunek 5. 7.

Wynik dzialania
program u
z wiczenia 5. 1 0

Tablica dwuwymiarowa nie musi mie, tak jak w poprzednich przy


kadach, ksztatu prostoktnego, tzn. takiego, gdzie liczba komrek
w kadym wierszu i kadej kolumnie jest staa . Rwnie dobrze mona
utworzy np . tablic o ksztacie trjkta (rysunek 5 .8 A) lub zupenie
nieregularn (rysunek 5 . 8 B) . Przy tworzeniu struktur nieregularnych
trzeba si jednak wicej napracowa , gdy kady wiersz zazwyczaj
naley tworzy rcznie, piszc odpowiedni lini kodu.
Rysunek 5. 8.

Przyklady bardziej
skomplikowanych tablic
dwuwymiarowych

R o zd z i a 5 .

Ta b l i c e

1 33

Postarajmy si utworzy struktur przedstawion na rysunku 5 . 8 B .


Naley zauway, e kady wiersz mona traktowa jak oddzieln
tablic jednowymiarow. Zatem jest to jednowymiarowa tablica, ktrej
poszczeglne komrki zawieraj inne jednowymiarowe tablice . Inaczej
mwic, jest to tablica tablic . Wystarczy wic zadeklarowa zmienn
tablicow o odpowiednim typie, a nastpnie poszczeglnym jej ele
mentom przypisa nowo utworzone tablice jednowymiarowe o zadanej
dugoci. Oto cae rozwizanie problemu.
Jednak co znaczy okrelenie odpowiedni typ tablicy"? Pomylmy jeli w tablicy (je dnowymiarowej) miay by przechowywane liczby
cakowite typu i nt, typem tej tablicy by i nt . Pisalimy wtedy :
i n t [ ] tabl i ca :

Jeli zatem typem nie jest i nt, ale tablica typu i nt, ktr oznacza si
jako i nt [ J , naley napisa :
i n t [ J [ J tabl i ca :

Z kolei utworzenie 4-elementowej tablicy zawierajcej tablice z liczbami


cakowitymi wymaga zapisu :
new tabl i ca [4J [ J ;

Te wiadomoci powinny wystarczy do wykonania kolejnego wi


czenia.
WICZENIE

Budowa tablicy nieregularnej

Napisz kod tworzcy struktur tablicy widocznej na rysunku 5 . 8 B ,


przechowujcej liczby cakowite . W kolejnych komrkach powinny
znale si kolejne liczby cakowite od 1 do 1 0 .
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ J [ J tabl i ca = n ew i nt [4J [ J ;
tabl i ca [ O J = new i n t [4J { l . 2 . 3 . 4 } :
tabl i ca [ lJ = new i n t [ 2J { 5 . 6 } ;
tabl i ca [2J = new i n t [ 3J { 7 . 8 . 9 } :
tabl i ca [3J = new i n t [ l J { l O } ;
}
}

1 34

C#

w i cz e n i a

Po wypenieniu danymi tablica z wiczenia bdzie miaa posta przed


stawion na rysunku 5 . 9 . Jak sobie poradzi z wywietleniem jej za
wartoci na ekranie? Oczywicie, mona zrobi to rcznie, piszc kod
oddzielnie dla kadego wiersza . Przy tak maej tablicy nie bdzie to
problemem. Czy jednak tej czynnoci nie da si zautomatyzowa?
Najwygodniej byoby przecie wyprowadza dane na ekran w zagnie
donych ptlach, tak jak w wiczeniu 5 . 1 0 .
Rysunek 5. 9.

Tablica z wiczenia
5. 1 1 wypelniona
przykladowymi
danymi

10
Oczywicie, jest to jak najbardziej moliwe, a z nieregularnoci ta
blicy mona sobie poradzi w bardzo prosty sposb . Przecie kada
tablica ma, omwion wczeniej w tym rozdziale, waciwo Length,
przy uyciu ktrej da si sprawdzi jej dugo . To cakowicie rozwi
zuje problem wywietlenia danych nawet z tak nieregularnej struktury
jak obecnie opisywana.
WICZENIE

Wywietlanie danych z tablicy nieregularnej

Zmodyfikuj kod z wiczenia 5 . 1 1 w taki sposb , aby dane zawarte


w tablicy zostay wywietlone na ekranie (rysunek 5 . 10) . W tym celu
uyj zagniedonych ptli fo r .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ ] [ ] tabl i ca = n ew i nt [4J [ J :
tabl i ca [ O J = new i n t [4J { l . 2 , 3 . 4 } :
tabl i ca [ l] = new i n t [ 2J { 5 . 6 } :

R o zd z i a 5 .

Ta b l i c e

1 35

tabl i ca [2J = new i n t [ 3J { 7 . 8 . 9 } :


tabl i ca [3J = new i n t [ l J { l O } :
fo r ( i n t i = O : i < tabl i c a . Length ; i ++ )
{
Con s o l e . W r i te ( "tabl i ca [ { O } J = " , i ) ;
fo r ( i n t j = O : j < tabl i ca [ i J . Length : j++ )
{
Con sol e . Wr i te( " [ { O } J " , tab l i c a [ i ] [j ] ) :
}
Con so l e . W r i tel i n e ( " " ) ;
}
}
}

Do wywietlenia danych rwnie zostay uyte dwie zagniedone ptle


fo r. W ptli zewntrznej jest umieszczona instrukcja Consol e . Wr i te
"+( "tabl i ca [ { O } J = " , i ) ; , wywietlajca numer aktualnie przetwarza
nego wiersza tablicy, natomiast w ptli wewntrznej znajduje si in
strukcja Consol e . Wr i te ( " { O } " , tab [ i ] [ j ] ) ; , wywietlajca zawarto
komrek w danym wierszu.
Rysunek 5. 10.

Wywietlenie danych
z nieregularnej tablicy
w wiczeniu 5. 1 2

(::.

C : \cs>Pr o gr am . exe
tabl i ca [OJI
[1] [2]
tabl i ca [ l] = [ 5 ] [6]
tabl i ca [2] = [7] [8]
tabl i ca [ 3] = [10]
=

1c : \cs>_

[ 3]
[9]

[ 4]

1 36

C#

w i cz e n i a

6
Wyjqtki i obsuga bd w
O bsuga bdw
W kadym wikszym programie wystpuj jakie bdy. Oczywicie,
staramy si ich wystrzega , nigdy jednak nie uda si ich cakowicie
wyeliminowa . Co wicej, aby program wychwytywa przynajmniej
cz bdw, ktrych przyczyn jest np . wprowadzenie zych wartoci
przez uytkownika, trzeba napisa wiele wierszy dodatkowego kodu,
ktry zaciemnia gwny kod programu . Jeeli przykadowo zadekla
rowalimy tablic 5-elementow, naleaoby sprawdzi, czy nie od
woujemy si do nieistniejcego elementu.
WICZENIE

Bdne odwoanie do tablicy

W klasie Ma i n zadeklaruj tablic 5-elementow. Sprbuj odczyta war


to nieistniejcego, 2 0 . elementu tej tablicy.
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i n t [ ] tab = new i nt [ 5 J ;
i n t val ue = tab [ l9J ;

C#

1 38

w i cz e n i a

Con sol e . Wr i tell n e ( " E l emen t n r 20 ma wa rto : " + v a l ue ) :


}
}

Oczywicie, prba wykonania powyszego kodu spowoduje bd,


poniewa nie ma w tablicy tab elementu o indeksie 19 (czyli dwu
dziestego; elementy s numerowane od O) . Najpierw zobaczymy wy
wietlone przez rodowisko uruchomieniowe (CLR) okno z informacj,
e aplikacja wygenerowaa bd, a nastpnie na konsoli pojawi si
komunikat podajcy dokadny typ bdu. Tego typu reakcj spotkalimy
ju w rozdziale 5 . (rysunki 5 . 2 i 5 . 3 ) .

W powyszym przykadzie popeniony bd jest ewidentnie widoczny.


Skoro tablica miaa 5 elementw, na pewno nie mona odwoa si do
elementu o indeksie 1 9 . Gdyby jednak deklaracja tablicy znajdowaa
si w jednej klasie, a odwoanie do niej - w drugiej klasie , nie byoby
to tak oczywiste .
WICZENIE

Odwoania do tablicy pomidzy klasami

Napisz takie dwie klasy, aby w j e dnej znaj dowaa si tablica


5-elementowa, a w drugiej nastpowao odwoanie do tej tablicy.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Tabl i ca tab = new Tabl i ca ( ) ;
i n t v a l ue = tab . get E l emen t ( 20 ) :
Con sol e . Wr i teli n e ( " E l emen t n r 20 ma wa rto : " + v a l ue ) :
}
}
publ i c cl a s s Tabl i ca
{
i n t [ ] tab :
publ i c Tabl i c a ( )
{
tab = new i n t [ 5J :
}
publ i c i nt getEl ement ( i nt i ndex )
{

Rozdzi a 6 .

Wyj q t k i i o b s u g a b d w

1 39

return tab [ i ndexJ :


}
}

W klasie Tabl i ca znajduje si pole typu tablicowego, ktremu w kon


struktorze przypisywana jest nowa tablica (przechowujca wartoci
cakowite typu i nt) o wielkoci 5 elementw. Do pobierania danych
z tej tablicy suy metoda getEl ement przyjmujca jako argument in
deks poszukiwanego elementu . W kodzie klasy P rog ram nastpuje
utworzenie nowego obiektu tab typu Tabl i ca oraz wywoanie metody
getEl ement tego obiektu. W kodzie klasy Program nie widzimy jednak,
jaki rozmiar ma tablica znajdujca si w obiekcie tab (klasy P rogram
i Tabl i ca mog si przecie znajdowa w rnych plikach) . Bardzo atwo
mona wic przekroczy maksymalny indeks i spowodowa bd .
Tak te dzieje si w tym przypadku. Efekt dziaania programu bdzie
wic bardzo podobny do tego z wiczenia 6 . 1 .

Bdw z wiczenia 6 .2 mona unikn, sprawdzajc, czy warto po


dawana jako argument metody getEl ement nie przekracza dopuszczal
nego zakresu, czyli przedziau O 4 . Takie sprawdzenie mona wyko
na, stosujc znan ju instrukcj i f.
-

WICZENIE

Sprawdzanie zakresu indeksw tablicy

Popraw kod z wiczenia 6 . 2 tak, aby po przekroczeniu dopuszczal


nego indeksu tablicy nie wystpowa bd w programie . Wprowad
do metody getEl ement instrukcj sprawdzajc, czy nastpuje prze
kroczenie zakresu indeksw tablicy.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Tabl i ca tab = new Tabl i ca ( ) :
i n t v a l ue
tab . get E l emen t ( 20 ) :
i f ( va l ue
-1)
{
Con s o l e . W r i tel i n e ( " N i e ma e l ementu o podanym numerze 1 " ) :
}
el se
{
=

==

C#

1 40

w i cz e n i a

Con s o l e . W r l tel 1 n e ( " El ement n r 20 ma wa rto : " + v a l ue ) :


}
}
}
publ 1 c cl a s s Tabl 1 ca
{
1 n t [ J tab ;
publ 1 c Tabl 1 c a ( )
{
tab = new 1 n t [ 5J :
}
publ 1 c 1 nt getEl ement ( 1 nt 1 ndex )
{
1 f ( ( 1 ndex >= 0 ) && ( 1 ndex < 5 ) )
{
return ta b [ 1 ndexJ ;
}
el se
{
return - l ;
}
}
}

Tak przygotowany kod reaguje poprawnie na prb odwoania si do


nieistniejcego elementu tablicy (rysunek 6 .1). W metodzie getEl ement
klasy Tabl i ca nastpuje sprawdzenie, czy indeks przekazany jako ar
gument jest waciwy, czyli czy mieci si w zakresie O 4 . W tym
celu jest uywana instrukcja warunkowa i f. Gdy zakres jest prawi
dowy, zwracana jest warto zapisana w tablicy pod tym indeksem,
gdy natomiast jest nieprawidowy, zwracana jest warto - 1 . Mona
by oczywicie zakoczy wykonywanie programu ju w metodzie
getEl ement, zwykle jednak trzeba poinformowa funkcj wywoujc
o wystpieniu bdu.
-

W metodzie Ma i n klasy Program badana jest warto zwrcona przez wy


woanie tab . getEl ement ( 20 ) . Jeli jest to - 1, oznacza to wystpienie bdu.
Wtedy wywietlany jest komunikat. Gdy otrzymana warto jest rna
od - 1, jest to warto pobranego elementu. I ta warto jest wywietlana.
Rysunek 6. 1.

Odwalanie do nieistniejcego
elementu nie powoduje
ju bldu aplikacji

Rozdzi a 6 .

Wyj q t k i i o b s u g a b d w

1 41

Sposb przedstawiony w wiczeniu 6 . 3 sprawdzi si w praktyce, ma


jednak pewn wad, ktra w pewnych sytuacjach moe by dyskwa
lifikujca. Ot aden z elementw tablicy nie moe mie wartoci
rwnej - 1 . To ograniczenie funkcjonalnoci programu. Mona jednak
poradzi sobie z tym problemem, dodajc do klasy Tabl i ca pole typu
bool ean (np . o nazwie i s E rror) sygnalizujce wystpienie bdu.
WICZENIE

Sygnalizacja wystpienia bdu

Zmodyfikuj kod z wiczenia 6 . 3 tak, aby o wystpieniu bdu infor


mowao dodatkowe pole umieszczone w klasie Tabl i ca .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Tabl i ca tab = new Tabl i ca ( ) :
i n t v a l ue = tab . get E l emen t ( 20 ) :
i f ( tab . i s Er ro r )
{
Con s o l e . W ri teli n e ( " N i e ma el ementu poda nym n umerze l " ) :
}
el se
{
Con s o l e . Wri teli n e ( " El ement n r 20 ma wa rto : " + v a l ue ) :
}
}
}
publ i c cl a s s Tabl i ca
{
i n t [ ] tab :
publ i c bool i s Erro r :
publ i c Tabl i c a ( )
{
tab = new i n t [ 5J :
i s E rror = f a l se :
}
publ i c i nt getEl ement ( i nt i ndex )
{
i f ( ( i ndex >= 0 ) && ( i ndex < 5 ) )
{
i s Error = fa l s e :
return ta b [ i ndexJ :

1 42

C#

w i cz e n i a

}
el se
{
i s Error
true :
return - 1 :
}
=

}
}

Tym razem informacja o tym, czy wystpi bd, jest zawarta w polu
i s E rro r, ktremu w konstruktorze przypisywana jest pocztkowa
warto fa l s e . W metodzie getEl ement w standardowy sposb bada
si zakres wartoci argumentu i ndex. Jeeli zawiera si on w prawi
dowym przedziale, pole i s E rror otrzymuje warto fa l s e i zwracana
jest warto elementu pobranego z tablicy . W przeciwnym razie pole
i s E r r o r otrzymuje warto t r u e , co sygnalizuje wystpienie bdu,
i zwracana jest warto - 1 . Co prawda, jest ona w takim przypadku bez
uyteczna, ale instrukcja return nie moe si oby bez podania war
toci typu i nt, gdy tak warto musi zwrci metoda getEl ement.
W klasie P rog ram, korzystajcej z obiektw typu Tabl i ca , po wywoa
niu metody getEl ement badany jest stan pola i s E rror obiektu tab. Gdy
jest rwne true (i f(tab . i s Erro r ) ) , wypisywany jest komunikat o bdzie,
a gdy jest rwne fal se, wywietlana jest warto pobranego elementu .

Jak pokazano w dotychczasowych wiczeniach, z bdami mona ra


dzi sobie na rne sposoby. Nie da si jednak nie zauway , e tego
typu rozwizania powoduj dodawanie coraz to wikszej liczby no
wych zmiennych i warunkw. Warto wic skorzysta z jakiej innej
metody obsugi bdw. Z pomoc przychodz tutaj tzw. wyjtki
(ang. exceptions). Wyjtek (ang. exception) jest to byt programistycz
ny, ktry powstaje w chwili wystpienia bdu. Moemy go jednak
przechwyci i wykona nasz wasny kod obsugi bdu. Jeeli tego
nie zrobimy, zostanie obsuony przez system, a na konsoli (o ile
program zosta uruchomiony na konsoli) pojawi si komunikat z in
formacj, gdzie i jakiego typu bd wystpi . Przykadowo w wicze
niu 6 . 1 wystpowa wyjtek o nazwie I ndexOutOfRangeExcept i on (po
dobnie jak w wiczeniu 5 . 2, w rozdziale 5 ., co wida byo wyranie na
rysunku 5 . 3). Oznacza on, e zosta przekroczony dopuszczalny zakres
indeksu w tablicy.

Rozdzi a 6 .

Wyj q t k i i o b s u g a b d w

1 43

Blok try... catch


Do obsugi wyjtkw suy blok try.catc h , ktrego schemat wykorzy
stania wyglda nastpujco :
t ry
{
//blok instrukcji mogcy spowodowa: wyjtek

}
catch ( TypWyj tkul i den tyfi ka torWyjtkul )
{
//obsuga wyjtku 1

}
catch ( TypWyj tku2 i den tyfi ka torWyjtku2)
{
//obsuga wyjtku 2

}
catch ( TypWyj tkuN i den tyfi katorWyjtkuN)
{
//obsuga wyjtku n

Po try nastpuje blok instrukcji mogcych spowodowa wyjtek. Jeeli


podczas ich wykonywania wyjtek zostanie wygenerowany, wykony
wanie zostanie przerwane, a sterowanie przekazane do bloku instrukcji
catc h . Tu z kolei nastpi sprawdzenie, czy ktry z blokw catch od
powiada wygenerowanemu wyjtkowi . Jeli tak, wykonany zostanie
kod danego boku catc h . Dopuszczalne jest przy tym pominicie iden
tyfikatorw wyjtkw, o ile nie bd uywane w blokach catc h .
WICZENIE

Wykorzystanie bloku try... catch

Zastosuj instrukcje try.catch do przechwycenia \'V)'jtku generowanego


przez system w wiczeniu 6 .2 . Wywietl wasny komunikat o bdzie .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Tabl i ca tab = new Tabl i ca ( ) :
try
{
i n t v a l ue = tab . getEl emen t ( 20 ) :

1 44

C#

w i cz e n i a

Con s o l e . W r l tel 1 n e ( " El ement n r 20 ma wa rto : " + v a l ue ) :


}
c a tch ( I n dexOutOfRange Except 1 on )
{
Con s o l e . W r l tel l n e ( " N 1 e ma e l ementu o n umerze 20 ! " ) ;
}
}
}
publ 1 c cl a s s Tabl 1 ca
{
1 n t [ J tab :
publ 1 c Tabl 1 c a ( )
{
tab = new 1 n t [ 5J ;
}
publ 1 c 1 nt getEl ement ( 1 nt 1 ndex )
{
return tab [ 1 ndexJ :
}
}

Klasa Tabl i ca pozostaa w wersji z wiczenia 6 . 2 , a zatem nie zawiera


adnych instrukcji weryfikujcych poprawno danych . W klasie
P rogram zosta natomiast uyty blok try ... catc h , w ktrym znalazy si
instrukcje, z ktrych jedna pobiera warto elementu tablicy o nu
merze 20, a druga wywietla pobran warto na ekranie . Poniewa
tablica zawarta wewntrz obiektu tab ma tylko 5 elementw i nie ist
nieje element o numerze 20, powstanie wyjtek. Wyjtek bdzie prze
chwycony w bloku catc h . Dziaanie zatem przebiegnie tak : wykony
wanie instrukcji
1 n t va l ue = tab . getE l emen t ( 20 ) ;

zostanie przerwane z powodu wystpienia bdu i sterowanie bdzie


przekazane do bloku catc h . Tym samym instrukcja :
Con sol e . W rl tell n e ( " E l ement n r 20 ma wa rto : " + v a l ue ) ;

zostanie pominita, a na ekranie pojawi si napis N i e ma el ementu o nu


merze 20. Wida wyranie, e wyjtek faktycznie zosta przechwycony
i prawidowo obsuony.

Naley zwrci uwag, e kod z wiczenia 6 . 5 nieco odbiega od przed


stawionego wczeniej schematu, cho oczywicie, zgodnie z przed
stawionym wyej opisem, jest jak najbardziej poprawny. Ot instrukcja
catch w tym przykadzie ma posta :

Rozdzi a 6 .

Wyj q t k i i o b s u g a b d w

1 45

catch ( TypWyjtku )

zamiast:
catch ( TypWyjtku i ndentyfi katorWyj tku )

Czym jest indentyfika to rWyj tku? Wyjanienie trzeba zacz od tego,


e wyjtki s obiektami. W momencie wygenerowania bdu tworzony
jest rwnie odpowiadajcy mu obiekt, zatem identyfika torWyj tku to
zmienna referencyjna wskazujca na obiekt wyjtku. Do czego moe si
ona przyda? Przykadowo do wywietlania wygenerowanej przez
system informacji o bdzie .
Informacj tak mona otrzyma na dwa rne sposoby. Pierwszy
z nich to uycie metody ToStri ng ( ) , zapewniajcy najpeniejszy komu
nikat. Drugi to skorzystanie z waciwoci Message. A zatem blok catch
mgby wyglda nastpujco :
catch ( TypWyjtku i ndentyfi katorWyj tku )
{
Con s o l e . W ri teL i n e C " Komun i k a t 1 : " + inden tyfikatorWyj tku . ToStri n g ( ) ) ;
Con s o l e . W r i tell n e ( " Komun i k a t 2 : " + inden tyfikatorWyj tku . Me s s a ge ) ;
}

Ta metoda zostanie uyta w kolejnym wiczeniu.


WICZENIE

Wykorzystanie obiektu wyjqtku

Zmodyfikuj kod z wiczenia 6 . 5 w taki sposb, aby po wystpienia


wyjtku na ekranie pojawiay si rwnie systemowe komunikaty
o bdzie .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Tabl i ca tab = new Tabl i ca ( ) :
try
{
i n t v a l ue = tab . getEl emen t ( 20 ) :
Con s o l e . W r i tel i n e ( " El ement n r 20 ma wa rto : " + v a l ue ) :
}
c a tch ( I n dexOutOfRange Except i on e )
{
Con s o l e . W r i tel i n e ( " N i e ma e l ementu o n umerze 20 1 " ) :

C#

1 46

w i cz e n i a

Con so l e . W r l tel 1 n e ( " Systemowy komun 1 k at o bdz 1 e to : " ) :


Con s o l e . W r 1 teL 1 n e ( e . ToStr1 n g ( ) ) ;
Con so l e . W r l tel l n e ( "Wa rto w a c 1 wo c 1 ' Me s s age ' to : " ) ;
Con s o l e . W r 1 te l 1 n e ( e . Me s s a ge ) :
}
}
}
publ 1 c cl a s s Tabl 1 ca
{

/IW tym miejscu kod klasy Tablica z wiczenia 6.5.

Identyfikator wyjtku w tym przykadzie to nazwa e (to czsto sto


sowane okrelenie) . W celu wykonania wiczenia wystarczyo doda
w bloku catch wiersze powodujce wywietlanie wartoci (cigu zna
kw) zwrconej przez wywoanie e . ToStri ng ( ) 1 oraz tre zawart we
polu Message obiektu wskazywanego przez e. Po kompilacji i urucho
mieniu programu zobaczymy widok przedstawiony na rysunku 6 . 2 .

Rysunek 6. 2. Systemowe komunikaty zwizane z przekroczeniem

dopuszczalnego indeksu tablicy

Sprbujemy teraz wychwyci dosy czsto wystpujcy bd; jest to


dzielenie przez zero. Gdy nie kontrolujemy stanu zmiennych, taka sy
tuacja moe doprowadzi do powanej awarii aplikacj i. Sprawdmy
najpierw jednak, czy kompilator pozwoli wykona jawne dzielenie
przez zero .

1 Prawidowym zapisem byby te Con s o l e . Wrl tel 1 n e ( e ) : , gdy w takim


przypadku zostaaby wykonana niejawna konwersja do typu str1 n g
polegajca wanie na wykonaniu metody ToSt r1 ng. To jednak temat
wykraczajcy poza ramy tego rozdziau.

Rozdzi a 6 .

WICZENIE

Wyj q t k i i o b s u g a b d w

1 47

Prba dzielenia przez zero

Napisz program, w ktrym wystpuje jawne dzielenie przez zero .


Sprbuj wykona kompilacj kodu.
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i nt X = 2 ;
i nt y = x I O ;
Con sol e . Wr i teli n e ( " x = " + x ) ;
Con sol e . Wr i teli n e ( "y = " + y ) ;
}
}

Szybko przekonamy si, e kompilacja kodu z powyszego wicze


nia si nie uda. Kompilator wykrywa, e chcemy dzieli przez zero i,
jako e jest to operacja niedozwolona, wywietla komunikat o bdzie .
Jest to widoczne na rysunku 6 . 3 .
ii C:\Windows\system32\cmd.exe

Rysunek 6. 3. Przy prbie jawnego dzielenia przez zero kompilator

generuje blqd

Niestety, mdro kompilatora koi1czy si w sytuacji, kiedy najpierw


zero przypiszemy jakiej zmiennej i dopiero tej zmiennej uyjemy
jako dzielnika. W takim przypadku kompilacja uda si bez problemw,
natomiast program nie bdzie dziaa . Mona si zabezpieczy przed
tak sytuacj, stosujc odpowiedni blok try.catc h .

C#

1 48

WICZENIE

w i cz e n i a

Przechwytywanie wyjtku DivideByZeroException

Napisz program, w ktrym wystpuje ukryte dzielenie przez zero.


Przechwy wygenerowany przez rodowisko uruchomieniowe wyjtek
i wywietl odpowiedni komunikat na ekranie.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
i nt x
O:
i nt y
6:
try
{
i nt z
y I x;
Con so l e . W r i tel i ne ( " x
" + x) :
Con so l e . W r i tel i ne ( "y
" + y) :
Con so l e . W r i tel i ne ( " z
" + z) :
}
c a tch ( D i vi deByZeroExcepti on )
{
Con so l e . W r i tel i n e ( " B d l Dzi e l en i e przez O . " ) :
}
}
}
=

W bloku t ry zmiennej z zosta przypisany wynik dzielenia zmien


nych y i x. Poniewa w x zostaa zapisana warto zero, dzielenie nie
moe si uda . Powstanie zatem wyjtek typu D i v i deByZero Except i on .
Jest on przechwytywany w bloku catc h . Dlatego po uruchomieniu
powyszego kodu na ekranie pojawi si komunikat o treci : Bd !
Dzi el en i e przez O .

H iera rch ia wyjtkw


Wyjtki w C# tworz struktur hierarchiczn, na czele ktrej znaj
duje si klasa Except i on. Z klasy tej wyprowadzone s kolejne klasy
potomne obsugujce rne typy bdw. Przykadowo dla znanego ju

Rozdzi a 6 .

Wyj q t k i i o b s u g a b d w

1 49

wyjtku o nazwie I ndexOutOfRa ngeExcepti on hierarchia wyglda tak,


jak na rysunku 6 .4 .
Rysunek 6.4.

Hierarchia klas dla wyjtku


IndexOutOfRangeException

Exception

L system Exception

LI

nd exOutOfRangeException

Skoro wyjtki s struktur hierarchiczn, nie jest obojtne, w jakiej


kolejnoci bd przechwytywane . W jednym bloku try ... catch mona
przecie obsuy wiele rnych bdw. Jaka obowizuje kolejno?
Zasada jest prosta - najpierw naley przechwytywa wyjtki bardziej
szczegowe, a dopiero pniej bardziej oglne .
W przykadzie widocznym na rysunku 6 . 5 I ndexOutOfRa ngeExcepti on
jest wyjtkiem najbardziej szczegowym, SystemExcepti on oglniejszym,
a Excepti on najbardziej oglnym. Aby zobaczy, jakie s tego konse
kwencje w praktyce, wykonajmy odpowiednie wiczenie .
WICZENIE

Nieprawidowa kolejno wyjqtkw

Zmodyfikuj kod z wiczenia 6.5 w taki sposb, aby najpierw przechwy


tywany by wyjtek oglny Excepti on, a nastpnie wyjtek I ndexOutOf
4-RangeExcepti on. Sprbuj wykona kompilacj otrzymanego kodu.
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Tabl i ca tab = new Tabl i ca ( ) ;
try
{
i n t v a l ue
tab . getEl emen t ( 20 ) ;
Con s o l e . W r i tel i n e ( " El ement n r 20 ma wa rto : " + v a l ue ) ;
}
c a tch ( System Excepti on )
{
Con so l e . W r i tel i n e ( "Wyj tek SystemExcept i on " ) ;
}
c a tch ( I n dexOutOfRange Except i on )
=

C#

1 50
{

w i cz e n i a

Con so l e . W r l tel 1 n e ( "Wyj tek I ndex0ut0fRange Except 1 on " ) :

}
}
}
publ 1 c cl a s s Tabl 1 ca
{

I/Tutaj tre klasy Tablica z wiczenia 6. 5.

Kompilacja si nie uda. Na ekranie zobaczymy komunikat pokazany


na rysunku 6 . 5 . Nie naley si dziwi : skoro najpierw przechwycilimy
wyjtek oglny SystemExcepti on, kod wystpujcy w bloku catch ( I ndex
"+OutOfRangeExcepti on ) nigdy nie zostanie osignity, kompilator zatem
protestuje . Taki bd atwo popeni, jeli nie pamita si o hierarchii
wyjtkw.
li!

C:\Windows\system32\cmd.exe

Rysunek 6. 5. Prba kompilacji kodu

bldn hierarchi wyjtkw

Aby poprawi kod wiczenia 6 . 9 tak, eby mona byo wykona


kompilacj, a program dziaa poprawnie, naley zamieni miejscami
bloki catch ; wtedy najpierw bdzie przechwytywany wyjtek IndexOut
"+OfRangeExcept i on (bardziej szczegowy) , a dopiero za nim wyjtek
SystemExcept i on (bardziej oglny) .
WICZENIE

Uwzgldnienie hierarchii wyjqtkw

Popraw kod klasy Prog ram z poprzedniego wiczenia tak, aby wyjtki
byy przechwytywane w odpowiedniej kolejnoci.
u s 1 n g Sy stem :
publ 1 c cl a s s Program
{
publ 1 c stat1 c vo1 d M a 1 n ( )

Rozdzi a 6 .
{

Wyj q t k i i o b s u g a b d w

1 51

Tabl i ca tab = new Tabl i ca ( ) :


try
{
i n t v a l ue = tab . getEl emen t ( 20 ) :
Con s o l e . W r i tel i n e ( " El ement n r 20 ma wa rto : " + v a l ue ) :
}
c a tch ( I n dexOutOfRange Except i on )
{
Con so l e . W r i tel i n e ( "Wyj tek I ndexOutOfRange Except i on " ) :
}
c a tch ( System Excepti on ) {
Con so l e . W r i tel i n e ( "Wyj tek SystemExcept i on " ) :
}

}
}

Wasne wyjqtki
Stosowanie wyjtkw nie ogranicza si tylko do przechwytywania
tych, ktre s generowane przez system. Mona je rwnie zgasza
samodzielnie . Powrmy zatem do wiczenia 6 . 5 . Konstrukcja klasy
Tabl i ca mogaby by zupenie inna . Dobrze byoby sprawdza, czy
parametr przekazywany metodzie getEl ement nie przekracza dopusz
czalnych wartoci, a jeli tak, samodzielnie wygenerowa wyjtek.
Jest to moliwe ; suy do tego instrukcja th row w postaci :
th row ob i ekt_wyjtku :

Jeli zatem chcemy wygenerowa (uywa si rwnie terminw


zgosi" lub - argonowo - wyrzuci") nowy wyjtek I ndexOutOf
"+RangeExcept i on, naley zastosowa konstrukcj :
th row new I n dexOutOfRange Except i on ( ) :

WICZENIE

Zgoszenie wyjtku

Zmodyfikuj kod wiczenia 6 . 5 w taki sposb, aby metoda getEl ement


sprawdzaa, czy nie nastpuje przekroczenie zakresu tablicy, i w takiej
sytuacji generowaa wyjtek.

1 52

C#

w i cz e n i a

u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Tabl i ca tab = new Tabl i ca ( ) :
try
{
i n t v a l ue = tab . getEl emen t ( 20 ) ;
Con s o l e . W r i tel i n e ( " El ement n r 20 ma wa rto : " + v a l ue ) ;
}
c a tch ( I n dexOutOfRange Except i on )
{
Con s o l e . W r i tel i n e ( " N i e ma e l ementu o n umerze 20 1 " ) ;
}
}
}
publ i c cl a s s Tabl i ca
{
i n t [ ] tab ;
publ i c Tabl i c a ( )
{
tab = new i n t [ 5J ;
}
publ i c i nt getEl ement ( i nt i ndex )
{
i f ( i ndex < O 1 1 i ndex > tab . Length
1)
{
th row new I n dexOutOfRan ge Excepti on ( ) ;
}
el se
{
return ta b [ i ndexJ ;
}
}
}
-

Do sprawdzenia, czy zosta przekroczony indeks tablicy, wykorzy


stano zwyk instrukcj warunkow i f. Jeli przekroczenie nastpio,
powstaje nowy obiekt typu IndexOutOfRangeExcepti on, ktry jest zgaszany
za pomoc instrukcji th row. Dziki temu mona samodzielnie sterowa
tym, kiedy i jaki wyjtek zostanie zgoszony.

Rozdzi a 6 .

Wyj q t k i i o b s u g a b d w

1 53

Co jednak zrobi w sytuacji, gdy chcemy utworzy wasny wyjtek,


np . o nazwie N i eMaTa k i egoE l ementu, i tene wyj tek przechwytywa
w bloku instrukcji catch? To aden problem - trzeba po prostu
utworzy now klas, pochodn klasy Except i on (lub jednej z klas po
chodnych od Excepti on), i nazwa j N i eMaTa k i egoE l ement u . W naj
prostszym przypadku mogaby ona wyglda nastpujco :
publ i c cl a s s N i eMaTa k i egoEl ementu : Except i on
{
}

To wszystko. Od tej chwili Ni eMaTa ki egoEl ementu bdzie penoprawnym


wyjtkiem, ktry moemy wygenerowa z zastosowaniem instrukcji
th row, czyli piszc :
th row new N i eMaTa k i egoEl ementu ( ) ;

WICZENIE

Wykorzystanie wasnego wyjtku

Zdefiniuj klas wyjtku o nazwie Ni eMaTa k i ego E l ementu i zmodyfikuj


kod wiczenia 6 . 1 1 tak, aby j wykorzystywa.
u s i n g Sy stem ;
publ i c cl a s s N i eMaTa k i egoEl ementu
{
}

Except i on

publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Tabl i ca tab = new Tabl i ca ( ) :
try
{
i n t v a l ue = tab . getEl emen t ( 20 ) ;
Con s o l e . W r i tel i n e ( " El ement n r 20 ma wa rto : " + v a l ue ) :
}
c a tch ( N i eMaTa k i egoEl ementu )
{
Con s o l e . W r i tel i n e ( " N i e ma e l ementu o n umerze 20 ! " ) ;
}
}
}
publ i c cl a s s Tabl i ca
{

C#

1 54

w i cz e n i a

i n t [ ] tab ;
publ i c Tabl i c a ( )
{
tab = new i n t [ 5J :
}
publ i c i nt getEl ement ( i nt i ndex )
{
i f ( i ndex < O 1 1 i ndex > tab . Length
{
th row new Ni eMaTa k i egoE l ementu ( ) ;
}
el se
{
return ta b [ i ndexJ ;
}
}

1)

Struktura kodu pozostaa tu taka sama jak w wiczeniu 6. 1 1 . Rnice s


takie, e na pocztku pojawia si definicja klasy Ni eMaTa k i ego El ementu
(pochodnej od Except i on) i obiekty tej klasy s uywane przy genero
waniu oraz przechwytywaniu wyjtkw.

7
I nterfejsy
Prosty i nte rfejs
Interfejsy s konstrukcjami takimi jak klasy, z t rnic, e zawie
raj jedynie deklaracje metod, a nie ich definicje. Inaczej mwic, s
klasami abstrakcyjnymi . Kada zwyka klasa moe implementowa
dany interfejs, co oznacza, e musi zawiera definicje wszystkich metod
umieszczonych w tym interfejsie .
Zamy, e mamy zdefiniowan klas Poi nt w najprostszej postaci,
zawierajc jedynie dwa pola typu i nt : jedno dla wsprzdnej x,
drugie dla wsprzdnej y :
publ i c cl a s s Poi nt
{
pub l i c i n t x ;
publ i c i nt y ;
}

Pierwszym zadaniem bdzie napisanie interfejsu o nazwie I S how,


w ktrym znajdzie si tylko jedna metoda o nazwie Show.

C#

1 56

WICZENIE

w i cz e n i a

Pierwszy interfejs

Napisz interfejs o nazwie !Show, w ktrym zadeklarowana bdzie metoda


o nazwie Show.
publ i c i nterface ! Sh ow
{
voi d Show ( ) ;
}

Jak wida, zadanie to nie byo skomplikowane . Interfejs przypomina


definicj klasy, ale zamiast sowa kluczowego cl a s s uywa si sowa
kluczowego i nterface.

Przekonajmy si teraz, e faktycznie w interfejsie nie wolno zdefi


niowa ciaa (treci) metody. W tym celu wystarczy wykona wi
czenie 7 . 2 .
WICZENIE

Umieszczenie w interfejsie treci metody

Dodaj do metody Show z interfejsu z wiczenia 7 .1 jej implementacj.


Sprbuj wykona kompilacj kodu.
publ i c i nterface ! Sh ow
{
voi d Show ( )
{
i nt a ;
}
}

Prba kompilacji powyszego fragmentu kodu spowoduje wygenerowa


nie bdu kompilacji CS0531 z komunikatem widocznym na rysunku
7 . 1 . Tak wic metody interfejsu z pewnoci nie mog zawiera imple
mentacji.

Powrmy do klasy Poi nt oraz interfejsu I Show i sprawdmy, jak wy


korzysta je w praktyce . Przede wszystkim trzeba si dowiedzie, jak
spowodowa, aby klasa implementowaa interfejs . Okazuje si, e

Rozd z i a 7 .

I n te rfejsy

1 57

Ciii C:\Wi ndows\system32\cmd.exe

Rysunek 7. 1. Prba kompilacji interfejsu zawierajcego implementacj

metody Show

naley zastosowa konstrukcj analogiczn do dziedziczenia, zatem


schemat definicji klasy implementujcej interfejs wyglda bdzie
nastpujco :
publ i c cl a s s nazwa k l asy
{

nazwa in terfejsu

//definicja klasy

WICZENIE

Implementacja interfejsu przez klas

Napisz kod, w ktrym klasa Poi nt implementuje interfejs I Show.


u s i n g Sy stem :
publ i c i nterface ! Sh ow
{
voi d Show ( ) :
}
publ i c cl a s s Poi nt
! Show
{
pub l i c i n t x :
publ i c i nt y :
publ i c vo i d Show ( )
{
Con sol e . Wr i tel i n e ( " Dane dotyczce pun k tu : " ) :
Con sol e . Wr i tel i n e ( "wsp rzdn a x = { O } " . x ) :
Con sol e . Wr i tel i n e ( "wsp rzdn a y = { O } " , y ) :
}
}

Jak wida, w tym przypadku implementacja interfejsu polega na


zdeklarowaniu oraz zdefiniowaniu w klasie Poi nt metody Show. Tre
tej metody moe by dowolna. W prezentowanym przykadzie metoda
Show powoduje wywietlenie na ekranie biecych wartoci x oraz y .

C#

1 58

w i cz e n i a

Przedstawiony kod mona zapisa w jednym pliku lub te w dwch


osobnych. To drugie rozwizanie wydaje si bardziej uniwersalne ,
dlatego te tre interfejsu I S how najlepiej zapisa w pliku !Show .es,
a tre klasy Poi nt - w pliku Point .es.

Oczywicie, prba kompilacji kodu z wiczenia 7 . 3 (niezalenie od


tego, czy zosta zapisany w jednym pliku, czy te w dwch) nie po
wiedzie si, a na ekranie zobaczymy komunikat widoczny na rysun
ku 7 .2 1 . Powd jest chyba jasny - nie zostaa zdefiniowana metoda
Ma i n, od ktrej mogoby zacz si wykonywanie programu. Informacja
ta zawarta jest w komunikacie zgoszonym przez kompilator. Napisz
my zatem program, ktry skorzysta z klasy Po i nt.
Iii C:\Win dow\system32\ c m d.exe

Rysunek 7. 2. Niezdefiniowanie metody Main powoduje bd kompilacji

WICZENIE

Wykorzystanie klasy Point i interfejsu IShow

Napisz program, w ktrym wykorzystasz metod Show klasy Po i nt.


u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Po i n t punkt = new Po i nt ( ) :
punkt . x
100 :
punkt . y
200 :
punkt . Show( ) :
=

1 Chyba e zastosujemy opcj /t kompilatora i skompilujemy kod np. jako


bibliotek.

Rozd z i a 7 .

1 59

I n te rfejsy

Powstaa klasa P rogram zawierajc publiczn i statyczn metod Ma i n,


od ktrej zaczynie si wykonywanie programu. Ten schemat jest dobrze
znany, gdy by ju wykorzystywany wiele razy. W metodzie Ma i n
deklarujemy zmienn referencyjn punkt i przypisujemy jej nowo
utworzony obiekt klasy Poi nt. Nastpnie inicjalizujemy pola x i y tego
obiektu odpowiednio wartociami 100 i 2 0 0 . Na zakoi1czenie wywou
jemy metod Show. Jeeli klas P rog ram zapiszemy w pliku Program .es,
klas Poi nt
w pliku Point .es, a interfejs ! Show
w pliku !Show.es,
do kompilacji programu niezbdne bdzie wykonanie komendy:
-

c s c Program . es Poi nt . e s I Show . c s

Powstanie wtedy plik Program .exe, a wynikiem jego dziaania, co nie


powinno by adnym zaskoczeniem, bdzie pojawienie si na ekranie
tekstu zaprezentowanego na rysunku 7 . 3 .

Rysunek 7.3. Wynik dziaania kodu z wiczenia

7.4

I nterfejsy w kl asach potom nych


Dotychczas implementowalimy interfejs jedynie w klasie bazowej ,
tzn. takiej , ktra nie dziedziczy z innej klasy2 . Czy zatem jest moliwa
implementacja interfejsu w klasie potomnej? Jak bdzie wygldaa
taka konstrukcja? Na szczcie, jest to bardzo proste . Wystarczy na
zw interfejsu oddzieli przecinkiem od nazwy klasy bazowej :

Dziedziczy jednak domylnie z klasy Obj ect.

C # w i cz e n i a

1 60
c l a s s k l asa_potomna
{

k l asa bazowa . inter fejs

//definicja klasy

Zbudujmy zatem jedn klas bazow o nazwie Shape i wyprowadmy


z niej dwie klasy potomne Recta ngl e i T r i a n g l e . Klasa S h a pe bdzie
klas oglna suc do opisu figur geometrycznych, Recta ngl e klas
opisujc prostokty, Tri angl e klas opisujc trjkty. Odwieymy
przy okazji wiadomoci o dziedziczeniu.
WICZENIE

Budowa klas reprezentujqcych figury geometryczne

Zbuduj klas Shape suc do przechowywania informacj i na temat


figur geometrycznych i wyprowad z niej dwie klasy potomne :
Rect a n g l e dla prostoktw i Tri angl e dla trjktw.
publ i c cl a s s Sh ape
{
publ i c i nt col or :
}
publ i c cl a s s Poi nt
{
pub l i c i n t x :
publ i c i nt y ;
}
publ i c cl a s s
{
pub l i c i n t
publ i c i nt
publ i c i nt
publ i c i nt
}

Shape

Rectan g l e

Shape

x:
y:
wi dth ;
hei ght ;

publ i c cl a s s Tri angl e


{
publ i c Po i nt a :
publ i c Po i nt b ;
publ i c Po i nt c :
}

S h a pe

Klasa Shape zawiera tylko jedn skadow oznaczajc kolor figury.


W klasie Rectangl e zdefiniowane zostay pola x i y wyznaczajce po
oenie grnego lewego wierzchoka oraz pola wi dth i hei ght okrelajce

Rozd z i a 7 .

I n te rfejsy

1 61

odpowiednio jego dugo i wysoko (warto zauway, e zamiast


pl x i y mona by te uy pola typu Poi nt) . Klasa Tri a n g l e zawiera
z kolei trzy pola, wszystkie typu Poi nt, ktre wyznaczaj pooenie
opisywanego trjkta3 .

Sprbujmy teraz zaimplementowa w klasach Recta ngl e i Tri a n g l e


znany ju interfejs ! Show. Zgodnie z wczeniejszymi wyjanieniami
w kadej z tych klasy trzeba bdzie zawrze odpowiedni metod Show.
Metoda bdzie musiaa uwzgldnia specyfik danej figury. Co innego
bdzie wywietlane w przypadku prostokta, a co innego w przypadku
trjkta.
WICZENIE

Interfejs IShow dla klas Rectangle i Triangle

Zaimplementuj interfejs I Show dla klas Recta ngl e i Tri angl e zdefinio
wanych w wiczeniu 7 . 5 .
u s i n g Sy stem :
publ i c i nterface ! Sh ow
{
voi d Show ( ) :
}
publ i c cl a s s Sh ape
{
publ i c i nt col or :
}
publ i c cl a s s Poi nt : Sh ape
{
pub l i c i n t x :
publ i c i nt y ;
}
publ i c cl a s s Rectan g l e
{
pub l i c i n t x :

Shape , ! Show

W praktyce do klasy Tri a n g l e dobrze byoby dopisa konstruktor tworzcy


obiekty typu Poi n t wskazujce wsprzdne wierzchokw. Nie to jest jednak
tematem tego rozdziau.

C#

1 62

w i cz e n i a

publ i c i nt y ;
publ i c i nt wi dth ;
publ i c i nt hei ght :
publ i c vo i d Show ( )
{
Con sol e . Wr i teli n e ( " Pa rametry prostok ta : " ) ;
Con sol e . Wr i tel i n e ( "wsp rzdn a x = { O } " . x ) :
Con sol e . Wr i tel i n e ( "wsp rzdn a y = { O } " . y ) ;
Con sol e . Wr i tel i n e ( " d ugo = { O }" . wi dth ) ;
Con sol e . Wr i teli n e ( " s zerok o = { O } \ n " . hei gh t ) ;
}
}
publ i c cl a s s Tri angl e
S h a pe . I S how
{
publ i c Po i nt a ;
publ i c Po i nt b ;
publ i c Po i nt c ;
publ i c vo i d Show ( )
{
Con sol e . Wr i teli n e ( " Pa rametry trj k ta : " ) ;
Con sol e . Wr i tell n e C "punkt a = ( { O } . { l } ) " , a . x . a . y ) ;
Con sol e . Wr i teli n e ( "punkt b = ( { 0 } . { l } ) " , b . x . b . y ) ;
Con sol e . Wr i teli n e ( "punkt c = ( { O } . { l } ) \ n " . c . x . c . y ) ;
}
}

W klasach Rectangl e oraz Tri angl e pojawia si metoda Show. W pierw


szym przypadku wywietla ona wsprzdne lewego grnego rogu
oraz szeroko i wysoko, a w drugim - wsprzdne wszystkich
wierzchokw. Obie metody maj typ zwracany voi d i nie przyjmuj
argumentw, zatem s zgodne z deklaracj zawart w interfejsie !Show,
ktry jest implementowany w obu wymienionych klasach.
WICZENIE

Uycie klas Rectangle i Triangle

Napisz program, w ktrym bd uywane obiekty typw Recta ngl e


i Tri angl e .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Rectan g l e prostokat = n ew Rectangl e ( ) ;

Rozd z i a 7 .

I n te rfejsy

1 63

prostok at . x = 1 0 0 :
prostok at . y = 2 0 0 :
prostok a t . wi dth = 50 ;
prostok a t . h e i ght = 8 0 :
Tri angl e troj k a t = new Tri a n g l e ( ) :
troj k a t . a = new Poi n t ( ) :
troj k a t . b = new Poi n t ( ) :
troj k a t . c = new Poi n t ( ) ;
troj k a t . a . x = 10 :
troj k a t . a . y = 20 :
troj k a t . b . x = 15 :
troj k a t . b . y = 18 :
troj k a t . c . x = 42 :
troj k a t . c . y = 24 :
prostok at . Show ( ) ;
troj k a t . Show( ) :
}
}

W metodzie Ma i n klasy Program tworzymy obiekt typu Rectangl e i przypi


sujemy jego polom przykadowe wartoci. Podobnie postpujemy
z obiektem typu Tri angl e. Poniewa pola w tej klasie s typu P o i nt
(a klasa Tri angl e nie ma odpowiedniego konstruktora) , trzeba dodatko
wo utworzy obiekty klasy Poi nt. Po przypisaniu wszystkich wartoci
wywoujemy odpowiednie metody Show, co powoduje pojawienie si
na ekranie informacji zaprezentowanych na rysunku 7 .4 .
Rysunek 7.4.

Przykad dziaania
metody Show
dla obiektw
rnych klas

Warto tu zwrci uwag, e o ile we wczeniejszych wiczeniach


(7 . 3 , 7 .4) implementowalimy interfejs I Show dla klasy Poi nt, tym ra
zem (wiczenie 7 . 7) wywietlanie parametrw punktu obsugujemy
z poziomu klasy Tri angl e, np . w wierszu :
Con sol e . W ri tel i n e ( "punkt a = ( { O } . { l } ) " , a . x , a . y ) ;

1 64

C#

w i cz e n i a

Jest to pewna niespjno w kodzie, jako e punkt te jest figur


geometryczn i nie ma powodu, aby pozbawia klas Poi nt moliwoci
samodzielnego wywietlania parametrw na ekranie . Warto naprawi to
mae niedopatrzenie i doda metod Show tak, aby dane wywietlane
byy np . w nastpujcej postaci :
(wa rto_x , warto_y )

Da si te zauway, e klasom Recta ngl e i Tri angl e przydayby si


konstruktory, tak aby parametry opisujce prostokty i trjkty prze
kazywane byy ju w trakcie tworzenia danych obiektw. W obecnej
postaci atwo zapomnie o zainicjalizowaniu jednego z pl . Cay kod
jest te duo mniej czytelny.
Wszystkie te poprawki wprowadzimy w kolejnym wiczeniu.
WICZENIE

Dodatkowe konstruktory i interfejsy

Zaimplementuj interfejs ! Show dla klasy Poi nt, dodaj konstruktory dla
klas Poi nt, Rectangl e i Tri angl e .
u s i n g Sy stem ;
i n terface I Show
{
voi d Show ( ) ;
}
publ i c cl a s s Sh ape
{
publ i c i nt col or ;
}
publ i c cl a s s Rectan g l e
Shape , I Show
{
pub l i c i n t x ;
publ i c i nt y ;
publ i c i nt wi dth ;
publ i c i nt hei ght :
publ i c Rectan g l e ( i n t x , i nt y , i nt wi dth . i n t hei ght )
{
th i s . x
x;
th i s . y
y;
th i s . wi dth
wi dth :
th i s . he i ght
h e i ght :
}
=

Rozd z i a 7 .

I n te rfejsy

1 65

publ i c vo i d Show ( )
{
Con sol e . Wr i teli n e ( " Pa rametry prostok ta : " ) ;
Con sol e . Wr i tel i n e ( "wsp rzdn a x = { O } " . x ) :
Con sol e . Wr i tel i n e ( "wsp rzdn a y = { O } " . y ) ;
Con sol e . Wr i tel i n e ( " d ugo = { O }" . wi dth ) :
Con sol e . Wr i teli n e ( " s zerok o = { O } \ n " . hei gh t ) :
}
}
publ i c cl a s s Tri angl e
S h a pe . I S how
{
publ i c Po i nt a :
publ i c Po i nt b ;
publ i c Po i nt c :
publ i c Tri angl e ( Po i nt a . Po i n t b . Po i n t c )
{
th i s . a = a :
th i s . b = b :
th i s . c = c :
}
publ i c vo i d Show ( )
{
Con sol e . Wr i teli n e ( " Pa rametry trj k ta : " ) ;
Con sol e . Wr i te ( "punkt a = " ) ; a . Show( ) ;
Con sol e . Wr i te ( " \ n pun kt b = " ) ; b . Show ( ) ;
Con sol e . Wr i te ( " \ n pun kt c = " ) ; c . Show ( ) ;
Con sol e . Wr i te ( " \ n " ) ;
}
}
publ i c cl a s s Poi nt
Shape . I Show
{
pub l i c i n t x ;
publ i c i nt y ;
publ i c Poi n t ( i nt x . i nt y )
{
th i s . x = x :
th i s . y = y :
}
publ i c vo i d Show ( )
{
Con sol e . Wr i te ( " ( { O } . { l } ) " , x . y ) :
}
}

Klasa Recta ngl e otrzymaa czteroargumentowy konstruktor, w ktrym


przekazywane s wartoci dla wszystkich zawartych w niej pl ( x, y,
wi dth, hei ght) . W jego wntrzu wartoci argumentw przypisywane

C#

1 66

w i cz e n i a

s odpowiednim polom. W klasie Tri angl e pojawi si konstruktor trj


argumento\'\T)T, przyjmujcy argumenty typu Poi nt okrelajce wsp
rzdne wierzchokw trjkta . Najwicej zmian zaszo w klasie Po i nt .
Implementuje ona teraz interfejs !Show, a wic zawiera rwnie metod
Show wywietlajc wartoci wsprzdnych . Dodatkiem jest rwnie
konstruktor przyjmujcy dwie wartoci typu i nt i przypisujcy je
polom x i y.
WICZENIE

Zastosowanie nowych wersji klas

Napisz te klas P rog ram testujc zachowanie klas z wiczenia 7 . 8 .


u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Rectan g l e prostokat = n ew Rectangl e ( l O O . 2 0 0 . 50 . 80 ) :
Tri angl e troj k a t = new Tri ang l e
(
new Poi n t ( lO . 20 ) ,
new Poi n t ( l5 . 18 ) ,
new Poi n t ( 42 . 24 )
);
prostok at . Show ( ) :
troj k a t . Show( ) :

W porwnaniu do wiczenia 7 . 7 kod klasy P rog ram bardzo si upro


ci i jest o wiele czytelniejszy. Obiekty przypisywane zmiennym
prostokat i t rojkat tworzone s za pomoc nowych konstruktorw,
dziki temu nie trzeba dokonywa bezporednich przypisali do pl .
W wywoaniu konstruktora klasy Tri angl e uywany jest te nowo
powstay konstruktor klasy Po i nt.

Rozd z i a 7 .

I n te rfejsy

1 67

Czy to i nterfejs?
Wiemy ju sporo o interfejsach w C#, przydayby si jednak jeszcze
wiadomoci o tym, w jaki sposb stwierdzi , czy dany obiekt imple
mentuje konkretny interfejs. Oczywicie, w najprostszym przypadku
tak wiedz dysponowa bdziemy ju na etapie kompilacji. Zamy,
e operujemy na klasach Recta ngl e i T r i a n g l e utworzonych w wi
czeniu 7 . 8 i klasie P o i nt z wiczenia 7 . 5 uzupenionej konstruktorem
z wiczenia 7 . 8 . Klasy Rectangl e i Tri angl e implementuj interfejs !Show,
natomiast klasa Po i nt
nie.
-

Co si zatem stanie, jeli sprbujemy skompilowa nastpujcy frag


ment kodu:
u s i ng Sys tem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Rectan g l e prostokat = n ew Rectangl e ( l O O . 2 0 0 . 50 . 80 ) :
Tri angl e troj k a t = new Tri ang l e
(
new Poi n t ( lO . 20 ) .
new Poi n t ( l5 . 18 ) .
new Poi n t ( 42 . 24 )
);
Po i n t punkt = new Poi n t ( l50 . 30 0 ) :
prostok at . Show ( ) :
troj k a t . Show( ) :
punkt . Show( ) :

Oczywicie, kompilacja si nie uda, jako e w klasie Po i nt nie ma


metody Show, a na ekranie zobaczymy komunikat o bdzie widoczny
na rysunku 7 . 5 .
W tym przypadku nie byo adnych problemw, nie zawsze jednak
mamy tak klarown sytuacj . Rozpatrzmy nieco bardziej skompli
kowany przykad (czytelnicy nieznajcy poj klas abstrakcyjnych
oraz metod wirtualnych mog pomin dalszy fragment i przej od
razu do rozdziau 8 .) . W tym celu wykonamy pewne modyfikacje utwo
rzonych dotychczas klas Shape, Recta ngl e, Tri angl e i Po i nt.

C#

1 68

w i cz e n i a

!ii C:\Windows\system32\ cmd.exe

Rysunek 7.5. Prba wywalania nieistniejcej metody powoduje blqd kompilacji

W klasie Shape zdefiniujemy wirtualn metod Show. Zmiana ta wy


musi przesonicie (inaczej : nadpisanie , ang . override) metod S h ow
w klasach Rectangl e i Tri angl e, jako e wci bd one implementowa
interfejs !S how. W klasie Poi nt metody Show nie zadeklarujemy.
WICZENIE

Interfejsy i metody wirtualne

Zmodyfikuj kod dotyczcy klas Shape, Rectangl e, Tri angl e i Poi nt w taki
sposb, aby w klasie Shape znalaza si wirtualna metoda Show.
i n terface I Show
{
voi d Show ( ) ;

}
publ i c abstract c l a s s Sh ape
{
publ i c i nt col or ;
publ i c vi rtu a l voi d Show ( )
{
Con sol e . Wr l tel i n e ( " Metoda Show k l a sy bazowej " ) ;

publ i c cl a s s Rectan g l e
{
pub l i c i n t x ;
publ i c i nt y ;

Shape . I Show

Rozd z i a 7 .

I n te rfejsy

publ i c i nt wi dth :
publ i c i nt hei ght :
publ i c Rectan g l e ( i n t x . i nt y , i nt wi dth . i n t hei ght )
{
th i s . x = x :
th i s . y = y ;
th i s . wi dth = wi dth ;
th i s . he i ght = h e i ght ;
}
publ i c overr i de vo i d Show( )
{
Con sol e . Wr i teli n e ( " Pa rametry prostok ta : " ) ;
Con sol e . Wr i tel i n e ( "wsp rzdn a x = { O } " , x ) ;
Con sol e . Wr i tel i n e ( "wsp rzdn a y = { O } " , y ) ;
Con sol e . Wr i tel i n e ( " d ugo = { O }" , wi dth ) :
Con sol e . Wr i teli n e ( " s zerok o = { O } \ n " , hei gh t ) :
}
}
publ i c cl a s s Tri angl e
S h a pe , I S how
{
publ i c Po i nt a :
publ i c Po i nt b :
publ i c Po i nt c :
publ i c Tri angl e ( Po i nt a . Po i n t b , Po i n t c )
{
th i s . a = a :
th i s . b = b :
th i s . c = c :
}
publ i c overr i de vo i d Show( )
{
Con sol e . Wr i teli n e ( " Pa rametry trj k ta : " ) :
Con sol e . Wr i teli n e ( "punkt a = ( { 0 } , { l } ) " , a . x , a . y ) ;
Con sol e . Wr i teli n e ( "punkt b = ( { O } , { l } ) " , b . x , b . y ) ;
Con sol e . Wr i teli n e ( "punkt c = ( { O } , { l } ) \ n " , c . x , c . y ) ;
}
}
publ i c cl a s s Poi nt
Shape
{
pub l i c i n t x :
publ i c i nt y ;
publ i c Poi n t ( i nt x . i nt y )
{
th i s . x = x :
th i s . y = y ;
}
}

1 69

C#

1 70

w i cz e n i a

Klasa Shape staa si klas abstrakcyjn, co oznacza, e nie mona


bdzie tworzy jej instancji (obiektw typu Shape) . Z kolei umiesz
czona w niej metoda Show staa si wirtualna (oznacza to sprawdzanie
typu obiektu w trakcie wykonania programu, tzw. pnie wizanie lub
wizanie czas u wykonania) . W klasach Recta ng l e oraz Tr i ang l e meto
da Show zostaa zadeklarowana z uyciem sowa ove r r i d e . To pozwala
na przesonicie metody Show z klasy bazowej (Shape) . Ostatnia z klas
(Poi nt) nie implementuje interfejsu !Show, zatem nie musi zawiera me
tody Show. Dlatego te zawiera tylko konstruktor (oraz definicje pl) .

Nietrudno si domyli, e po zdefiniowaniu klas, takim jak w wi


czeniu 7 . 1 0, kod przedstawiony na pocztku tego podrozdziau b
dzie w peni poprawny, a wic uda si jego kompilacja oraz wyko
nanie . Szczeglnie za moliwe bdzie wywoanie metody Show dla
obiektu Punkt :
punkt . Show( ) ;

Efekt dziaania takiego kodu jest widoczny na rysunku 7 . 6 . Wida


wyranie, e dla obiektw prostokat i trojkat zostay wywoane me
tody Show klas Rectangl e i Tri angl e, natomiast dla obiektu punkt wy
woana zostaa metoda pochodzca z klasy bazowej (Sh ape) .
Rysunek 7. 6.

Dla obiektu punkt


zostala wywoana
metoda Show
klasy Shape

Problem pojawi si w sytuacji, gdy trzeba bdzie wywoywa wy


cznie metody implementowane ze wzgldu na interfejs, a nie b
dzie wiadomo dokadnie, jakiego typu jest obiekt. Inaczej mwic,
metoda Show ma by wywoana tylko wtedy, kiedy dany obiekt im
plementuje interfejs ! Show. W pozostaych sytuacjach nie powinna

Rozd z i a 7 .

I n te rfejsy

1 71

by wywoywana. W powyszym przypadku teoretycznie wiadomo,


ktre obiekty implementuj ten interfejs - wystarczy zajrze do kodu
rdowego danej klasy . Nie zawsze jednak bdzie mona tak atwo
to sprawdzi .
WICZENIE

Wywoanie metody niezgodne z zaoeniami

Zadeklaruj tablic obiektw typu S h a pe i przypisz jej komrkom


obiekty klas Rectangl e, Tri nangl e i Poi nt . Dla kadego z elementw tabli
cy w ptli fo r wywoaj metod Show.
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Rectan g l e prostokat = n ew Rectangl e ( l O O . 2 0 0 . 50 . 80 ) ;
Tri angl e troj k a t = new Tri ang l e
(
new Poi n t ( lO . 20 ) ,
new Poi n t ( l5 . 18 ) .
new Poi n t ( 42 . 24 )
);
Po i n t punkt = new Poi n t ( l50 . 30 0 ) ;
Shape [ J tab = new S h a p e [3 J ;
ta b [ O J = prostok at ;
ta b [ l J = troj k at ;
t a b [ 2 J = punkt ;
fo r ( i n t i = O ; i < tab . Length ; i ++ )
{
tab [ i J . Show ( ) ;

W kodzie zostay utworzone trzy obiekty typw Recta ngl e, Tri angl e
oraz Poi nt. Powstaa rwnie 3-elementowa tablica typu Shape, w ktrej
kolejnych komrkach zostay zapisane obiekty : p r o s t o k a t , tro j k a t
i punkt. Przypisanie byo moliwe, dlatego e wymienione klasy dziedzi
cz z klasy Shape. Na zakoczenie w ptli fo r dla kadego obiektu
zawartego w tablicy zostaa wywoana metoda Show (ta b [ i ] . Show( ) ) .

1 72

C#

w i cz e n i a

Oczywicie, program zaprezentowany w wiczeniu 7 . 1 1 zadziaa,


cho nie do koilca zgodnie z pierwotnymi zaoeniami. Poniewa nie
sprawdzamy, jaki jest rzeczywisty typ obiektu zawartego w danej
komrce tablicy, wywoamy metod Show rwnie dla komrki numer
trzy (o indeksie 2), a znajdujcy si tam obiekt jest typu Po i nt . Ta
klasa nie dziedziczy po interfejsie ! Show i nie zawiera metody Show .
Dlatego te wywoana bdzie metoda klasy bazowej . Tymczasem
metoda Show miaa by wywoywana jedynie dla obiektw implemen
tujcych interfejs ! Show.
Jak zatem stwierdzi, czy dany obiekt implementuje pewien interfej s,
czy te nie? Do dyspozycji s a trzy metody :
D

rzutowanie typu,

konstrukcja ze sowem i s ,

konstrukcja ze sowem a s .

Rzutowa nie
Pierwsza metoda to dokonanie rzutowania obiektu na typ interfejsu .
Jeli w tablicy znajduje si obiekt typu Shape, mona wykona prb
rzutowania go na typ !S how, czyli uy konstrukcji w postaci:
( I Show ) tabl i ca [ i ndek s J :

Jeli obiekt znajdujcy si w tablicy implementuje interfejs ! Show,


rzutowanie zakoilczy si sukcesem. W przeciwnym przypadku wygene
rowany zostanie wyjtek I n v a l i d C a s t Except i o n . Wyjtek ten mona
przechwyci i odpowiednio zareagowa . Zastosujmy zatem t metod
i poprawmy kod z wiczenia 7 . 1 1 tak, aby dziaa zgodnie z pierwot
nymi zaoeniami.
WICZENIE

Rzutowanie na typ interfejsu

Zn1ief1 kod z wiczenia 7 . 1 1 w taki sposb, aby n1etoda Show bya wy


woywana tylko w stosunku do obiektw implementujcych interfejs
I Show. Zastosuj metod rzutowania i przechwytywania wyjtkw.
u s i n g Sy stem :
publ i c cl a s s Program
{

Rozd z i a 7 .

I n te rfejsy

1 73

publ i c stati c voi d M a i n ( )


{
Rectan g l e prostokat = n ew Rectangl e ( l O O . 2 0 0 . 50 . 80 ) :
Tri angl e troj k a t = new Tri ang l e
(
new Poi n t ( lO . 20 ) ,
new Poi n t ( l5 . 18 ) ,
new Poi n t ( 42 , 24 )
):
Po i n t punkt = new Poi n t ( l50 . 30 0 ) :
Shape [ J tab = new S h a p e [3 J :
ta b [ O J = prostok at :
ta b [ l ] = troj k at :
t a b [ 2 J = punkt :
fo r ( i n t i = O : i < tab . Length : i ++ )
{
try
{
( ( I Show ) ta b [ i J ) . Show ( ) :
}
catch ( I n va l i dC a stExcept i on )
{
Con sol e . Wr i teli n e ( " t a b [ { O } J : b r a k wywo an i a Show . " . i ) :
}
}
}
}

Zmodyfikowana zostaa ptla fo r przetwarzajca elementy tablicy


tab. Kady element poddawany jest rzutowaniu do typu interfejsowego
! Show. To oznacza, e jeli dany obiekt implementuje interfejs ! Show,
konwersja zostanie wykonana i bdzie moga by wywoana metoda
Show. W przeciwnym przypadku (obiekt nie implementuje interfejsu
! Show) bdzie wygenerowany wyjtek I nval i dCastExcept i on przechwy
tywany w bloku catc h . A zatem metoda Show zostanie wywoana je
dynie dla obiektw klas Rectangl e i Tri angl e, natomiast dla obiektu
typu Poi nt zostanie wywietlony osobny komunikat informacyjny .
Wida to wyranie na rysunku 7 . 7 .

Kod bloku try z wiczenia 7 . 1 2 inona te zapisa w nieco czytelniej


szej, cho bardziej rozwlekej postaci :
t ry
{
I Show tempObj = ( I Show ) ta b [ i J :
tempObj . Show ( ) :
}

1 74

C#

w i cz e n i a

Rysunek 7. 7.

Metoda Show
zostala wywalana
jedynie dla obiektw
Rectangle i Triangle

Moliwe byoby rwnie umieszczenie instrukcji tempObj . Show( ) poza


blokiem try... catc h . Ptla fo r wygldaaby wtedy nastpujco :
for ( i n t i = O ; i < tab . Length ; i ++ )
{
! Show tempObj ;
t ry
{
tempObj = ( I Show ) tab [ i J ;
}
catch ( I n va l i dCas tExcepti on )
{
Con sol e . Wr i teli n e ( " t a b [ { O } J : brak wywo an i a Show . " , i ) ;
conti n u e :
}
tempObj . Show ( ) ;
}

Sowo kl uczowe as
Sposb drugi to uycie operatora as . Mona go wykorzysta w sposb
nastpujcy:
obi ekt a s i n terfej s ;

Oto przykad :
I Show obj = tabl i ca [ i ndek s J a s I S how ;

Jeli obiekt nie implementuje danego interfejsu, konstrukcja a s zwra


ca warto nul l . W powyszym przypadku, jeli w tablicy tabl i ca na
pozycji i ndeks nie ma obiektu implementujcego interfejs I Show, zmien
nej obj zostanie przypisana warto nul l .

Rozd z i a 7 .

I n te rfejsy

1 75

Konstrukcja ze sowem kluczowym a s to rwnie rodzaj rzutowania,


realizowany tylko nieco inaczej ni w przykadzie z wiczenia 7 . 1 2 .
WICZENIE

Uycie operatora as

Zmieli kod z wiczenia 7 . 1 1 w taki sposb , aby metoda Show bya


wywoywana tylko w stosunku do obiektw implementujcych in
terfejs I Show. Wykorzystaj konstrukcj ze sowem kluczowym a s .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{

l/Tutaj pocztek kodu z wiczenia 7. 1 1.

fo r ( i n t i = O : i < tab . Length : i ++ )


{
! Show tempObj = tab [ i J a s ! Show :
i f( tempObj ! = n u l l )
{
tempObj . Show ( ) ;
}
el se
{
Con sol e . Wr i teli n e ( " t a b [ { O } J : b r a k wywo an i a Show . " , i ) :
}
}
}
}

Sowo kl uczowe is
Ostatnim z prezentowanych sposobw na stwierdzenie , czy obiekt
implementuje dany interfej s, jest uycie operatora i s . Najczciej
uywa si go w poczeni u z klasyczn konstrukcj warunkow i f.
Schemat postpowania jest nastpujcy:
i f ( obi ekt i s i n terfej s )
{
//instrukcje do wykonania, gdy obiekt implementuje interfejs

1 76

C#

w i cz e n i a

Wida wic wyranie, e i ten sposb doskonale nadaje si do uycia


w omawianym przypadku. Wykonajmy zatem ostatnie wiczenie w tym
rozdziale .
WICZENIE

Wykorzystanie operatora is

Zmie kod z wiczenia 7 . 1 1 w taki sposb , aby metoda Show bya


wywoywana tylko w stosunku do obiektw implementujcych in
terfejs I Show. Wykorzystaj konstrukcj ze sowem kluczowym i s .
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{

I/Tutaj pocztek kodu z wiczenia 7. 1 1.

fo r ( i n t i
O : i < tab . Length : i ++ )
{
i f( tab [ i J i s ! Show )
{
tab [ i J . Show ( ) :
}
el se
{
Con sol e . Wr i teli n e ( " t a b [ { O } J : b r a k wywo an i a Show . " , i ) :
}
}
=

}
}

III
Prog ra mowa nie w Wi ndows

1 78

C#

w i cz e n i a

8
Pie rwsze o kno
Utworzenie okna
W pierwszych dwch czciach ksiki znalazy si przykady bar
dzo wielu programw konsolowych, zatem najwyszy czas zaj si
tworzeniem aplikacji z graficznym interfejsem uytkownika. Podob
nie jak w czci pierwszej, kod bdziemy pisa rcznie" , nie korzy
stajc z pomocy edytora Visual C # . To pozwoli na dobre poznanie
mechanizmw rzdzcych aplikacjami okienkowymi.
Podstawowy szablon kodu pozostanie taki sam jak w dotychczaso
wych przykadach . Dodatkowo trzeba bdzie poinformowa kom
pilator o tym, e chcemy korzysta z klas pakietu Windows .Forms.
Na pocztku kodu bdzie wic umieszczana dyrektywa us i ng w po
staci us i ng Wi ndows . Fo rms :
u s i n g Sy stem ;
u s i n g Wi ndows . Forms ;
publ i c cl a s s n a zwa_k l a sy
{
publ i c stati c voi d M a i n ( )
{
//tutaj instrukcje do wykonania

C#

1 80

w i cz e n i a

Do utworzenia podstawowego okna bdzie potrzebna klasa Form z plat


formy .NET. Naley utworzy jej instancj oraz przekaza j jako pa
rametr w wywoaniu instrukcji App l i cat i on . Run ( ) . A zatem w naj
prostszym przypadku w metodzie Ma i n powinna znale si linia :
Appl i cati on . Run ( new Form ( ) ) : .
WICZENIE

Wywietlenie okna aplikacji

Napisz aplikacj okienkow, ktrej jedynym zadaniem b dzie wywie


tlenie na ekranie okna (rysunek 8 . 1 ) .
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms :
publ i c cl a s s Program
{
publ i c stati c voi d M a i n ( )
{
Appl i ca t i on . Run ( new Form ( ) ) :

ii C:\Windows\system32\cmd.exe - Program.exe

Rysunek 8. 1. Wynik dzialania kodu z wiczenia 8. 1

Okno z wiczenia 8 . 1 nie robi nic poytecznego, warto jednak zauwa


y, e s w nim do dyspozycji dziaajce przyciski suce do mi
nimalizacji, maksymalizacji oraz zmykania, a take typowe menu

Rozdzi a 8 .

P i e rwsze o k n o

1 81

systemowe . Osoby programujce w Javie powinny zwrci te uwa


g, e faktycznie tak aplikacj mona zamkn, klikajc odpowiedni
przycisk.
Nie bdziemy jednak zadowoleni z jednej rzeczy. Ot niezalenie
od tego, czy tak skompilowany program zostanie uruchomiony z po
ziomu wiersza polece, czy te przez kliknicie jego ikony, zawsze
w tle pojawia si bdzie okno konsoli. Jest to widoczne na rysunku
8 . 1 . Powd takiego zachowania jest prosty. Domylnie kompilator
zakada, e tworzymy aplikacj konsolow. Dopiero ustawienie od
powiedniej opcji kompilacji zmieni ten stan rzeczy (patrz tabela 1 . 1
z rozdziau 1 .) . Zamiast zatem pisa :
c s c Program . es

naley skorzysta z polecenia :


c s c /ta rget : wi nexe P rogram . es

lub z jego formy skrconej :


c s c /t : wi nexe Program . e s

Klasa Form udostpnia duy zbir waciwoci, ktre wpywaj na jej za


chowanie. Cz z nich zaprezentowana jest w tabeli 8 .1 . Pozwalaj one
m.in. na zmian rozmiarw, kolorw czy przypisanego kroju czcionki.
Tabela 8. 1. Wybrane wlaciwoci klasy Form

Ty p

Nazwa
waciwoci

Znaczenie

bool

AutoScal eMode

Ustala tryb automatycznego


skalowania okna.

bool

AutoScro l l

Okrela, czy w oknie maj si


automatycznie pojawia paski
przew1Jan1a.

bool

AutoSi ze

Okrela, czy forma ( okno) moe


automatycznie zmienia rozmiary
zgodnie z trybem okrelonym przez

AutoSi zeMode.
AutoSi zeMode

AutoSi zeMode

Okrela tryb automatycznej zmiany


rozmiarw formy.

Col or

BackCo l or

Okrela aktualny kolor ta.

C#

1 82

w i cz e n i a

Tabela 8. 1. Wybrane waciwoci klasy Form - cig dalszy

Ty p

Nazwa
waciwoci

Znaczenie

Im age

Background Image

Okrela obraz ta okna.

Bounds

Bounds

Okrela rozmiar oraz pooenie


okna.

Si ze

C l i entSi ze

Okrela rozmiar obszaru roboczego


okna.

Con textMenu

ContextMenu

Okrela powizane z oknem menu


kontekstowe.

Cu rsor

Cursor

Okrela rodzaj kursora wywietlanego,


kiedy wskanik myszy znajdzie si
nad oknem.

Font

Font

Okrela rodzaj czcionki, ktr bdzie


wywietlany tekst znajdujcy si
w oknie.

Col or

ForeCol or

Okrela kolor uywany do rysowania


obiektw w oknie ( kolor
pierwszoplanowy).

FormBo rderStyl e

FormBorde rStyl e

Ustala typ ramki okalajcej okno.

i nt

Hei ght

Okrela wysoko okna.

I con

I con

Ustala ikon przypisan do okna.

i nt

Le ft

Okrela w pikselach pooenie


lewego grnego rogu w poziomie.

Po i nt

Locati on

Okrela wsprzdne lewego


grnego rogu okna.

Ma i nMenu

Menu

Menu gwne przypisane do okna.

bool

Mod a l

Decyduje, czy okno ma by modalne.

s t r i ng

N a me

Okrela nazw okna.

Control

Pa ren t

Referencja do obiektu nadrzdnego


okna.

Rozdzi a 8 .

P i e rwsze o k n o

1 83

Tabela 8. 1. Wybrane waciwoci klasy Form - cig dalszy

Ty p

Nazwa
waciwoci

bool

Show i nTa s kb a r

Decyduje, czy okno ma by


wywietlane na pasku narzdziowym.

Si ze

Si ze

Okrela wysoko i szeroko okna.

Stri ng

Text

Okrela tytu okna ( tekst na pasku

Znaczenie

tytuu).

i nt

Top

Okrela w pikselach pooenie


lewego grnego rogu w pionie.

bool

Vi s i b l e

Okrela, czy okno ma by


widoczne.

i nt

Wi dth

Okrela w pikselach szeroko okna.

FormWi n dowState

Wi ndowSta te

Reprezentuje biecy stan okna.

WICZENIE

Wywietlenie okna o zadanym rozmiarze

Napisz aplikacj wywietlajc okno o rozmiarze 320x200 pikseli.


Zdefiniuj tytu okna wywietlany na pasku tytuu.
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms ;
publ i c c l a s s Ma i n Form : Form
{
publ i c Ma i n Form ( )
{
th i s . Wi dth
320 :
th i s . He i ght
200 :
th i s . Text
"Tytu okn a " :
=

publ i c stati c voi d M a i n ( )


{
Appl i ca t i on . Run ( new Ma i n Form ( ) ) :

Powstaa tu klasa Mai nForm dziedziczca z Form, a wic przejmujca jej


cechy i waciwoci. Jest to bardzo prosta konstrukcja zawierajca
jedynie konstruktor oraz metod Mai n . W konstruktorze waciwociom

1 84

C#

w i cz e n i a

wi dth i hei ght przypisywane s wartoci 320 i 2 0 0 . W metodzie Ma i n


tworzony jest nowy obiekt klasy Ma i nForm, ktrzy staje si argumentem
metody Run klasy Appl i cati on. Dziki temu okno o wymiarach 320 X 200
pojawia si na ekranie .

Wywietl a nie kom u n i katu


Aby wywietli okno z komunikatem (rysunek 8.2), naley skorzysta
z klasy Mess ageBox. Udostpnia ona metod S h ow wywietlajc cig
znakw podany jako argument. Poniewa jest to metoda statyczna, nie
trzeba wczeniej tworzy obiektu MessageBox, wystarczy wywoanie :
Mes s ageBox . Show ( " teks t " ) :
Rysunek 8. 2.

Wynik dziaania
metody Show klasy
MessageBox

WICZENIE

Wywietlenie okna dialogowego z zadanym komunikatem

Wywietl okno z dowolnym komunikatem.


u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms :
publ i c cl a s s Apl i k acj a
{
publ i c stati c voi d M a i n ( )
{
Me s s a geBox . Show( " Przyk a dowy tek s t " ) :

Rozdzi a 8 .

P i e rwsze o k n o

1 85

Okno z komunikatem wywietlane za pomoc metody zaprezento


wanej w wiczeniu 8 . 3 jest niezalene od okna aplikacj i. W prezen
towanym przykadzie okno aplikacji nawet nie powstao . Ten fakt
mona wykorzysta np . do wywietlania krtkiego tekstu licencji przed
uruchomieniem programu gwnego .
WICZENIE

Okno dialogowe przed oknem gwnym

Wywietl okno z komunikatem, ktre pojawi si przed gwnym oknem


aplikacji.
u s i n g Sy stem ;
u s i n g Sy stem . W i n dows . Forms ;
publ i c cl a s s Apl i k acj a
{
publ i c stati c voi d M a i n ( )
{
Me s s a geBox . Show( "To j est przy k a dowy tek st l i cencj i . " ) ;
Appl i ca t i on . Run ( new Form ( ) ) ;

Zd a rzenie Ap p l icatio n Exit


Co zrobi w sytuacji, kiedy chce si wywietli komunikat w czasie,
gdy aplikacja jest zamykana? W jaki sposb wychwyci ten moment?
Z pomoc przychodzi zdarzenie Appl i c ati onExi t (wicej informacji
o zdarzeniach podano w kolejnym rozdziale) . Jeli poczy si je od
powiednio z zawart w programie metod, bdzie mona wykona
dowolny kod przed wyjciem z programu. Schemat postpowania jest
zatem nastpujcy.
Tworzymy metod o dowolnej nazwie, np . OnEx i t , i nastpujcej
deklaracji :
p r i vate voi d n a zwa_metody ( obj ect sende r . EventArgs ea )
{
I/tutaj kod metody

C#

1 86

w i cz e n i a

Nastpnie w konstruktorze klasy pochodnej klasy Form, podobnie jak


w wiczeniu 8 . 2, umieszczamy instrukcj :
Appl i c ati on . Appl i c a t i on Exi t += new EventHandl e r ( th i s . n azwa_metody ) ;

WICZENIE

Obsuga zdarzenia ApplicationExit

Napisz program wywietlajcy okno gwne . Przy prbie zamknicia


aplikacji wywietl okno z dowolnym komunikatem.
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms ;
publ i c c l a s s Ma i n Form : Form
{
Button button = new Button ( ) ;
publ i c Ma i n Form ( )
{
Appl i ca t i on . Appl i c a t i on Exi t += new EventHandl e r ( th i s . on Exi t ) ;

pri vate voi d on Exi t ( obj ect sender . EventArgs ea )


{
Me s s a geBox . Show( "Apl i k acj a zostan i e zamkni ta ! " ) ;

publ i c stati c voi d M a i n ( )


{
Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

9
De l eg a cje i zd a rzenia
Del egacje
Przed przystpieniem do budowy aplikacji okienkowych bardziej zo
onych ni przedstawiane w rozdziale 8 . trzeba zapozna si z tematem
delegacji i zdarze. Wiadomoci te bd niezbdne , aby mona byo
reagowa na zdarzenia generowane przez uytkownika, takie jak klik
nicie przycisku czy te wybranie pozycji z menu. Czym zatem s
wspomniane delegacje? Mona powiedzie, e historycznie wywodz
si ze wskanikw do funkcji znanych jeszcze z C i C + + , cho s
konstrukcjami bardziej zaawansowanymi.
Rozwamy taki przykad : mamy dowoln, utworzon przez nas klas .
Klasa ta bdzie zawieraa dwa pola o nazwach x i y oraz metod Show
wywietlajc dane na ekranie . Realizacja takiego zadania z pewnoci
nie bdzie dla nikogo problemem, gdy wszystkie potrzebne wiadomo
ci zostay podane w rozdziale 4. Napiszmy wic krtki fragment kodu.
WICZENIE

Prosta klasa wyjciowa

Napisz kod klasy zawierajcej dwa pola typu i nt o nazwach x i y oraz


metod Show wywietlajc dane na ekranie .

C#

1 88

w i cz e n i a

u s i n g Sy stem :
publ i c cl a s s Konten e r
{
pub l i c i n t x :
publ i c i nt y ;
publ i c Konten e r ( i n t x , i n t y )
{
th i s . x
x:
th i s . y
y;
=

publ i c vo i d Show ( )
{
Con sol e . Wr i teli n e ( " x
Con sol e . Wr i teli n e ( "y

{ O }"
{ O }"

x) :
y) ;

Zgodnie z poleceniem w klasie zostay umieszczone dwa pola typu


i nt, tj . x i y. Ze wzgldu na uycie modyfikatora publ i e dostp do
nich nie jest ograniczony. Stan pl moe by ustalony za pomoc
dwuargumentowego konstruktora, natomiast ich wartoci mog by
wywietlone na konsoli przy uyciu metody Show.

Zamy teraz, e chcemy mie moliwo decydowania o ksztacie


metody Show i o tym, co robi w zupenie innym miejscu programu .
Konkretniej mwic, klasa Kontener ma zawiera metod Show, ale
implementacja tej metody mogaby by zmieniana w trakcie dziaa
nia programu. Raz wypisywalibymy na ekranie tylko warto zmiennej
x, innym razem tylko zmiennej y, a czasem chcielibymy, aby na
ekranie pojawiao si pene zdanie Wa rto x wynosi
a warto y Jak
to zrobi? Najprociej uy wanie delegacji.
. ,

WICZENIE

..

Tworzenie delegacji

Zmodyfikuj klas z wiczenia 9.1 w taki sposb , aby wywoywanie


funkcji Show odbywao si przez delegacj .
publ i c cl a s s Konten e r
{
pub l i c i n t x :
publ i c i nt y ;
publ i c Konten e r ( i nt x , i n t y )
{

Rozd z i a 9 .

D e l e g a cj e i zd a rz e n i a

1 89

th i s . x = x :
th i s . y = y ;

publ i c del egate vo i d ShowCa l l Ba c k ( Konten er k ) :


publ i c vo i d Show ( ShowC a l l Ba c k k )
{
k ( th i s ) :

Zaprezentowany kod pocztkowo moe wydawa si skomplikowa


ny. Tak jednak nie jest. Jak go interpretowa? Po pierwsze, zostaa
zadeklarowana delegacja o nazwie ShowCa 1 1 Bac k , ktrej parametrem
jest obiekt typu Kontener. Po drugie , parametrem metody Show jest
obiekt delegacji. Po trzecie, metoda Show wywouje delegacj, przeka
zujc jej jako parametr instancj obiektu, na rzecz ktrego jest wy
woywana .

Poniewa dla osb, ktre nie znaj tematyki delegacji, wyjanienie


wiczenia 9 .2 wci moe by zawie , najlepiej po prostu od razu
sprawdzi , jak w praktyce uy tego typu konstrukcji. To z pew
noci pozwoli wyjani wszelkie wtpliwoci.
WICZENIE

Proste uycie delegacji

Napisz program korzystajcy z klasy Kontener z wiczenia 9 .2 . Uyj


w nim mechanizmu delegacji.
u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d Show( Kon tene r k )
{
Con sol e . Wr i teli n e ( " x = { O }" . k . x ) :
Con sol e . Wr i teli n e ( "y = { O }" . k . y ) :

publ i c stati c voi d M a i n ( )


{
Konten er kont = new Kon tener ( lO O , 20 0 ) ;
Konten e r . ShowCa l l Ba c k c a l l Back =
new Kontener . ShowC a l l Back ( P rogram . Sh ow ) :
kont . Show ( c a l l Ba ck ) ;

C#

1 90

w i cz e n i a

W tym wiczeniu powstaa klasa P rog ram zawierajca metod Show


przyjmujc jako argument obiekt klasy Kontener . We wntrzu metody
nastpuje odczytanie wartoci pl x i y tego obiektu oraz wywietlenie
ich na ekranie . Wykonywanie kodu zaczyna si, jak wiadomo, od
funkcji M a i n. Powstaje w niej nowy obiekt kont klasy Kontene r :
Konten er kont = new Kon tener ( lOO , 20 0 ) :

Nastpnie tworzymy now delegacj cal l Back powizan z metod Show:


Konten er . ShowCa l l Ba c k c a l l Ba c k =
new Kontener . ShowC a l l Back ( P rogram . Sh ow ) ;

Ostatnim krokiem jest wywoanie metody Show obiektu kont i przeka


zanie jej w postaci argumentu delegacji ca 1 1 Bac k . Tym samym o spo
sobie wywietlenia wartoci pl x i y obiektu kont bdzie decydowaa
metoda Show z klasy P rogram.
WICZENIE

Wykorzystanie kilku delegacji

Napisz i przetestuj kilka delegacji dla metody Show klasy Kontener.


u s i n g Sy stem :
publ i c cl a s s Program
{
publ i c stati c voi d Show l ( Konten er k )
{
Con sol e . Wr i teli n e ( " x = { O }" , k . x ) ;
Con sol e . Wr i teli n e ( "y = { O } \ n " , k . y ) ;
}
publ i c stati c voi d Show2 ( Konten er k )
{
Con sol e . Wr i tel i n e ( " W a rto x wyn o s i { O }" , k . x ) :
Con sol e . Wr i tel i n e ( " W a rto y wyn o s i { O } \ n " , k . y ) :
}
publ i c stati c voi d Show3 ( Konten er k )
{
Con sol e . Wr i teli n e ( "Obi ekt zawi era n a stpuj ce po l a : " ) :
Con sol e . Wr i teli n e ( " Pol e x o warto c i { O } " , k . x ) :
Con sol e . Wr i teli n e ( " Pol e y o warto c i { O } \ n " , k . y ) :
}
publ i c stati c voi d M a i n ( )
{
Konten er kont= n ew Konten er ( l O O . 20 0 ) :
Konten e r . ShowCa l l Ba c k c a l l Ba c k l =
new Kontener . ShowC a l l Ba c k ( P rogram . Sh owl ) :

Rozd z i a 9 .

D e l e g a cj e i zd a rz e n i a

1 91

Konten e r . ShowCa l l Ba c k c a l 1 Back2


new Kontener . ShowC a l l Ba c k ( P rogram . Sh ow2 ) :
Konten e r . ShowCa l l Ba c k c a l 1 Back3
new Kontener . ShowC a l l Ba c k ( P rogram . Sh ow3 ) :
=

Con sol e . Wr l tel1 n e ( " P 1 erwsza funkcj a Show" ) ;


kont . Show ( c a l l Ba ck l ) :
Con sol e . Wr l tel l n e ( " D ruga fun kcj a Show" ) ;
kont . Show ( c a l 1 Ba c k 2 ) ;
Con sol e . Wr l tel l n e ( "Trzec1 a fu nkcj a Show" ) ;
kont . Show ( c a l 1 Ba c k3 ) ;

Tym razem zdefiniowane zostay trzy delegacje (ca l l Bac k l , cal l Back2,
ca 1 1 Back3) i trzy funkcje Show (Showl, Show2, Show3), ktre w rny spo
sb wywietlaj dane z obiektu typu Kontene r . Sposb postpowania
jest tu taki sam jak w wiczeniu 9 . 3 . W tym przypadku do obsugi
wywietlania danych z obiektu typu Kontener uywane s po prostu
trzy rne funkcje zdefiniowane w klasie P rogram. Najwaniejsze jest
jednak to, e wywoania metody Show pozwalaj na wykonanie prak
tycznie dowolnego kodu, a nie wymagaj przy tym adnych zmian
w klasie Kontene r .
Efekt dziaania kodu z powyszego wiczenia widoczny jest na ry
sunku 9 . 1 .
Rysunek 9. 1.

Wynik dziaania
trzech rnych
delegacji dla
funkcji Show

1 92

C#

w i cz e n i a

Zd a rzenia
Mechanizm zdarze (ang . events) oparty jest na delegacjach i pozwala,
aby obiekt mg informowa o swoim stanie czy te wanie o wyst
pieniu pewnego zdarzenia. Najczciej wykorzystuje si t moliwo
podczas tworzenia aplikacji z interfejsem graficznym . Wanie przy
uyciu zdarze mona reagowa na kliknicie mysz przycisku czy
wybranie pozycji z menu. Zanim jednak przejdziemy do obsugi zdarze11
w rodowisku okienkowym (co zostanie pokazane w rozdziale 1 O . ) , zo
baczmy, w jaki sposb te mechanizmy dziaaj.
Do definiowania zdarze11 suy sowo kluczowe event. Jednak wczeniej
naley utworzy odpowiadajc zdarzeniu delegacj, a zatem postpo
wanie jest dwuetapowe .
1.

Definiujemy delegacj w postaci:


publ 1 c del egate typ_zwracany nazwa_de l egacj i (parametry) ;

2.

Definiujemy jedno lub wicej zdarze w postaci :


publ 1 c stat 1 c event nazwa_de l egacj i nazwa_zdarzen i a

Sprbujmy wykona praktyczny przykad. Zamy, e mamy klas


Kontener w postaci:
publ 1 c cl a s s Konten e r
{
pr1 vate 1 n t x ;
publ 1 c Konten e r ( )
{
Set X ( O ) ;

publ 1 c vo 1 d SetX ( 1 n t x )
{
th 1 s . x
x;
=

}
publ 1 c 1 nt GetX ( )
{
return x :

Pole x jest prywatne, nie ma do niego bezporedniego dostpu. Do


ustawiania suy bdzie zatem metoda s etX . Pobieranie danych za
pewnia metoda getX . Wyobramy sobie teraz, e ta klasa bardzo nie
lubi" , kiedy warto x jest mniejsza od zera. Jeeli wic wykryje, e

Rozd z i a 9 .

D e l e g a cj e i zd a rz e n i a

1 93

polu x chcemy przypisa liczb ujemn, wysya, poprzez zdarzenie,


stosown informacj. Czas zatem na utworzenie odpowiedniej delegacji
i zdarzenia .
WICZENIE

Wiqzanie delegacji i zdarze

Zmodyfikuj klas Kontener w taki sposb, aby po przypisaniu wartoci


ujemnej polu x generowaa odpowiednie zdarzenie .
publ i c cl a s s Konten e r
{
pri vate i n t x :
publ i c Konten e r ( )
{
Set X ( O ) :

publ i c del egate vo i d EventHandl e r ( ) :


publ i c stati c even t EventHa ndl e r XJe stUj emne :
publ i c vo i d SetX ( i n t x )
{
th i s . x = x :
i f( x < 0 )
{
i f( XJ estUj emne ! = n u l l )
XJestUj emne ( ) :

publ i c i nt GetX ( )
{
return x :

Zgodnie z podanymi wyej zasadami zostaa tu zdefiniowana zarwno


delegacja:
publ i c del egate voi d Even tHandl e r ( ) ;

jak i powizane z ni zdarzenie :


publ i c stat i c event EventHand l e r XJestUj emne :

W metodzie setX nastpuje sprawdzanie, czy przekazany parametr ma


warto mniejsz od zera. Jeli tak, wywoywane jest zdarzenie :
XJ estUj emne ( ) :

1 94

C#

w i cz e n i a

Niezbdne jest jednak wczeniejsze sprawdzenie, czy do tego zdarzenia


zastaa przypisana jaka procedura obsugi. Suy temu instrukcja:
i f ( XJe stUj emne 1 = n u l l )

Ujmujc rzecz nieco inaczej : jeeli istnieje powizana ze zdarzeniem


delegacja, za pomoc tej delegacji mona wywoa odpowiadajc jej
metod . Zostanie to pokazane w kolejnym wiczeniu.

Sprawdmy teraz, w jaki sposb przypisa procedur obsugi zdarzenia


do obiektu . Naley skorzysta z operatora += w postaci :
NazwaK 7 asy . NazwaZdarzen i a += new
Nazwa K l asy . NazwaDe 7 egacj i ( Procedura0bs ug i ) ;

WICZENIE

Testowanie zdarze i delegacji

Napisz procedur obsugi zdarzenia dla klasy Kontener. Sprbuj przypi


sa polu x warto ujemn i sprawd, czy program dziaa zgodnie
z zaoeniami.
u s i n g Sy stem ;
publ i c cl a s s Program
{
publ i c stati c voi d On U j emn e ( )
{
Con sol e . Wr i teli n e ( " X j e st uj emne l " ) ;

publ i c stati c voi d M a i n ( )


{
Konten er k = new Konten er ( ) ;
Konten e r . XJ e stUj emne += n ew Konten er . E ventHandl e r ( On Uj emne ) ;
k . Set X ( - 1 ) ;

Procedur obsugi zdarzenia XJestUjemne, powstajcego gdy warto pola


x obiektu typu Kontener spadnie poniej zera, jest tu metoda OnUj emne
z klasy P ro g r a m . Wiemy j ze zdarzeniem za pomoc delegacji,
w wierszu :
Konten e r . XJ estUj emne += n ew Kon tener . E ventHan d l e r ( OnUjemne ) ;

Rozd z i a 9 .

D e l e g a cj e i zd a rz e n i a

1 95

Dziki temu po wykonaniu instrukcji :


k . SetX ( - 1 ) :

na ekranie pojawi si komunikat zdefiniowany w metodzie OnUjemne.

Co jednak zrobi w sytuacji, kiedy chcemy w procedurze obsugi


mie dostp do obiektu, ktry zdarzenie wygenerowa? Nie ma naj
mniejszego problemu. Wystarczy odpowiednio skonstruowa dele
gacj. A gdyby trzeba byo jednemu zdarzeniu przypisa kilka procedur
obsugi? To te jest moliwe . Wystarczy kilkakrotnie uy opera
tora += .
WICZENIE

Dostp do obiektu generujqcego zdarzenie

Zmodyfikuj utworzone w poprzednich wiczeniach klasy P rog ram oraz


Kontener w taki sposb , aby procedura obsugi zdarzenia otrzymy
waa jako parametr obiekt generujcy zdarzenie . Napisz dwie rne
procedury obsugi zdarzenia.
u s i n g Sy stem :
publ i c cl a s s Konten e r
{
pri vate i n t x :
publ i c Konten e r ( )
{
Set X ( O ) :

publ i c del egate vo i d EventHan dl e r ( Konten er k ) :


publ i c stati c even t EventHa ndl e r XJe stUj emne :
publ i c vo i d SetX ( i n t x )
{
th i s . x = x :
i f(x < 0 )
{
i f ( XJes tUj emne 1 = nu l l )
XJestUj emne ( th i s ) :

publ i c i nt GetX ( )
{
return x :

C#

1 96

w i cz e n i a

publ i c cl a s s Program

publ i c stati c voi d On U j emn e l ( Kontene r k )

{
}

Con sol e . Wr i teli n e ( " X j e st rwne { O } . " , k . G etX ( ) ) :

publ i c stati c voi d On U j emn e 2 ( Kontene r k )

Con sol e . Wr i tel i n e ( " D ruga procedura obs ug i zda rzen i a l " ) :

publ i c stati c voi d M a i n ( )

Konten er kont = new Kon tener ( ) :


Konten e r . XJ e stUj emne += n ew Konten e r . EventHandl e r ( On Uj emne l ) :
Konten e r . XJ e stUj emne += n ew Konten e r . EventHandl e r ( On Uj emne2 ) :
kont . SetX ( - 1 ) :

W klasie Kontener zmieni si typ delegacji. Obecnie przyjmuje ona


jeden argument typu Kontener i nie zwraca wyniku. Dlatego te me
tody bdce procedurami obsugi zdarzenia XJestUjemne bd musiay
mie deklaracje zgodne z powyszym opisem. Tak wanie jest z me
todami OnUjemnel i 0Ujemne2 w klasie P rogram. Wizanie metod ze zda
rzeniem odbywa si za pomoc instrukcji:
Konten e r . XJ estUj emne += n ew Kontener . EventHand l e r ( OnUj emne l ) ;
Konten e r . XJ estUj emne += n ew Kontene r . EventHand l e r ( OnUj emne2 ) :

Tym samym zdarzenie otrzymuje dwie procedury obsugi i po przy


pisaniu ujemnej wartoci polu x obie zostan wykonane . Zatem po
uruchomieniu programu na ekranie pojawi si komunikaty widoczne
na rysunku 9 . 2 .
Rysunek 9. 2.

Wykonanie dwch
rnych metod
w odpowiedzi
na zdarzenie

Ko m ponenty
Etykiety (La bel)
Klasa Label suy do tworzenia etykiet, czyli kontrolek uywanych
do wywietlania krtkich napisw. Tekst etykiety moe by zmieniany
przez aplikacj, uytkownik nie ma natomiast moliwoci bezpored
niej jego edycji. Aby skorzysta z etykiety, naley utworzy obiekt
klasy Label oraz doda go do kolekcji Control s okna, na ktrym ta
etykieta ma si znajdowa . W tym celu stosuje si instrukcj Control s .
4-Add ( nazwa_etykiety ) . Wygld oraz zachowanie etykiety mona modyfi
kowa, korzystajc z jej waciwoci, ktre zebrane s w tabeli 1 0 . 1 .
Tabela 10. 1. Wybrane wlaciwoci klasy Label
Ty p

Nazwa
waciwoci

Znaczenie

bool

AutoS 1 ze

Okrela, czy etykieta ma automatycznie


dopasowywa swj rozmiar do zawartego
w niej tekstu.

Col or

BackCol or

Okrela kolor ta etykiety.

Bo rderStyl e

Bo rderStyl e

Okrela styl ramki otaczajcej etykiet.

Bounds

Bounds

Okrela rozmiar oraz pooenie etykiety.

C#

1 98

w i cz e n i a

Tabela 10. 1. Wybrane wlaciwoci klasy Label - cig dalszy


Ty p

Nazwa
waciwoci

Znaczenie

Cu rsor

Cu rsor

Okrela rodzaj kursora wywietlanego, kiedy


wskanik myszy znajdzie si nad etykiet.

Font

Font

Okrela rodzaj czcionki, ktr bdzie


wywietlany tekst znajdujcy si na etykiecie.

Col or

Im age

Fo reCol or

Okrela kolor tekstu etykiety.

He1 ght

Okrela wysoko etykiety.

Im age

Obraz wywietlany na etykiecie.

Le ft

Okrela pooenie lewego grnego rogu


w poziomie, w pikselach.

Po 1 nt

Locat 1 on

Okrela wsprzdne lewego grnego rogu


etykiety.

Control

Name

Nazwa etykiety.

Pa rent

Referencja do obiektu zawierajcego


etykiet ( nadrzdnego).
Okrela wysoko i szeroko etykiety.

s t r 1 ng

Text

Okrela tekst wywietlany na etykiecie.

ContentA1 1 gnment

TextA1 1 gn

Okrela pooenie tekstu na etykiecie.

Top

Okrela pooenie lewego grnego rogu


w pionie, w pikselach.

bool

WICZENIE

V1 s 1 bl e

Okrela, czy etykieta ma by widoczna.

W1 dth

Okrela rozmiar etykiety w poziomie.

Dodanie etykiety do okna aplikacji

Dodaj do okna aplikacji komponent Label z dowolnym tekstem. Ety


kieta powinna znale si w centrum okna aplikacji.

R o z d z i a 1 0. Ko m p o n e n t y

1 99

u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms ;
publ i c c l a s s Ma i n Form : Form

Label l abel = new Label ( ) ;


publ i c Ma i n Form ( )

th i s . Wi dth = 320 ;
th i s . He i ght = 2 0 0 :
th i s . Text = "Okno z etyk i et" ;
l a bel . Text = " Przy k adowa etyk i eta . . . " ;
l a bel . AutoSi ze = true :
l a bel . Left = ( th i s . C l i entSi ze . W i dt h - l abel . Wi dth ) I 2 ;
l a bel . Top = ( th i s . Cl i en tS i ze . Hei ght - l abel . He i ght ) I 2 ;
th i s . Control s . Add ( l abel ) ;

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) :

Wynikiem dziaania kodu z powyszego wiczenia jest okno widoczne


na rysunku 1 0 . 1 . Jak wida , tekst faktycznie znajduje si w centrum
formy. Takie umiejscowienie etykiety uzyskujemy poprzez modyfikacj
waciwoci Top oraz Left. Aby uzyska odpowiednie wartoci, wyko
nywane s proste dziaania matematyczne :
Wsp rzdna X = ( d ugo o k n a - d ugo etyk i ety ) I 2
Wsp rzdna Y = ( wysoko o k n a - wysoko etyk i ety ) I 2
Rysunek 1 0. 1.

Etykieta tekstowa
um1e;scow10na
w centrum okna

ii ...

Okno z etykiet

Przyka owa ety'klietai . . .

Oczywicie, dziaania te naley wykona po przypisaniu etykiecie


tekstu, inaczej nie bd uwzgldniay jej prawidowej wielkoci . Do
uzyskania szerokoci i wysokoci formy naley wykorzysta waci
woci C l i entWi dth oraz Cl i entHei g h t . Podaj one rozmiar okna po

C#

200

w i cz e n i a

odliczeniu okalajcej ramki oraz paska tytuowego i ewentualnego


menu, czyli po prostu wielko okna, ktr mamy do dyspozycji i na
ktrej moemy umieszcza inne obiekty.

Tekst wywietlany na etykiecie moe by wywietlany dowoln


czcionk zainstalowan w systemie . Wystarczy zmodyfikowa wa
ciwo Font obiektu Label . Aby jednak tak modyfikacj wykona,
trzeba najpierw utworzy obiekt klasy Font (dostpnej w przestrzeni
nazw System . D rawi ng) . Klasa ta zawiera kilka konstruktorw, mona
uy konstruktora o postaci:
publ i c Fon t ( Fon tFami l y fami l y , fl oat emSi ze . Fon tStyl e styl e ) :

Parametr emS i ze okrela wielko czcionki, natomiast FontStyl e to typ


wyliczeniowy, w ktrym zdefiniowane s wartoci prze dstawione
w tabeli 1 0 . 2 .
Tabela 10. 2. Wartoci typu FontStyle
Nazwa

Znaczenie

Bo l d

tekst pogrubiony

Ital i c

tekst pochylony

Regu l a r

tekst zwyczajny

Stri keout

tekst przekrelony

Underl i ne

tekst podkrelony

FontFami l y jest to klasa reprezentujca rodzin czcionek. Udostpnia ona


rwnie statyczn waciwo Fami l i es , ktra zwraca tablic z list
wszystkich fontw dostpnych w systemie . To, jak uzyska tak list,
zostao pokazane w wiczeniu 1 0 . 2 .
WICZENIE

Lista dostpnych czcionek

Wypisz na ekranie list wszystkich dostpnych czcionek.


u s i n g Sy stem :
u s i ng Sy stem . Drawi ng :
publ i c cl a s s Program

R o z d z i a 1 0. Ko m p o n e n t y

publ i c stati c voi d M a i n ( )

foreach ( Fon tFami l y font i n FontFami l y . Fami l i es )

2o1

Con s o l e . W r i tel i ne ( font . Name ) :

Przykadowa lista czcionek uzyskana za pomoc tego programu wi


doczna jest na rysunku 1 0 . 2 . Kod jest bardzo prosty, zostaa uyta
zwyczajna ptla typu fo rea c h (omwiona w rozdziale 5 ., Tablice" ) ,
ktra przebiega przez wszystkie elementy tablicy FontFami l y . Farni l i es .
W celu uzyskania nazwy danego fontu odwoujemy si do waciwoci
Name obiektu podstawionego pod zmienn font (jej typem jest Font) .
Naley zwrci uwag na znajdujc si na pocztku kodu dyrektyw
us i ng System . Drawi ng, za pomoc ktrej mona korzysta z przestrzeni
nazw System . Drawi ng, gdzie zdefiniowane s m.in. klasy Font i FontFami ly.
Rysunek 1 0. 2.

Lista czcionek
uzyskana przy
uzyc1u programu
z wiczenia 1 0.2

Skoro wiadomo ju tak duo na temat fontw, sprbujmy wywietli


tekst na etykiecie wybran czcionk, np . typu Courier. W wikszoci
systemw jest ona zainstalowana standardowo. Skorzystamy z przed
stawionego wczeniej konstruktora klasy Font, nie bdziemy jednak
tworzy bezporednio obiektu klasy FontFami l y, lecz pozwolimy, aby
system zrobi to za nas . Zamiast wic pisa :
new Fon t ( n ew FontFami l y ( "Cou r i e r " ) . 20 . FontStyl e . Bo l d ) :

uyjemy konstrukcji :
new Fon t ( "Couri e r " . 20 . FontStyl e . Bol d ) :

C#

2 02

WICZENIE

w i cz e n i a

Etykieta wykorzystujca wybrany krj czcionki

Dodaj do okna aplikacji komponent Label z dowolnym tekstem napi


sanym czcionk Cou ri er o wielkoci 20 punktw (rysunek 1 0 . 3 ) .
u s i n g Sy stem . W i n dows . Forms ;
u s i ng Sy stem . Drawi ng ;
publ i c c l a s s Ma i n Form : Form

Label l abel = new Label ( ) ;


publ i c Ma i n Form ( )

th i s . Wi dth = 320 ;
th i s . He i ght = 2 0 0 ;
th i s . Text = "Okno z etyk i et" ;
l a bel . Font = new Fon t ( "Couri e r " , 20 . Fon tStyl e . Bol d ) ;
l a bel . Text = " C zci on k a Couri e r " ;
l a bel . AutoSi ze = true ;
th i s . Control s . Add ( l abel ) ;
l a bel . Left = ( th i s . C l i entSi ze . W i dt h - l abel . Wi dth ) I 2 ;
l a bel . Top = ( th i s . Cl i en tS i ze . Hei ght - l abel . He i ght ) I 2 ;

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Rysunek 1 0. 3.

Etykieta, na ktrej
uyto czcionki
Courier o wielkoci
20 punktw

ii...,

Okno

etykiet

C z c i o nka

Cour i e r

R o z d z i a 1 0. Ko m p o n e n t y

2 03

Przyciski (Button)
Klasa Button pozwala na tworzenie standardowych przyciskw z do
wolnymi napisami. Aby z niej skorzysta, naley utworzy nowy
obiekt tej klasy, ustali jego pooenie oraz napisa procedur obsugi
zdarze (wykonywan po klikniciu przycisku) . Przycisk umiejscawia
my w oknie ; wykorzystujemy tu waciwoci Top oraz Left, podobnie
jak w innych komponentach (np . etykietach) . Przydatne waciwoci
klasy Button przedstawione s w tabeli 1 0 . 3 .
Tabela 10. 3. Wybrane wlaciwoci klasy Button
Ty p

Nazwa waciwoci

Znaczenie

Col or

Back Col or

Okrela kolor ta przycisku.

Bounds

Bounds

Okrela rozmiar oraz pooenie przycisku.

Cu rsor

Cu rsor

Okrela rodzaj kursora wywietlanego,


kiedy wskanik myszy znajdzie si
nad przyciskiem.

Fl atStyl e

Fl atStyl e

M odyfikuje styl przycisku.

Font

Font

Okrela rodzaj czcionki, ktr bdzie


wywietlany tekst znajdujcy si
na przycisk u.

Co l o r

Im age

Fo reCo l or

Okrela kolor tekstu przycisk u.

He1 ght

Okrela wysoko przycisku.

I mage

Obraz wywietlany na przycisku.

Left

Okrela pooenie lewego grnego rogu


w poziomie, w pikselach.

Po 1 nt

Locat 1 on

Okrela wsprzdne lewego grnego


rogu przycisku.

Control

Name

Nazwa przycisku.

Pa rent

Referencja do obiektu zawierajcego


przycisk ( obiektu nadrzdnego).

S1 ze

Okrela wysoko i szeroko przycisku.

2 04

C#

w i cz e n i a

Tabela 10. 3. Wybrane waciwoci klasy Button - cig dalszy


Ty p

Nazwa waciwoci

Znaczenie

s t r i ng

Text

Tekst wywietlany na przycisku.

Con tent
._Al i gnment

TextAl i gn

Okrela pooenie tekstu na przycisku.

i nt

Top

Okrela pooenie lewego grnego rogu


w pionie, w pikselach.

bool

Vi s i bl e

Okrela, czy przycisk ma by widoczny.

i nt

Wi dth

Okrela rozmiar przycisku w poziomie,


w pikselach.

WICZENIE

Umieszczenie przycisku w oknie aplikacji

Utwrz okno, w ktrym bdzie znajdowa si przycisk (rysunek 10 .4) .


u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

Button button = new Button ( ) ;


publ i c Ma i n Form ( )

th i s . Wi dth = 320 ;
th i s . He i ght = 2 0 0 :
th i s . Text = "Okno z p rzyc i s k i em" :
button . Top = 60 :
bu tton . Left = 120 :
th i s . Control s . Add( button ) :

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

205

R o z d z i a 1 0. Ko m p o n e n t y
Rysunek 1 0.4.

Przycisk dodany
w glwnym oknie
aplikacji

1iSJ Okno z przyciskiem

Przycisk utworzony w wiczeniu 1 0 .4 nie reaguje na kliknicia, nie


ma te na nim adnego napisu. Konieczne zatem bd kolejne mody
fikacje kodu programu . Na przypisanie tekstu do przycisku pozwala
waciwo Text. Z kolei reakcje na kliknicia zapewni dodanie pro
cedury obsugi zdarze11 do waciwoci Cl i ck :
button . Cl 1 c k += eh :

gdzie eh to obiekt klasy EventHandl er (rozdzia 9 .) .


WICZENIE

Obsuga klikni przycisku

Zmodyfikuj kod z wiczenia 1 0 .4 w taki sposb, aby po klikniciu


przycisku nastpowao zamknicie aplikacji. Na przycisku powinien
te pojawi si napis .
u s 1 n g Sy stem :
u s 1 n g Sy stem . W 1 n dows . Forms :
publ 1 c c l a s s Ma 1 n Form : Form

Button button = new Button ( ) :


publ 1 c Ma 1 n Form ( )

th 1 s . W1 dth = 320 :
th 1 s . He 1 ght = 2 0 0 :
th 1 s . Text = "Okno z przyc 1 s k 1 em " :
button . Top = 60 :
bu tton . Left = 120 :
bu tton . Text = " K l 1 kn 1 j mn 1 e 1 " :
EventHandl er eh = n ew EventHandl er ( th 1 s . Cl oseC1 1 cked ) :
bu tton . C l 1 c k += eh :
th 1 s . Control s . Add( button ) :

C#

2 06

w i cz e n i a

publ i c vo i d C l oseC l i cked ( Obj ect sender . Even tArgs e )

th i s . C l o s e ( ) :

publ i c stati c voi d M a i n ( )

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

}
}
Tekst na przycisku zosta zdefiniowany za pomoc waciwoci Text.
Powsta take obiekt typu EventHandl er powizany z metod Cl oseCl i cked.
Metoda ta ma dwa argumenty. Pierwszy (s ender) wskazuje obiekt b
dcy rdem zdarzenia (w tym przypadku jest to przycisk button),
drugi (e) zawiera informacje powizane ze zdarzeniem (np . wsp
rzdne kliknicia) . Te dane nie s jednak uywane . Jedynym dziaaniem
metody Cl oseCl i cked jest zamknicie okna aplikacji (wywoanie metody
Cl ose) . Procedura obsugi zdarzenia jest wizana ze zdarzeniem (wa
ciwo Cl i ck przycisku) w instrukcji:
button . Cl i c k += eh :

Pol a tekstowe (TextBox)


Klasa TextBox suy do utworzenia pl tekstowych umoliwiajcych
wprowadzanie przez uytkownika cigw znakw. W zalenoci od
ustawie11 pole tekstowe moe by jedno- lub wielowierszowe . Zmia
ny mona wykona poprzez odpowiednie ustawienie waciwoci
Mul ti l i ne. Wybrane waciwoci klasy przedstawione s w tabeli 10.4.

R o z d z i a 1 0. Ko m p o n e n t y

207

Tabela 10.4. Wybrane wlaciwoci klasy TextBox


Ty p

Nazwa
waciwoci

Znaczenie

bool

AutoS 1 ze

Okrela, czy pole tekstowe ma automatycznie


dopasowywa swj rozmiar do zawartego
w nim tekstu.

Col or

BackCol or

Okrela kolor ta pola tekstowego.

I mage

Background I mage

Obraz znajdujcy si w tle okna tekstowego.

BorderStyl e

BorderStyl e

Okrela styl ramki otaczajcej pole tekstowe.

Bounds

Bounds

Okrela rozmiar oraz pooenie pola


tekstowego.

Cu rsor

Cu r s o r

Rodzaj kursora wywietlanego, kiedy wskanik


myszy znajdzie si nad polem tekstowym.

Font

Font

Okrela rodzaj czcionki, ktr bdzie


wywietlany tekst znajdujcy si w polu.

Col or

ForeCol or

Okrela kolor tekstu pola tekstowego.

He1 ght

Okrela wysoko pola tekstowego.

Le ft

Okrela pooenie lewego grnego rogu


w poziomie, w pikselach.

str1 n g [ J

L 1 nes

Tablica zawierajca poszczeglne linie tekstu


zawarte w polu tekstowym.

Po 1 nt

Locat 1 on

Okrela wsprzdne lewego grnego rogu


pola tekstowego.

Maxlength

Maksymalna liczba znakw, ktre mona


wprowadzi do pola tekstowego.

bool

Mod1 f1 ed

Okrela, czy zawarto pola tekstowego bya


modyfikowana.

bool

Mu l t1 1 1 ne

Okrela, czy pole tekstowe ma zawiera


jedn, czy wiele linii tekstu.

s t r 1 ng

N a me

Nazwa pola tekstowego.

Control

Pa rent

Referencja do obiektu zawierajcego pole


tekstowe ( obiektu nadrzdnego).

C#

2 08

w i cz e n i a

Tabela 10.4. Wybrane wlaciwoci klasy TextBox - cig dalszy


Ty p

Nazwa
waciwoci

Znaczenie

Char

Pas swordCh a r

Okrela, jaki znak bdzie wywietlany


w polu tekstowym w cel u zamaskowania
wprowadzanego tekstu; aby skorzysta z tej
opcji, waciwo Mul ti l i ne musi by ustawiona

na fa l se .
bool

Rea dOn l y

Okrela, czy pole tekstowe ma by ustawione


w trybie tylko do odczytu.

s t r i ng

Sel ectedText

Zaznaczony fragment tekstu w polu tekstowym.

i nt

Sel ecti on length

Liczba znakw w zaznaczonym fragmencie


tekstu.

i nt

Sel ecti onSta rt

Indeks pierwszego znaku zaznaczonego


fragmentu tekstu.

Si ze

Si ze

Okrela rozmiar pola tekstowego.

s t r i ng

Text

Tekst wywietlany w polu tekstowym.

Con tent
'-+Al i gnment

TextAl i gn

Okrela pooenie tekstu w polu tekstowym.

i nt

Top

Okrela pooenie lewego grnego rogu


w pionie, w pikselach.

bool

Vi s i bl e

Okrela, czy pole tekstowe ma by widoczne.

i nt

Wi dth

Okrela rozmiar pola tekstowego w poziomie.

bool

WordWrap

Okrela, czy sowa maj by automatycznie


przenoszone do nowej linii, kiedy nie mieszcz
si w biecej; aby zastosowa t funkcj,
waciwo M u l t i l i n e musi by ustawiona
na true.

R o z d z i a 1 0. Ko m p o n e n t y

WICZENIE

209

Obsuga pola tekstowego

Umie w oknie aplikacji pole tekstowe i przycisk. Po klikniciu przyci


sku wywietl wprowadzony do pola tekst w oknie dialogowym.
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

Button button = new Button ( ) :


TextBox textBox = new TextBox( ) :
publ i c Ma i n Form ( )

th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
th i s . Text = "Apl i k acj a " :
bu tton . Top = 120 :
bu tton . Left = ( th i s . Cl i en tS i ze . Wi dth - button . W i dth ) I 2 ;
bu tton . Text = " K l i kn i j mn i e l " ;
textBox . Top = 60 :
textBox . Left = ( th i s . C l i entSi ze . W i dth - textBox . Wi dth ) I 2 ;
EventHandl er eh = n ew EventHandl er ( th i s . Bu ttonC l i cked ) ;
bu tton . C l i c k += eh :
th i s . Control s . Add( button ) :
th i s . Control s . Add( textBox ) ;

publ i c vo i d Button C l i cked( Obj ect sende r . EventArgs e )

Me s s ageBox . Show( textBox . Text ) ;

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) :

W oknie aplikacji zostay umieszczone przycisk (button) oraz pole


tekstowe (textBox) . Pozycja tych elementw w pionie ustalana jest
arbitralnie, natomiast pozycja w poziomie jest wyliczana dynamicznie,
tak aby oba elementy byy wyrodkowane . Przycisk otrzyma proce
dur obsugi zdarzenia w postaci metody ButtonCl i cked (odbywa si
to na takich samych zasadach jak w wiczeniu 1 0 . 5) . W metodzie
ButtonCl i cked jest uywana metoda Show klasy MessageBox wywietlajca
komunikat (zawarto pola Text pola tekstowego textBox) .

C#

210

WICZENIE

w i cz e n i a

Inne uycie pola tekstowego

Umie w oknie aplikacji pole tekstowe, etykiet tekstow i przycisk,


tak jak na rysunku 1 0 . 5 . Po klikniciu przycisku wywietl na etykiecie
cig znakw wprowadzony przez uytkownika w polu tekstowym.
u s i n g Sy stem :
u s i ng Sy stem . Drawi ng :
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

Button button = new Button ( ) :


Label l abel = new Label ( ) :
TextBox textBox = new TextBox( ) :
publ i c Ma i n Form ( )

th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
th i s . Text = "Apl i k acj a " :
button . Top = 60 :
bu tton . Left = ( th i s . Cl i en tS i ze . Wi dth - button . W i dth ) I 2 :
bu tton . Text = " K l i kn i j mn i e l " :
l a bel
l a bel
l a bel
l a bel

. Top = 30 :
. Text = " Etyk i eta " :
. TextAl i gn = ContentAl i gnment . Mi ddl eCente r :
. Left = ( th i s . C l i entSi ze . W i dt h - l abel . Wi dth ) I 2 :

textBox . Top = 120 :


textBox . Left = ( th i s . C l i entSi ze . W i dth - textBox . Wi dth ) I 2 :
EventHandl er eh = n ew EventHandl er ( th i s . Bu ttonC l i cked ) :
bu tton . C l i c k += eh :
th i s . Control s . Add( button ) :
th i s . Control s . Add ( l abel ) :
th i s . Control s . Add( textBox ) :

publ i c vo i d Button C l i cked( Obj ect sende r . EventArgs e )

l a bel . Text = textBox . Text :


l a bel . Left = C th i s . C l i entSi ze . W i dt h - l abel . Wi dth ) I 2 :

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) :

21 1

R o z d z i a 1 0. Ko m p o n e n t y
Rysunek 1 0. 5.

Wynik dzialania kodu


z wiczenia 1 O. 7

a..,

Ap l i kacj a
-----

G:JI

Test prQQramu.

I Kl i knij mnie!

IT

est programu .

Oglna budowa aplikacji jest podobna do prezentowanej w wicze


niu 1 0 . 6 . Dodatkowo pojawia si jedynie etykieta reprezentowana
przez pole l abel klasy Label . Tekst etykiety jest pozycjonowany (w tym
przypadku - centrowany) dziki zmianie waciwoci TextAl i gn .
Przypisywan wartoci jest M i ddl eCenter (oznacza wyrodkowanie
w pionie i poziomie) pochodzca z klasy ContentAl i gnment. Procedur
obsugi zdarzenia Cl i c k przycisku button jest metoda Butto n C l i c k ed .
W tej metodzie tekst pobrany z pola tekstowego (waciwo Text obiek
tu textBox) jest przypisywany etykiecie (waciwo Text obiektu l abel ) .
Dodatkowo zmieniana jest pozycja etykiety tak, aby zawsze znajdo
waa si w rodku okna (ze wzgldu na uycie waciwoci TextAl i gn
mona by to rozwiza inaczej - etykieta mogaby mie szeroko
okna; jest to jednak wiczenie do samodzielnego wykonania) .

Pol a wybo ru (CheckBox, RadioButton)


Pola wyboru to kolejne znane elementy interfejsu Windows, ktre mo
na z atwoci stosowa, korzystajc z dostpnych w .NET klas CheckBox
i Rad i o Button. Wybrane waciwoci tych klas przedstawione s w ta
beli 1 0 . 5 .
Aby sprawdzi , czy pole wyboru jest zaznaczone, naley odwoa si
do waciwoci Checked . Ustawiona na true sygnalizuje, e pole jest
zaznaczone, na fa l se, e zaznaczone nie jest. Waciwoci tej mona
rwnie przypisywa wartoci i samemu decydowa o stanie pola.

212

C#

w i cz e n i a

Tabela 10. 5. Wybrane wlaciwoci klas CheckBox i RadioButton


Nazwa
waciwoci

Typ

Znaczenie

AutoCheck

bool

Okrela, czy pole ma by automatycznie


zaznaczane lub odznaczane, kiedy uytkownik
kliknie je mysz.

BackCo l or

Col or

Okrela kolor ta pola.

Bounds

Bounds

Okrela rozmiar oraz pooenie pola.

C h ecked

bool

Pozwala stwierdzi, czy pole jest zaznaczone.

C h eckState

CheckState

Okrela sposb zaznaczania pola.

Cu rsor

Cursor

Rodzaj k ursora wywietlanego, kiedy wskanik


myszy znajdzie si nad polem.

Fl atStyl e

F l atStyl e

Okrela styl, w jakim pole bdzie wywietlane.

Font

Font

Okrela rodzaj czcionki, ktr bdzie wywietlany


tekst znajdujcy si przy polu.

Fo reCo l or

Col or

Okrela kolor tekstu pola.

He1 ght

1 nt

Okrela wysoko pola.

Le ft

1 nt

Okrela pooenie lewego grnego rogu


w poziomie, w pikselach.

Locat1 on

Po1 nt

Okrela wsprzdne lewego grnego rogu pola.

Na me

s t 1 ng

Nazwa pola.

Pa rent

Control

Referencja do obiektu zawierajcego pole

S1 ze

S 1 ze

Okrela wysoko i szeroko pola.

Text

str1 ng

Tekst wywietlany przy polu.

TextA1 1 gn

Con tent
'-+Al 1 gnment

Okrela pooenie tekstu znajdujcego si przy


polu.

Th reeState

bool

Okrela, czy pole ma by dwu- czy trjstanowe.

Top

1 nt

Okrela pooenie pola w pionie, w pikselach.

V1 s 1 bl e

bool

Okrela, czy pole ma by widoczne.

W1 dth

1 nt

Okrela rozmiar pola w poziomie.

R o z d z i a 1 0. Ko m p o n e n t y

213

Wykonajmy proste wiczenie, w ktrym wywietlimy na ekranie


okno zawierajce trzy elementy klasy CheckBox oraz przycisk (rysunek
1 0 .6) . Po klikniciu przycisku pojawi si informacja, ktre pola zo
stay zaznaczone.
WICZENIE

Obsuga pl wyboru typu CheckBox

Umie w oknie trzy obiekty typu CheckBox oraz przycisk. Po klikniciu


przycisku wywietl informacj, ktre opcje zostay zaznaczone .
u s i n g Sy stem :
u s i ng Sy stem . Drawi ng ;
u s i n g Sy stem . W i n dows . Forms ;
publ i c c l a s s Ma i n Form : Form

Button button = new Button ( ) ;


Chec k Box c h b l . chb2 . c hb3 :
publ i c Ma i n Form ( )

th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
th i s . Text = " Pol a wyboru " ;
bu tton . Top = 120 :
bu tton . Left = ( th i s . Cl i en tS i ze . Wi dth - button . W i dth ) I 2 ;
bu tton . Text = " K l i kn i j mn i e l " ;
c h b l = n ew Check Box( ) ;
c h b l . Left = 120 :
c h b l . Top = 20 :
c h b l . Text = "CheckBox n r l " ;
chb2 = n ew Check Box( ) ;
chb2 . Left = 120 :
chb2 . Top = 40 :
chb2 . Text = "CheckBox n r 2" :
c h b3 = n ew Check Box( ) ;
c h b3 . Left = 120 :
c h b3 . Top = 60 :
c h b3 . Text = "CheckBox n r 3" :
EventHandl er eh = n ew EventHandl er ( th i s . Bu ttonC l i cked ) ;
bu tton . C l i c k += eh ;
th i s . Control s . Add( button ) ;
th i s . Control s . Add ( ch b l ) ;

214

C#

w i cz e n i a

th i s . Control s . Add ( chb2 ) :


th i s . Control s . Add ( chb3 ) :

publ i c vo i d Button C l i cked( Obj ect sende r . EventArgs e )

" " s2
s t r i ng s l
i f ( ch b l . Checked )
=

sl

""

s3

"" ;

" 1 ":

i f ( chb2 . Checked )

s2

" 2 ":

i f ( chb3 . Checked )

s3

" 3 ":

Me s s a geBox . Show( " Zo s t a y zaznaczone opcj e : " + s l + s 2 +s 3 ) ;

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) :

Zasada dziaania kodu jest podobna do zasad z wczeniejszych


przykadw. Pola wyboru (c h b l , c h b 2 , c h b3) tworzone s za pomoc
konstruktora klasy CheckBox. Kade z nich otrzymuje przypisany mu
tekst, a take jest pozycjonowane przy uyciu waciwoci Left oraz
Top. Kliknicie przycisku bdzie powodowao wywoanie metody
ButtonCl i c ked . W jej wntrzu badany jest stan waciwoci Checked
obiektw chbl, chb2 i chb3 . Jeli ktra z tych waciwoci ma warto
true, zmieniany jest stan odpowiedniej zmiennej pomocniczej : s l, s2
lub s3. Na kmicu za pomoc metody Show wywietlany jest komuni
kat informacyjny zoony ze staego tekstu poczonego z cigami
zapisanymi w wymienionych zmiennych. Przykadowy efekt dziaania
aplikacji zosta przedstawiony na rysunku 1 0 . 6 .

Druga z omawianych klas, Rad i oButton, ma dziaanie podobne do kla


sy CheckBox, jednak wywietlane pola nie s prostoktne, ale okrge .
Dodatkow rnic jest to, e omawiane pola s polami wykluczaj
cymi, czyli w jednej grupie moe by zaznaczone tylko jedno z nich .

215

R o z d z i a 1 0. Ko m p o n e n t y
Rysunek 1 0. 6.

wiczenie

ii'51 P o l a wyb o ru

obrazujce
wykorzystanie
pl wyboru typ u
CheckBox

r Oh:eclkBox: n r 1
r Oh:eclkBox: n r 2
r Oh:eclkBox: rr r 3

I Kl i kn ij mnie! I
WICZENIE

Obsuga pl wyboru typu radio

Umie w oknie trzy obiekty klasy Rad i o Button oraz przycisk. Po klikni
ciu przycisku wywietl informacj, ktra z opcji zostaa zaznaczona .
u s i n g Sy stem ;
u s i ng Sy stem . Drawi ng ;
u s i n g Sy stem . W i n dows . Forms ;
publ i c c l a s s Ma i n Form : Form

Button button = new Button ( ) ;


Radi oButton rbl , rb2 , rb3 ;
publ i c Ma i n Form ( )

th i s . Wi dth = 320 ;
th i s . He i ght = 2 0 0 ;
th i s . Text = " Pol a wyboru " ;
bu tton . Top = 120 ;
bu tton . Left = ( th i s . Cl i en tS i ze . Wi dth - button . W i dth ) I 2 ;
bu tton . Text = " K l i kn i j mn i e l " ;
rb l = new Radi oButton ( ) ;
rb 1 . Left = 120 ;
rb l . Top = 20 ;
rb l . Text = "Opcj a n r 1 " ;
rb2 = new Radi oButton ( ) ;
rb2 . Left = 120 ;
rb2 . Top = 40 ;
rb2 . Text = "Opcj a n r 2" ;
rb3 = new Radi oButton ( ) ;
rb3 . Left = 120 ;

C#

216

w i cz e n i a

rb3 . Top = 60 :
rb3 . Text = "Opcj a n r 3" ;
EventHandl er eh = n ew EventHandl er ( th 1 s . Bu ttonC 1 1 cked ) ;
bu tton . C l 1 c k += eh ;
th 1 s . Control s . Add( button ) :
th 1 s . Control s . Add ( rb l ) ;
th 1 s . Control s . Add( rb2 ) ;
th 1 s . Control s . Add( rb3 ) ;

publ 1 c vo 1 d Button C 1 1 cked( Obj ect sende r . EventArgs e )

s t r 1 ng s l = " " , s 2 = " " , s3 = '"' ;


1 f ( rbl . Checked )

{
}

sl = " 1 " ;

el se 1 f ( rb2 . Checked )

s2 = " 2 " ;

el se 1 f ( rb3 . Checked )

s3 = " 3 " :

Me s s a geBox . Show( " Zazn aczona zosta a opcj a : " + s l + s 2 +s 3 ) ;

publ 1 c stat1 c vo1 d M a 1 n ( )

{
}

Appl 1 ca t 1 on . Run ( new Ma 1 n Form ( ) ) ;

Zasada dziaania programu jest identyczna z zasad z wiczenia


1 0 . 8 . Rnica sprowadza si do zastosowania klasy Rad i o Button za
miast Check Button. Dziki temu powstan pola typu radio, z ktrych
w jednym czasie aktywne (zaznaczone) bdzie mogo by tylko jedno.
Wystpujca w wiczeniu 1 0 . 8 seria instrukcji i f zostaa take zmie
niona na jedn zoon instrukcj i f.el s e .

R o z d z i a 1 0. Ko m p o n e n t y

217

Listy rozwija ne (Com boBox)


Listy rozwijane (rozwijalne) mona tworzy przy uyciu klasy ComboBox.
Udostpniane przez ni waciwoci przedstawione s w tabeli 1 0 . 6 .
Najwaniejsza z nich jest waciwo Items , jako e zawiera wszyst
kie elementy znajdujce si na licie. Waciwo ta jest w rzeczywisto
ci kolekcj elementw typu obj ect . Dodawanie elementw mona
zrealizowa, stosujc konstrukcj :
ComboBox . I tems . Add ( " e 7 emen t" ) ;

Natomiast ich usunicie spowodujemy, wykorzystujc :


ComboBox . I tems . Remove ( "e 7 emen t " ) ;

Tabela 10. 6. Wybrane waciwoci klasy ComboBox


Typ

Nazwa waciwoci

Znaczenie

Co l o r

BackCo l or

Okrela kolor ta listy.

Bounds

Bounds

Okrela rozmiar oraz pooenie listy.

Cu rsor

Cursor

Okrela rodzaj kursora


wywietlanego, kiedy wskanik
myszy znajdzie si nad list.

Font

Font

Okrela rodzaj czcionki, ktr


bdzie wywietlany tekst
znajdujcy si na licie.

Co l o r

ForeCol or

Okrela kolor tekstu.

1 nt

He1 ght

Okrela wysoko listy.

1 nt

I temHe 1 ght

Okrela wysoko pojedynczego


elementu listy.

Obj ectCol l ect1 on

I tems

Lista elementw znajdujcych si


na licie.

1 nt

Left

Okrela pooenie lewego grnego


rogu w poziomie, w pikselach.

Po 1 nt

Locat1 on

Okrela wsprzdne lewego


grnego rogu listy.

C#

218

w i cz e n i a

Tabela 10. 6. Wybrane wlaciwoci klasy ComboBox - cig dalszy


Ty p

Nazwa waciwoci

Znaczenie

Int

MaxDropDown i tems

Maksymalna liczba elementw,


ktre bd wywietlane po
rozwiniciu listy.

Maxlength

Maksymalna liczba znakw


wywietlanych w polu
edycyjnym listy.

Control

Na me

Nazwa listy.

Pa ren t

Referencja do obiektu
zawierajcego list.

Sel ected i ndex

I ndeks aktualnie zaznaczonego


elementu.

obj ect

Sel ected i tem

Aktualnie zaznaczony element.


Okrela wysoko i szeroko listy.

bool

Sorted

Okrela, czy elementy listy maj


by posortowane.

Text

Tekst wywietlany w polu


edycyjnym listy.

Top

Okrela pooenie lewego grnego


rogu w pionie, w pikselach.

bool

Vi s i b l e

Okrela, czy lista ma by widoczna.

Wi dth

Okrela rozmiar listy w poziomie.

Jeeli chcemy doda wiksz liczb elementw jednoczenie, najwy


godniej zastosowa metod AddRange w postaci :
ComboBox . I tems . AddRa nge
(
new[ J obj ect

):

" E l ement 1"


" E l ement 2"
// .
" E l ement N"

R o z d z i a 1 0. Ko m p o n e n t y

219

Wybranie przez uytkownika elementu z listy mona wykry poprzez


oprogramowanie zdarzenia o nazwie Sel ected i ndexChanged . Odniesie
nie do wybranego elementu znajdziemy natomiast we waciwoci
Sel ected ltem .
WICZENIE

Sposb uycia listy rozwijalnej

Umie w oknie aplikacji element ComboBox (rysunek 1 0 . 7 ) . Po wybraniu


pozycji z listy wywietl jej nazw w oknie dialogowym.
u s i n g Sy stem :
u s i ng Sy stem . Drawi ng ;
u s i n g Sy stem . W i n dows . Forms ;
publ i c c l a s s Ma i n Form : Form

ComboBox cb = new ComboBox( ) ;


publ i c Ma i n Form ( )

th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
th i s . Text = " L i sta rozwi j an a " ;
cb . I tems . AddRange
(
new obj ect [ J

" C# . Praktyczny k u r s " ,


" J a va . Praktyczny k u r s " ,
" J a vaSc r i pt . P r a k tyczny k u r s " ,
"Tworzn i e st ron WWW . Praktyczny k u rs " ,
" PHP5 . Praktyczny k u r s " }

);
cb . Wi dth = 200 ;
cb . Left = ( th i s . Cl i entSi ze . Wi dth - cb . W i dt h ) I 2 ;
cb . Top = ( th i s . C l i entSi ze . Hei ght - cb . Hei ght ) I 2 ;
EventHandl er eh = n ew EventHandl er ( th i s . On Se l ecti on ) ;
cb . Sel ected i n dexChanged += eh :
th i s . Control s . Add ( cb ) ;
}
publ i c vo i d OnSel ecti on ( Obj ect sende r . EventArgs e )

s t r i ng s = ( ( ComboBox) sende r ) . Sel ected i tem . ToStr i n g ( ) ;


Me s s ageBox . Show( "Wyb rano el ement : " + s ) :

}
publ i c stati c voi d M a i n ( )

C#

220

{
}

w i cz e n i a

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Rysunek 1 0. 7.

Element ComboBox
utworzony
w wiczeniu 1 0. 1 0

i;i...

L i sta rozwij a n a
----

G:Jl @) I

ar Pre
JavaScript. Prcktyczny kurs
Tworznie stron 1l1Nl/'W. Prarczny kurs
P H P 5. Pra rcz kurs

Lista rozwijana jest reprezentowana przez pole cb typu ComboBox. Po


zycje listy dodawane s za pomoc metody AddRange waciwoci
Items . Argumentem metody jest nowo utworzona tablica zawierajca
poszczeglne cigi znakw skadajce si na tytuy kilku ksiek z serii
Praktyczny kurs. Aby moliwa bya reakcja na wybr elementu listy,
zdarzenie Sel ected i ndexC ha nged wizane jest z procedur obsugi, ktr
jest metoda OnSe l ect i on klasy Ma i nF o rm . Zastosowana zostaa nieuy
wana do tej pory metoda dotarcia do obiektu wywoujcego zdarze
nie - stosowany jest argument s ender metody . Konieczne byo przy
tym rzutowanie na typ ComboBox ( ( ( ComboBox ) s ender ) ) , bo typem for
malnym argumentu jest obj ect . Wybrana przez uytkownika pozycja
listy jest uzyskiwana przez odwoanie si do waciwoci Sel ected ltem,
a zawarty w niej tekst - przez wywoanie metody ToStri ng .

Listy zwyke (ListBox)


Obsuga zwykych list jest bardzo podobna do obsugi elementw
Combo Box. Do dyspozycji jest jednak kilka dodatkowych waciwoci,
ktre pozwalaj na obsug sytuacji, kiedy na licie znajdzie si
wiele zaznaczonych elementw. Te dodatkowe waciwoci przed
stawione s w tabeli 1 0 . 7 .

221

R o z d z i a 1 0. Ko m p o n e n t y

Tabela 10. 7. Wybrane wlaciwoci klasy ListBox


Nazwa waciwoci

Typ

Znaczenie

Mu l t 1 Col umn

bool

Okrela, czy elementy listy

mog by wywietlane
w wielu kolumnach.

Scrol l Al waysV 1 s 1 b l e

bool

Okrela, czy pasek


przewijania ma by stale
widoczny.

Sel ected i nd 1 ces

Sel ected i ndexCo l l ect1 on

Lista zawierajca indeksy


wszystkich zaznaczonych
elementw.

Sel ected i tems

Sel ectedObj ectCol l ect1 on

Lista zawierajca
wszystkie zaznaczone
elementy.

Sel ect1 onMode

Sel ect1 onMode

Okrela sposb, w jaki


bd zaznaczane
elementy listy.

Podstawow rnic w stosunku do listy ComboBox, oprcz metody


wywietlania, jest - oczywicie - moliwo zaznaczania wicej
ni jednego elementu. Sposb, w jaki elementy bd zaznaczane,
mona kontrolowa za pomoc waciwoci Sel ecti onMode, ktrej przy
pisuje si nastpujce wartoci:
D

Mul t i S i mpl e - moe by zaznaczonych wiele elementw,

Mul ti Extended - moe by zaznaczonych wiele elementw,


do zaznaczania mona uywa klawiszy Shift, Ctrl i klawiszy
kursora,

One - tylko jeden element moe by zaznaczony,

None - elementy nie mog by zaznaczane .

Dostp do zaznaczonych elementw uzyskuje si dziki waciwociom


Se l ected Ind i ces , ktra zawiera indeksy wszystkich zaznaczonych ele
mentw, oraz Se l ected I tems, zawierajcej list zaznaczonych elementw.
Naley zwrci uwag, e jeeli lista pracuje w trybie Mul t i S i mpl e lub
Mul ti Extended, waciwoci Sel ected l ndex (indeks wybranego elemen
tu) i Sel ected ltem (wybrany element) bd wskazyway dowolny z za
znaczonych elementw.

222

C#

w i cz e n i a

b
ll1l-L-is-ta w-ie_l_ok_r_ot_n_e-go w-y-_o r_u
WICZENIE

Umie w oknie aplikacji list L i stBox zawierajc klika elementw


oraz przycisk (rysunek 1 0 .8) . Po klikniciu przycisku wywietl nazwy
elementw, ktre zostay zaznaczone .
u s i n g Sy stem :
u s i ng Sy stem . Drawi ng :
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

L i stBox l b = n ew L i stBox( ) :
Button button = new Button ( ) :
publ i c Ma i n Form ( )

th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
th i s . Text = " L i sta e l emen tw" :
bu tton . Top = 140 :
bu tton . Left = ( th i s . Cl i en tS i ze . Wi dth - button . W i dth ) I 2 :
bu tton . Text = " K l i kn i j mn i e l " ;
l b . I tems . AddRange
(
new obj ect [ J

" J a va . wi czen i a praktyczne " .


" J a vaSc r i pt . wi czen i a praktyczne " .
"SQL . wi czen i a praktyczn e " .
"Aj ax i PHP . wi czen i a praktyczne " .
"J ooml a ! 1 . 6 . wi czen i a "

);
l b . Wi dth = 200 ;
l b . Left = ( th i s . Cl i entSi ze . Wi dth - l b . W i dt h ) I 2 :
l b . Top = ( th i s . C l i entSi ze . Hei ght - l b . He i ght ) I 2 ;
l b . Sel ecti on Mode = Sel ecti onMode . M u l ti Extended :
EventHandl er eh = n ew EventHandl er ( th i s . On ButtonCl i c k ) ;
bu tton . C l i c k += eh :
th i s . Control s . Add( l b ) :
th i s . Control s . Add ( button ) :

publ i c vo i d OnButtonCl i ck ( Object sende r . EventArgs e )

223

R o z d z i a 1 0. Ko m p o n e n t y
s t r 1 ng str = " " :
fo reach ( st r 1 ng n ame 1 n l b . Sel ected l tem s )

str += " " + n ame + " \ n " :

Me s s a geBox . Show( " Zazn aczone e l ementy : \ n " + s tr ) :

publ 1 c stat1 c vo1 d M a 1 n ( )

{
}

Appl 1 ca t 1 on . Run ( new Ma 1 n Form ( ) ) ;

Lista tworzona jest na takiej samej zasadzie jak w wiczeniu 1 0 . 1 0 jedynie zamiast klasy ComboBox zostaa uyta L i stBox. Dodatkowo w oknie
zosta rwnie umieszczony przycisk typu Butto n (wygld aplikacji
mona zobaczy na rysunku 10 .8) . Lista jest reprezentowana przez
pole l b. Aby moliwe byo zaznaczanie wielu elementw, waci
wo Sel ecti onMode otrzymaa warto Sel ecti onMod e . Mul ti Extended .
Kliknicie przycisku button bdzie powodowao wywoanie metody
On ButtonCl i c k . W jej wntrzu znajduje si ptla fo reach odczytujca
wszystkie elementy waciwoci Sel eted ltems listy l b. Kady taki ele
ment odpowiada pojedynczej zaznaczonej pozycji. Wewntrz ptli kon
struowany jest cig znakw str skadajcy si z zaznaczonych pozycji
(elementw kolekcji Se l ected I tems) . Po zakoi1czeniu ptli cig zapisany
w str jest wywietlany na ekranie w osobnym oknie dialogowym.
Rysunek 1 0. 8.

Lista pracujca
w tiybie
MultiExtended
z wiczenia 1 0. 1 1

ii...,

L i sta elem entw

1
---- @1 1

Kli knij 11 11ie!

224

C#

w i cz e n i a

Menu
Czym s menu, z pewnoci nie trzeba nikomu przypomina . Czas
zatem nauczy si, w jaki sposb skorzysta z tych poytecznych
elementw interfejsu w C# na platformie .NET. Do dyspozycji s za
rwno menu gwne, jak i menu kontekstowe . Do ich tworzenia su
klasy Mai nMenu, ContextMenu oraz Menultem. Wszystkie znajduj si w prze
strzeni nazw Wi ndows . System . Fo rms .

Menu gwne
Aby doda do aplikacji menu gwne, trzeba wykona kilka czynnoci.
Przede wszystkim naley utworzy obiekt klasy Ma i nMenu i przypisa
go waciwoci Menu obiektu klasy Form. W ten sposb do aplikacji zosta
nie dodane menu gwne , ktre jednak nie bdzie zawierao adnej
pozycji. W celu utworzenia pozycji budujemy obiekt klasy Men u l tem
i dodajemy go do menu gwnego za pomoc metody Add . Schemat
postpowania jest zatem nastpujcy:
Ma i nMenu ob i ekt menu = new M a i nMen u ( ) :
Men u l tem ob i ekt_pozycj i = n ew Men u l tem ( ) :
ob i ek t_menu . Menu l tems . Acid ( ob i ekt_pozycj i ) :

Po wykonaniu tych instrukcji wystarczy tylko przypisa utworzonej


pozycji tekst, jaki ma si na niej pojawia, np . Plik. Sposb wykona
nia tego zadania jest wyjtkowo prosty. Wystarczy waciwoci Text
obiektu klasy Menultem przypisa odpowiedni cig znakw. W omawia
nym przykadzie naleaoby uy instrukcji:
ob iekt_pozycj i . Text = " Pl i k " :

WICZENIE

Dodanie do aplikacji menu gwnego

Napisz aplikacj wywietlajc okno zawierajce menu gwne z po


zycj Plik, co jest widoczne na rysunku 1 0 . 9 .
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms ;
publ i c c l a s s Ma i n Form : Form

R o z d z i a 1 0. Ko m p o n e n t y

225

M a i n Menu mai nMenu = n ew M a i nMen u ( ) :


Men u l tem men u l teml = new Men u l tem ( ) ;
publ i c Ma i n Form ( )

th i s . Text = "Okno z men u " :


th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
men u l tem l . Text = " Pl i k " :
ma i nMen u . Men u i tems . Add ( men u i tem l ) :
th i s . Menu = m a i n Men u :

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Rysunek 1 0. 9.

Aplikacja zawierajca
menu glwne

D_.

Okno z menu

,[ P Tik l

Sposb postpowania jest zgodny z podanym wyej opisem. Menu


gwne reprezentuje obiekt ma i nMenu (utworzony za pomoc kon
struktora klasy Mai nMenu) , natomiast pozycj menu - obiekt men ul teml
(ktry powsta przy uyciu konstruktora klasy Men u l tem) . Pozycja me
nu jest dodawana do menu przez wywoanie metody Add . Menu jest
z kolei umieszczane w oknie aplikacji przez przypisanie obiektu
ma i nMenu waciwoci Menu (t waciwo zawiera obiekt reprezentujcy
okno aplikacji; obiekt klasy M a i n F o rm reprezentowany przez wska
zanie th i s) .

Do menu Plik powstaego w wiczeniu 1 0 . 1 2 naleaoby doda ko


lejn pozycj - niech to bdzie Zamknij - bdzie mona wtedy
wykorzysta j do kol1czenia pracy z aplikacj. Sposb postpowania

C#

226

w i cz e n i a

jest tu taki sam jak w przypadku menu gwnego . Trzeba utworzy


nowy obiekt klasy Men u l tem oraz skorzysta z metody Add waciwoci
Men u l tems . Jak to wyglda w praktyce, pokazano w wiczeniu 1 0 . 1 3 .
WICZENIE

Dodawanie pozycji do menu

Do menu otrzymanego w wiczeniu 1 0 . 1 2 dodaj pozycj o nazwie


Zamknij, co widoczne jest na rysunku 1 0 . 1 0 .
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

M a i n Menu mai nMenu = n ew M a i nMen u ( ) :


Men u l tem men u l teml = new Men u l tem ( ) :
Men u l tem men u l tem2 = new Men u l tem ( ) :
publ i c Ma i n Form ( )

th i s . Text = "Okno z men u " :


th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
men u l tem l . Text = " Pl i k " :
men u l tem2 . Text = " Zamkni j " :
ma i nMen u . Men u i tems . Add ( men u i tem l ) :
men u l tem l . Men u l tems . Add ( men u l tem2 ) :
th i s . Menu = m a i n Men u :

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Rysunek 1 0. 10.

Aplikacja ma teraz
dodatkowe podmenu

G:JI @) I

aEJ O kn o z menu

[Plikl
I_

Zamknij

R o z d z i a 1 0. Ko m p o n e n t y

227

Struktura programu pozostaa taka sama jak w wiczeniu 1 0 . 1 2 . Dodana


zostaa jedynie nowa pozycja menu odzwierciedlana przez menu l tem2 .
Obiekt ten zosta dodany do pozycji Zamknij (reprezentowanej przez
obiekt men u l teml) za pomoc wywoania metody Add (udostpnianej
przez waciwo Menul tems ) .

Nazwy poszczeglnym menu mona nadawa rwnie bezporednio


w konstruktorze klasy Men u l tem . Pozwala to na zaoszczdzenie pew
nej iloci miejsca w kodzie programu . dany cig znakw trzeba
poda jako argument konstruktora, schematycznie :
Men u l tem ob i ekt_pozycj i = n ew Men u l tem ( "nazwa_pozycj i " ) :

WICZENIE

Bezporednie nadawanie nazw menu

Utwrz menu, tak jak w wiczeniu 1 0 . 1 3 . Skorzystaj z metody bez


poredniego nadawania nazw pozycjom.
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

M a i n Menu mai nMenu = n ew M a i nMen u ( ) :


Men u l tem men u l teml = new Menu l tem ( " P l i k " ) :
Men u I tem men u I tem2 = new Menu I tem ( " Zamkn i j " ) :
publ i c Ma i n Form ( )

th i s . Text = "Okno z men u " :


th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
ma i nMen u . Men u i tems . Add ( men u i tem l ) :
men u i tem l . Men u i tems . Add ( men u i tem2 ) :
th i s . Menu = m a i n Men u :

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) :

C#

228

w i cz e n i a

Oprcz opisanych wyej , istnieje jeszcze jedna moliwo tworzenia


podmenu - nie trzeba bezporednio tworzy obiektw Men u ltem .
Zrobi to za nas rwnie dobrze metoda Add, zastosowana do waci
woci Men u l tems 1 Zamiast pisa :
Menu I tem ob i ekt_pozycj i = n ew Men u I tem ( "nazwa " ) :
ob i ek t_menu . Menu l tems . Add ( ob i ekt_pozycj i ) :

mona zastosowa konstrukcj :


Men u l tem men u l tem l = ob i ekt menu . Men u l tems . Add ( "nazwa " ) ;

Co prawda, tak utworzonego obiektu (referencji do obiektu) nie trze


ba koniecznie przypisywa zmiennej (w tym przypadku menu l teml),
jednak lepiej to zrobi . Dziki temu bdzie mona odwoywa si do
niego w dalszej czci kodu.
WICZENIE

Bezporednie tworzenie pozycji menu

Utwrz pozycj menu, tak jak w wiczeniu 1 0 . 1 3 . Skorzystaj z nowej


metody dodawania podmenu.
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

M a i n Menu mai nMenu = n ew M a i nMen u ( ) :


Men u l tem men u l teml :
Men u l tem men u l tem2 :
publ i c Ma i n Form ( )

th i s . Text = "Okno z men u " :


th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
men u l teml = m a i n Menu . Menu i tems . Add ( " Pl i k " ) :
men u l tem2 = men u l tem l . Men u l tems . Add ( " Zamkn i j " ) :
th i s . Menu = m a i n Men u :

1 W rzeczywistoci Menu I tems to wskazanie na obiekt klasy zagniedonej

Menu . Men u i temCo l l ect i on . Dopiero ta klasa zawiera zestaw przecionych


metod Add. Blisze informacje mona znale w dokumentacji .NET SDK
oraz Visual C#.

R o z d z i a 1 0. Ko m p o n e n t y

229

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Utworzone w poprzednim wiczeniu menu jest - niestety - nieak


tywne, tzn. po jego wybraniu nic si nie dzieje. Z pewnoci nie jest
to wielkim zaskoczeniem, nie powstay przecie jeszcze odpowied
nie procedury obsugi. Po lekturze rozdziau 9 . atwo si domyli,
e trzeba bdzie skorzysta ze zdarze oraz delegacji EventHandl er.
Naley zatem zdefiniowa metod obsugujc zdarzenie . Deklaracja tej
metody musi by zgodna z delegacj EventHandl er, ktra ma posta :
publ i c del egate voi d EventHandl er ( object s en de r . EventArgs a rgs ) ;

Parametry sender i a rgs nie musz by uywane . Przykadowo metoda,


ktrej zadaniem byoby reagowanie na wybranie z menu pozycji Zamkni j,
mogaby wyglda nastpujco :
publ i c voi d Zamkn i j C l i cked ( Obj ect sender . Even tArgs e )

t h i s . Cl o s e ( ) ;

}
Pozostaje zatem powizanie takiej metody ze zdarzeniem polegajcym
na wybraniu pozycji Zamkni j . Naley utworzy delegacj typu Event
4-Handl e r i przekaza jej w postaci argumentu metod Zamkni jCl i cked :
EventHandl er eh = new EventHa n d l e r ( Zamkn i j C l i c ked ) ;

Po takiej deklaracji wie si delegacj z konkretn pozycj w menu,


piszc :
Men u l tems . Add ( " Zamkn i j " . eh ) ;

WICZENIE

Aktywacja menu

Uzupenij kod z wiczenia 1 0 . 1 5 w taki sposb , aby po wybraniu


z menu Pl i k pozycji Zamk n i j nastpowao wyjcie z aplikacji.
u s i n g Sy stem ;
u s i n g Sy stem . W i n dows . Forms ;
publ i c c l a s s Ma i n Form : Form

C#

230

w i cz e n i a

M a i n Menu mai nMenu = n ew M a i nMen u ( ) :


Men u l tem men u l teml :
Men u l tem men u l tem2 :
publ i c Ma i n Form ( )

th i s . Text = "Okno z men u " :


th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
men u l teml = m a i n Menu . Menu i tems . Add ( " Pl i k " ) :
EventHandl er eh = n ew EventHandl er ( th i s . Cl oseCl i cked ) :
men u l tem2 = men u l tem l . Men u l tems . Add ( " Zamkn i j " , eh ) :
th i s . Menu = m a i n Men u :

publ i c vo i d C l oseC l i cked ( Obj ect sender . Even tArgs e )

th i s . C l o s e ( ) :

publ i c stati c voi d M a i n ( )

{
}

WICZENIE
1 0. 1 7

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Obsuga zdarze powizanych z menu

Napisz aplikacj zawierajc kilka pozycji w menu gwnym . Po


wybraniu dowolnej pozycji z menu wywietl jej nazw , korzystajc
z metody Show klasy MessageBox.
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

M a i n Menu mai nMenu = n ew M a i nMen u ( ) :


Men u l tem men u l teml :
Men u l tem men u l tem2 :
Men u l tem men u l tem3 :
Men u l tem men u lSub i tem l :
Men u l tem men u 1Sub l tem2 :
Men u l tem men u 2Sub l tem l :
Men u l tem men u3Sub l tem l :
Men u l tem men u3Sub l tem2 :
Men u l tem men u3Sub l tem3 :
publ i c Ma i n Form ( )

R o z d z i a 1 0. Ko m p o n e n t y

231

th i s . Text = "Okno z men u " :


th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
men u l teml = m a i n Menu . Menu i tems . Add ( " Pozycj a 1 " ) ;
men u l tem2 = m a i n Menu . Menu i tems . Add ( " Pozycj a 2" ) ;
men u l tem3 = m a i n Menu . Menu i tems . Add ( " Pozycj a 3" ) ;
EventHandl er eh = n ew EventHandl er ( th i s . Menu i temCl i c ked ) ;
men u lSub i teml = men u l teml . Men u l tem s . Add ( " Podpozycj a l " , eh ) ;
men u 1S u b l tem2 = men u l teml . Men u l tem s . Add ( " Podpozycj a 2 " , eh ) ;
men u2Sub l teml = men u i tem2 . Men u i tem s . Add ( " Podpozycj a l " , eh ) ;
menu3Su b l teml = men u l tem3 . Men u l tem s . Add ( " Podpozycj a l " , eh ) ;
menu3Sub l tem2 = men u i tem3 . Men u i tem s . Add ( " Podpozycj a 2 " , eh ) ;
menu3Sub l tem3 = men u i tem3 . Men u i tem s . Add ( " Podpozycj a 3 " , eh ) ;
th i s . Menu = m a i n Men u ;

publ i c vo i d Men u i temCl i cked ( obj ect s en de r . E ventArgs e )

Me s s a geBox . Show( ( ( Men u i tem ) sender ) . Text ) ;

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Okno tak skonstruowanej aplikacji bdzie miao wygld zaprezento


wany na rysunku 1 0 . 1 1 . Wybranie dowolnej pozycji podmenu spo
woduje wywietlenie jej nazwy w dodatkowym oknie dialogowym
(rysunek 1 0 . 1 2) . Sposb dodawania obsugi zdarze do poszczegl
nych pozycji jest taki sam jak w wiczeniu 1 0 . 1 6 i wczeniej szych
(w kadym przypadku jest to delegacja eh typu EventHandl er powi
zana z metod Men u itemCl i c ked) . Sama procedura obsugi zostaa oczywicie - zmieniona, cho uywane s w niej konstrukcje pre
zentowane ju w poprzednich przykadach. Zastosowana zostaa meto
da Show klasy MessageBox, ktra pozwala na wywietlenie okna dialogo
wego z dowolnie podanym tekstem.

2 32

C#

Rysunek 1 0. 1 1.

11

Struktura menu
utworzona
w wiczeniu 1 0. 1 7

Okno

w i cz e n i a
z

Pozycja 1

menu

Pozycja 3 ]

Pozycja 2

Podpozycja 1
Podpozycja 2

Podpozycja 3

Rysunek 1 0. 12.

11

Wybranie dowolnej
pozycji podmenu
powoduje
wywietlenie
;e; nazwy

Okno z menu

-.!:ozycja 1

GJ[fil[fil

P ==-..

Podpozycja1 3

OK

Chwili uwagi wymaga zastosowany sposb uzyskania nazwy wybra


nego podmenu (jest podobny do przykadu z list rozwijan z wi
czenia 1 0 . 1 0) . Korzystamy tutaj z faktu, e do procedury obsugi zda
rzenia, czyli metody Menui temCl i cked, jest przekazywana referencja do
obiektu, ktry j wywouje . Jest to argument s ender . Rzecz jasna, sko
ro parametr ten jest typu obj ect, naley dokona rzutowania na typ
Men u l tem . Po dokonaniu rzutowania mona bezporednio odwoa si
do waciwoci Text .

Menu ko ntekstowe
Tworzenie menu kontekstowego jest bardzo podobne do budowania
menu gwnego . Struktur definiuje si dokadnie w taki sam sposb .
Rnica jest taka, e zamiast przypisania :
Form . Menu

nasze menu :

jest stosowane przypisanie :


Form . Con textMen u

nasze menu :

oraz zamiast klasy Mai nMenu uywa si klasy ContextMenu.

233

R o z d z i a 1 0. Ko m p o n e n t y

WICZENIE

Dodanie do aplikacji menu kontekstowego

Napisz aplikacj posiadajc menu kontekstowe (rysunek 1 0 . 1 3 ) .


u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

ContextMen u contextMen u = n ew ContextMen u ( ) :


Men u l tem men u l teml :
Men u l tem men u l tem2 :
Men u l tem men u l tem3 :
Men u l tem men u l tem4 :
publ i c Ma i n Form ( )

th i s . Text = "Okno z men u kontek stowym" :


th i s . Wi dth = 320 :
th i s . He i ght
200 :
=

men u l teml
men u l tem2
men u l tem3
men u l tem4

=
=
=
=

contextMenu . Men u i tems . Add ( " Pozycj a


contextMenu . Men u i tems . Add ( " Pozycj a
contextMenu . Men u i tems . Add ( " Pozycj a
contextMenu . Men u i tems . Add ( " Pozycj a

l" )
2" )
3" )
4" )

:
:
:
:

th i s . Con textMen u = contextMen u :

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) :

Obiekt reprezentujcy menu kontekstowe zosta utworzony za po


moc konstruktora klasy ContextMenu i przypisany zmiennej (polu)
contextMenu. Nastpnie za pomoc metody Add kolekcji Menultems po
wstay cztery pozycje menu. Odwoania do nich znalazy si w polach
typu Men u l tem . Zbudowane w ten sposb menu kontekstowe zostao
dodane do okna aplikacji przez przypisanie obiektu contextMenu wa
ciwoci ContextMenu. Wygld tego menu pokazano na rysunku 1 0 . 1 3 .

C#

234
Rysunek 1 0. 13.

Aplikacja
posiadajca
menu kontekstowe

ii...,

Okno

w i cz e n i a
z

menu kontekstowym

P ozycj a 1

P ozycj a 2.
P ozycj a 3

P ozycj a 4

Menu kontekstowe moe mie wiele poziomw, podobnie jak i menu


zwyke . Identyczna jest te zasada tworzenia takiej konstrukcji. Do
istniejcych pozycji naley dodawa kolejne , a do zbudowania po
danej hierarchii. Przykad aplikacji zawierajcej wielopoziomowe
menu kontekstowe zosta przedstawiony w wiczeniu 1 0 . 1 9 .
WICZENIE

Wielopoziomowe menu kontekstowe

Napisz aplikacj posiadajc wielopoziomowe menu kontekstowe


widoczne na rysunku 1 O . 1 4 .
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

ContextMen u contextMen u = n ew ContextMen u ( ) :


Men u l tem men u l teml :
Men u l tem men u l tem2 :
Men u l tem men u l tem3 :
Men u l tem men u l tem4 :
Men u l tem
Men u l tem
Men u l tem
Men u l tem

menu4Sub l tem l :
menu4Sub l tem2 :
men u4Su b l tem3 :
men u4Su b l tem4 :

Men u l tem men u4Su b l tem4Sub l tem l :


publ i c Ma i n Form ( )

th i s . Text = "Okno z men u kontek stowym" :


th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :

235

R o z d z i a 1 0. Ko m p o n e n t y
men u i teml
men u i tem2
men u i tem3
men u i tem4

contextMenu . Men u i tems . Add ( " Pozycj a


contextMenu . Men u i tems . Add ( " Pozycj a
contextMenu . Men u i tems . Add ( " Pozycj a
contextMenu . Men u i tems . Add ( " Pozycj a

men u4Sub l teml


men u4Sub l tem2
men u4Sub l tem3
men u4Sub l tem4

1" ) ;

2" ) ;
3" ) ;
4" ) ;

men u i tem4 . Men u i tem s . Add ( " Podpozycj a


men u i tem4 . Men u i tem s . Add ( " Podpozycj a
men u i tem4 . Men u i tem s . Add ( " Podpozycj a
men u i tem4 . Men u i tem s . Add ( " Podpozycj a

men u4Sub i tem4Sub i tem l


th i s . Con textMen u

1" ) :

2" ) :
3" ) :
4" ) :

menu4Su b i tem4 . Menu i tems . Add ( " Podpozycj a 1 " ) :

contextMen u ;

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Rysunek 1 0. 14.

Aplikacja
z wielopoziomowym
menu kontekstowym

"

Okno

menu kontekstowym

l a l

Pozycja 1
Pozycja 2

Pozycja 3

Podpozycja 1

Pozycja 4

Podpozycja 2

Podpozycja 3

Podpozycja 4

li

Waciwoci Menu
W menu zarwno gwnym, jak i kontekstowym istnieje moliwo
zaznaczania kadej pozycji. Odbywa si to poprzez zmian waci
woci Checked obiektu klasy Men u l tem na true (pozycja zaznaczona)
lub fa l se (pozycja niezaznaczona) .

C#

236

WICZENIE

w i cz e n i a

Menu z moliwoci zaznaczania pozycji

Napisz aplikacj posiadajc menu kontekstowe, w ktrym co druga


pozycja jest zaznaczona (rysunek 1 0 . 1 5 ) .
u s i n g Sy stem . W i n dows . Forms ;
publ i c c l a s s Ma i n Form : Form

ContextMen u contextMen u = n ew ContextMen u ( ) ;


Men u l tem men u l teml :
Men u l tem men u l tem2 :
Men u l tem men u l tem3 :
Men u l tem men u l tem4 :
publ i c Ma i n Form ( )

th i s . Text = "Okno z men u kontek stowym" :


th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
men u l teml = contextMenu . Men u i tems . Add ( " Pozycj a
men u i tem l . C hecked = true :
men u l tem2 = contextMenu . Men u i tems . Add ( " Pozycj a
men u l tem3 = contextMenu . Men u i tems . Add ( " Pozycj a
men u l tem3 . C hecked = true :
men u l tem4 = contextMenu . Men u i tems . Add ( " Pozycj a
th i s . Con textMen u = contextMen u :

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Rysunek 1 0. 15.

Menu kontekstowe
z zaznaczonymi
niektrymi
pozyCJam1

t1SJ Okno z menu kontekstowym


./

P o-zycja 1

./

P ozycja 3

P o,zycja 2
P o,zycja 4

l" ) ;
2" ) ;
3" ) ;
4" ) ;

R o z d z i a 1 0. Ko m p o n e n t y

237

Menu wraz z pozycjami zostao utworzone w taki sam sposb jak


w wiczeniu 1 0 . 1 8 . Pozycje pierwsza (reprezentowana przez obiekt
menulteml) i trzecia (reprezentowana przez obiekt menultem3) zostay za
znaczone przez przypisanie wartoci true waciwoci Checked odpo
wiednich obiektw. Dlatego po uruchomieniu aplikacji i wywoaniu
menu na ekranie pojawi si widok przedstawiony na rysunku 1 0 . 1 5 .

Korzystajc z obsugi zdarze oraz waciwoci Checked, mona utwo


rzy menu, w ktrym stan pozycji bdzie si zmienia dynamicznie .
Znaczy to, e kiedy uytkownik pierwszy raz wybierze dan pozycj,
zostanie ona zaznaczona, kolejne wybranie teje pozycji spowoduje
usunicie jej zaznaczenia itd. Taki sposb obsugi czsto spotykamy
w aplikacjach, warto wic przewiczy jego wykonanie .

----,
_
_
_
_
_
_
_
_
_
_
_
_
_
_
_
_
_
_
_
_
w
.
l
_
ll1fl_Me n u z m oz i o ci q zm ia n y zazna czen
WICZENIE

Utwrz menu gwne, ktrego stan poszczeglnych pozycji bdzie


si zmienia po kadym wybraniu danej pozycji.
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

M a i n Menu
Men u l tem
Men u l tem
Men u l tem
Men u l tem
Men u l tem

mai nMenu = n ew M a i nMen u ( ) :


men u l teml :
men uSub i teml :
men uSub i tem2 :
men uSub i tem3 :
men uSub i tem4 :

publ i c Ma i n Form ( )

th i s . Text = "Okno z men u " :


th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
EventHandl er eh = n ew EventHandl er ( th i s . Menu i temCl i c ked ) :
men u l teml = m a i n Men u . Men u i tems . Add ( " Menu l " ) :
menuSub i tem l = men u l tem l . Men u l tems . Add ( " Pozycj a l " , eh ) :
menuSub i tem2 = men u l tem l . Men u l tems . Add ( " Pozycj a 2 " , eh ) :
menuSub i tem3 = men u l tem l . Men u l tems . Add ( " Pozycj a 3 " , eh ) :

C#

238
menuSub I tem4
th i s . Menu

w i cz e n i a

menu I tem l . Men u I tems . Add ( " Pozycj a 4 " . eh ) :

m a i n Men u ;

publ i c vo i d Men u i temCl i cked ( Obj ect s en de r . E ventArgs e )

( ( Menu i tem ) sende r ) . C hecked

l ( ( Men u i tem ) s ender ) . Checked ;

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Delegacji eh zosta przypisany nowy obiekt typu EventHandl er powi


zany z metod Men u i temCl i cked . Nastpnie zosta on uyty w instruk
cjach tworzcych pozycje men u . W zwizku z tym wybranie dowolnej
pozycji bdzie powodowao wywoanie wspominanej metody. W jej
wntrzu warto waciwoci Checked danej pozycji jest po prostu
zmieniana na przeciwn, czyli jeli waciwo bya rwna fa l se,
bdzie rwna true, jeli natomiast bya rwna true, bdzie rwna
fa l s e . Jest to wykonywane w instrukcji:
( ( Men u i tem ) sender ) . C hecked

l ( ( Menu i tem ) sende r ) . C hecked :

Tym samym wskazanie niezaznaczonej pozycji menu spowoduje jej


zaznaczenie i odwrotnie, wskazanie zaznaczonej pozycji spowoduje
. .
.
usun1c1e zaznaczenia .

Oprcz standardowego sposobu zaznaczenia pozycji, ktry zosta uyty


w wiczeniu 1 0 . 20, istnieje take inny. Jeli waciwoci Rad i oCheck
obiektu klasy Men u l tem przypiszemy warto true, po nadaniu wa
ciwoci Checked rwnie wartoci true, menu bd zaznaczane za
pomoc symbolu kropki (kka) .
WICZENIE

Alternatywny sposb zaznaczania pozycji menu

Zmodyfikuj kod z wiczenia 1 0 . 2 1 w taki sposb , aby wtedy, gdy ak


tywna jest pierwsza pozycja menu (Pozycja 1), pozostae byy zazna
czane przez symbol kropki (rysunek 1 0 . 1 6 ) , a kiedy jest nieaktywna
- przez symbol domylny.

239

R o z d z i a 1 0. Ko m p o n e n t y
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms ;
publ i c c l a s s Ma i n Form : Form

M a i n Menu
Men u l tem
Men u l tem
Men u l tem
Men u l tem
Men u l tem

mai nMenu = n ew M a i nMen u ( ) ;


men u l teml :
men uSub i teml :
men uSub i tem2 :
men uSub i tem3 :
men uSub i tem4 :

publ i c Ma i n Form ( )

th i s . Text = "Okno z men u " ;


th i s . Wi dth = 320 ;
th i s . He i ght = 2 0 0 :
EventHandl er eh = n ew EventHandl er ( th i s . Menu i temCl i c ked ) ;
men u l teml = m a i n Men u . Men u i tems . Add ( " Menu l " ) ;
menuSub i tem l = men u i tem l . Men u i tems . Add ( " Pozycj a
menuSub i tem2 = men u l tem l . Men u I tems . Add ( " Pozycj a
menuSub i tem3 = men u l tem l . Men u i tems . Add ( " Pozycj a
menuSub i tem4 = men u l tem l . Men u i tems . Add ( " Pozycj a

l" ,
2" ,
3" ,
4" ,

eh )
eh )
eh )
eh )

;
:
:
:

menuSub i tem l . Radi oCheck = fa l se :


th i s . Menu = m a i n Men u ;

publ i c vo i d Men u i temCl i cked ( Obj ect s en de r . E ventArgs e )

( ( Menu l tem ) sende r ) . C hecked = 1 ( ( Men u l tem ) s ender ) . Checked ;


i f ( sender == men uSub i teml )

i f( ( ( Men u l tem ) sender ) . C hecked )

men uSub i tem2 . Ra d i oCheck = true ;


men uSub i tem3 . Ra d i oCheck = true ;
men uSub i tem4 . Ra d i oCheck = true ;

el se

men uSub i tem2 . Ra d i oCheck = fa l s e ;


men uSub i tem3 . Ra d i oCheck = fa l s e ;
men uSub i tem4 . Ra d i oCheck = fa l s e ;

publ i c stati c voi d M a i n ( )

C#

240

{
}

w i cz e n i a

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Rysunek 1 0. 16.

Elementy menu
zaznaczane
za pomocq
symbolu kropki

Il_,

Okno z menu

Menl!J l ]
./

P nycj a 1
P ozycj a 2

Ciii
Ciii

P ozycj a 3
P ozycj a 4

Rnica w stosunku do przykadu z wiczenia 1 0 . 2 1 sprowadza si


przede wszystkim do modyfikacji metody Men u i temCl i cked . Instrukcja
zmieniajca stan pozycji menu pozostaa - co prawda - niezmie
niona, za ni jednak pojawiy zagniedone instrukcje warunkowe .
Badane jest, czy inicjatorem zdarzenia (argument sender) jest obiekt
pierwszej pozycji menu (men uSubi teml), mwic prociej - czy wy
brana zostaa pierwsza pozycja menu. Jeli zostaa wybrana, dalsze
postpowanie zaley od tego, czy ta pozycja jest zaznaczona (jej war
to Checked jest rwna true) . Gdy jest zaznaczona, waciwoci Ra
di oCheck pozostaych pozycji s zaznaczane (otrzymuj warto true) ,
w przeciwnym przypadku ich zaznaczenia s usuwane (waciwoci
Rad i oCheck otrzymuj warto fa l s e) .

Skrty kl owi atu ro we


Dostp do menu moe by zrealizowany przy uyciu skrtw klawiatu
rowych z klawiszem Alt. Wiele aplikacji udostpnia ten praktyczny
sposb, ktry, na szczcie, jest bardzo prosty do realizacji. Wystar
czy, e podczas tworzenia pozycji menu liter, ktra bdzie uywana
do aktywacji tej pozycji, poprzedzi si znakiem & . To cae zadanie .

R o z d z i a 1 0. Ko m p o n e n t y

WICZENIE

241

Dostp do menu za pomoc skrtw klawiaturowych

Napisz aplikacj zawierajc menu Plik, gdzie bdzie znajdowa si


pozycja Zamknij, ktrej wybranie spowoduje zamknicie programu .
Menu powinno by dostpne poprzez skrty klawiaturowe z klawi
szem Alt.
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

M a i n Menu mai nMenu = n ew M a i nMen u ( ) :


Men u l tem men u l teml :
Men u l tem men u l tem2 :
publ i c Ma i n Form ( )

th i s . Text = "Okno z men u " :


th i s . Wi dth
320 :
th i s . He i ght
200 :
=

men u l teml
m a i n Menu . Menu i tems . Add ( "&P l i k " ) :
EventHandl er eh = n ew EventHandl er ( th i s . Zamkn i j C l i cked ) ;
men u l tem2
men u l tem l . Men u l tems . Ad d ( "&Zamkn i j " , eh ) ;
th i s . Menu
m a i n Men u :
=

publ i c vo i d Zamkn i j C l i cked ( Obj ect sender . EventArgs e )

th i s . C l o s e ( ) ;

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) :

Na rysunku 1 0 . 1 7 wida , e dostp do menu moe by realizowany


poprzez nacinicie klawisza Alt i wybranej litery. Aktywne znaki s
podkrelone . Warto jednak zwrci uwag, e przy tym sposobie re
alizacji (tzn. aktywowania menu klawiszem Alt) nie mona dosta si
bezporednio do danej pozycji. W powyszym przypadku, aby wy
bra pozycj Close, naleaoby najpierw wcisn klawisz Alt i, przy
trzymujc go, nacisn kolejno P i Z.

2 42

C#

Rysunek 1 0. 1 7.

Menu dostpne
poprzez skrty
klawiszowe
z klawiszem Alt

w i cz e n i a

1iSJ Okno z menu


:la mknij

Moemy jednak skorzysta z bezporednich skrtw klawiaturo


wych z klawiszem Control. Skoro na co dzie uywamy takich kom
binacji jak Ctrl+C, Ctrl+ V czy Ctrl+X, nie ma powodu, aby nie wy
posaa aplikacji pisanych w C# w takie wanie udogodnienia.
Powizanie menu ze skrtem klawiaturowym bdzie wygldao zu
penie inaczej ni w poprzednim wiczeniu. Do dyspozycji s dwa
sposoby: albo przypisanie skrtu do menu ju podczas tworzenia kon
kretnej pozycji, albo najpierw utworzenie danej pozycji, a nastpnie
zmodyfikowanie jej waciwoci S h o rtCut . Oba sposoby zostan
sprawdzone w kolejnych dwch wiczeniach.
Najpierw przypiszemy odpowiedni skrt ju podczas tworzenia po
zycji. Wymaga to uycia trjargumentowego konstruktora w postaci:
publ i c Men u i tem
(
s t r i ng text .
Even tHan d l er eh .
Shortcut shortcut

Jak wida, w tym przypadku niezbdne bdzie jednoczesne przypisanie


obsugi zdarzenia. Skrt definiowany jest za pomoc wyliczenia Short
4CUt, np . dla kombinacji Ctrl+ W naley uy wartoci Sho rtcut . Ctrl W.
WICZENIE

Skrty definiowane razem z menu

Napisz aplikacj zawierajc menu Plik, w ktrym bdzie znajdowa


si pozycja Zamknij. Wybranie tej pozycji powinno spowodowa
zamknicie programu. Do pozycji Zamk nij przypisz skrt klawiatu
rowy Ctrl+ W (lub inny) .

243

R o z d z i a 1 0. Ko m p o n e n t y
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms ;
publ i c c l a s s Ma i n Form : Form

M a i n Menu mai nMenu = n ew M a i nMen u ( ) ;


Men u l tem men u l teml :
Men u l tem men u l tem2 :
publ i c Ma i n Form ( )

th i s . Text = "Okno z men u " ;


th i s . Wi dth = 320 ;
th i s . He i ght = 2 0 0 :
men u l teml = m a i n Menu . Menu i tems . Add ( "&P l i k " ) ;
EventHandl er eh = n ew EventHandl er ( th i s . Zamkn i j C l i cked ) ;
men u l tem2 = new Men u l tem ( "&Zamkn i j " , e h . S hortcut . Ctrl W ) ;
men u i tem l . Men u i tems . Add ( men u i tem2 ) ;
th i s . Menu = m a i n Men u :

publ i c vo i d Zamkn i j C l i cked ( Obj ect sender . EventArgs e )

th i s . C l o s e ( ) ;

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Jeli spojrzymy na rysunek 1 0 . 1 8 , zobaczymy, e do pozycji Zamknij


w menu Plik dopisany zosta skrt Ctrl+ W. Wcinicie na klawiatu
rze tej kombinacji znakw (nawet gdy menu nie jest aktywne) spo
woduje automatyczne wywoanie pozycji Zamknij, a tym samym
wykonanie metody Zamkn i j Cl i cked . Poniewa jedynym zadaniem tej
metody jest zamknicie aplikacji, program zakoczy swoje dziaanie .
Rysunek 10.18.

Menu z przypisanym
skrtem kl.awiaturowym

ii..,

Okno z menu

Zamknij

1 @1 1

----

Ctrl + \!\1

244

C#

w i cz e n i a

Drug z metod dodawania skrtw klawiaturowych jest modyfikacja


waciwoci ShortCut w obiekcie klasy Menultem . Najpierw naley utwo
rzy pozycj menu (z wykorzystaniem jednego z przedstawionych
wyej sposobw) i dopiero do niej przypisa skrt.
WICZENIE

Przypisywanie skrtw do istniejcych menu

Napisz aplikacj zawierajc menu Plik, w ktrym bdzie znajdowa


si pozycja Zamknij. Do pozycji Zamknij przypisz skrt klawiaturo
wy Ctrl+ W (lub inny) , uyj drugiego z poznanych sposobw definio
wania skrtw.
u s i n g Sy stem :
u s i n g Sy stem . W i n dows . Forms :
publ i c c l a s s Ma i n Form : Form

M a i n Menu mai nMenu = n ew M a i nMen u ( ) ;


Men u l tem men u l teml :
Men u l tem men u l tem2 :
publ i c Ma i n Form ( )

th i s . Text = "Okno z men u " :


th i s . Wi dth = 320 :
th i s . He i ght = 2 0 0 :
men u l teml
m a i n Menu . Menu i tems . Add ( "&P l i k " ) :
EventHandl er eh = n ew EventHandl er ( th i s . Zamkn i j C l i cked ) :
men u l tem2
men u l tem l . Men u l tems . Ad d ( "&Zamkn i j " , eh ) :
men u l tem2 . Shortcut
Shortcut . Ctrl W :
th i s . Menu
m a i n Men u :
=

publ i c vo i d Zamkn i j C l i cked ( Obj ect sender . EventArgs e )

th i s . C l o s e ( ) :

publ i c stati c voi d M a i n ( )

{
}

Appl i ca t i on . Run ( new Ma i n Form ( ) ) ;

Notatki

You might also like