Você está na página 1de 87

IDZ DO

PRZYKADOWY ROZDZIA
SPIS TRECI

KATALOG KSIEK
KATALOG ONLINE
ZAMW DRUKOWANY KATALOG

Delphi dla .NET.


Vademecum profesjonalisty
Autor: Xavier Pacheco
Tumaczenie: Rafa Joca, Szymon
Kobalczyk, Mikoaj Szczepaniak
ISBN: 83-7361-631-4
Tytu oryginau: Delphi for .net Developers Guide
Format: B5, stron: 944

TWJ KOSZYK
DODAJ DO KOSZYKA

CENNIK I INFORMACJE
ZAMW INFORMACJE
O NOWOCIACH
ZAMW CENNIK

CZYTELNIA
FRAGMENTY KSIEK ONLINE

Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl

Platforma .NET staje si coraz bardziej popularna. Powstaje coraz wicej aplikacji
realizowanych wanie pod jej ktem. Udostpniane przez platform .NET mechanizmy
pozwalaj na szybkie tworzenie aplikacji, co przysparza jej wielu zwolennikw. Do
stworzenia aplikacji nie wystarcz jednak tylko mechanizmy, nawet najlepsze. Niezbdne
jest wygodne i uniwersalne rodowisko programowania, jakim niewtpliwie jest Delphi.
Jego najnowsza wersja umoliwia pene wykorzystanie potencjau platformy .NET.
Delphi dla .NET. Vademecum profesjonalisty to podrcznik przedstawiajcy moliwoci
tworzenia aplikacji .NET za pomoc narzdzia programistycznego firmy Borland.
W ksice zamieszczono praktyczne przykady, omwienie ciekawych technik oraz
przydatne wskazwki na temat efektywnego korzystania z potencjau platformy .NET
Framework. Ksika zawiera dokadne omwienie jzyka programowania Delphi,
zaawansowanych zagadnie zwizanych z programowaniem dla platformy .NET
(w tym z zarzdzaniem pamici), mechanizmw COM-Interop i Reflection, biblioteki
GDI+, wytwarzania komponentw typu Windows Forms oraz Web Forms i wiele innych.
Znajdziesz tu take solidn analiz kluczowych technologii platformy .NET, takich jak
ADO.NET i ASP.NET, wcznie z mnstwem przykadw demonstrujcych ich moliwoci.
Podstawowe wiadomoci o platformie .NET i rodzaje aplikacji .NET
Przegld elementw platformy .NET
Delphi for .NET rodowisko i jzyk programowania
Biblioteka klas platformy .NET
Korzystanie z biblioteki GDI+
rodowisko Mono
Programowanie wielowtkowe
Usugi COM Interop i Platform Invocation Service
Programowanie aplikacji bazodanowych
Tworzenie stron WWW w technologii ASP.NET
Jeli szukasz ksiki powiconej technologii .NET i programowaniu w jzyku Delphi
aplikacji zgodnych z t technologi, trafie najlepiej, jak tylko moge.

5RKUVTGEK



 




    




   





Koncepcja .NET................................................................................................................... 28
Wizja .NET .................................................................................................................... 28
Skadniki platformy .NET Framework
rodowisko Common Language Runtime (CLR) i biblioteki Class Libraries........ 31
Rodzaje aplikacji .NET.................................................................................................. 32
Czym jest biblioteka VCL for .NET? ............................................................................ 33
Rozproszone wytwarzanie oprogramowania za porednictwem usug Web Services.......... 34
Definicja usug Web Services ........................................................................................ 35
Klienty usug Web Services........................................................................................... 37
Narzdzia programowania usug Web Services............................................................. 38




  !"#
$" %

&
Od tworzenia do uruchamiania ............................................................................................ 39
rodowisko Common Language Runtime (CLR) ................................................................ 40
Moduy zarzdzane ........................................................................................................ 40
Podzespoy..................................................................................................................... 41
Kod zarzdzany i niezarzdzany.................................................................................... 42
Kompilowanie i uruchamianie kodu MSIL i JIT ........................................................... 42
System Common Type System (CTS) ................................................................................. 45
Typy wartociowe.......................................................................................................... 45
Typy referencyjne .......................................................................................................... 46
Specyfikacja Common Language Specification (CLS)........................................................ 46
Platforma .NET Framework i biblioteka Base Class Library (BCL).................................... 47
Przestrzenie nazw .......................................................................................................... 47
Przestrze nazw System................................................................................................. 47
Gwne podprzestrzenie przestrzeni nazw System ........................................................ 47



  !   "#  $

&


  '(#%) !


 *+%,)

-Omwienie Delphi for .NET................................................................................................ 55


Wprowadzenie do zintegrowanego rodowiska programowania (IDE) ............................... 56
Strona powitalna ............................................................................................................ 57
Obszar projektowania .................................................................................................... 57
Formularze..................................................................................................................... 60

Delphi dla .NET. Vademecum profesjonalisty

Paleta narzdzi i fragmenty kodu................................................................................... 61


Inspektor obiektw ........................................................................................................ 62
Edytor kodu ................................................................................................................... 63
Meneder projektu ......................................................................................................... 65
Widok modelu ............................................................................................................... 66
Eksplorator danych ........................................................................................................ 67
Repozytorium obiektw................................................................................................. 67
Eksplorator kodu............................................................................................................ 68
Lista zada do wykonania.............................................................................................. 68

.


"#/"# +  


Struktury oparte na moduach zarzdzanych........................................................................ 71
Przestrzenie nazw .......................................................................................................... 71
Struktura moduu ........................................................................................................... 73
Skadnia klauzuli uses.................................................................................................... 75
Cykliczne odwoania do moduw................................................................................. 76
Przestrzenie nazw................................................................................................................. 77
Deklaracja przestrzeni nazw .......................................................................................... 77
Stosowanie przestrzeni nazw ......................................................................................... 79
Klauzula namespaces..................................................................................................... 79
Identyfikowanie oglnych przestrzeni nazw.................................................................. 79
Aliasy moduw............................................................................................................. 80

-


0(#%) 

1
Wszystko o technologii .NET .............................................................................................. 81
Komentarze .......................................................................................................................... 82
Procedury i funkcje .............................................................................................................. 82
Nawiasy w wywoaniach ............................................................................................... 83
Przecianie ................................................................................................................... 83
Domylne wartoci parametrw..................................................................................... 83
Zmienne ............................................................................................................................... 85
Stae ..................................................................................................................................... 86
Operatory ............................................................................................................................. 88
Operatory przypisania.................................................................................................... 88
Operatory porwnania ................................................................................................... 89
Operatory logiczne......................................................................................................... 89
Operatory arytmetyczne................................................................................................. 90
Operatory bitowe ........................................................................................................... 91
Procedury zwikszania i zmniejszania........................................................................... 92
Operatory typu zrb i przypisz ................................................................................... 92
Typy jzyka Delphi.............................................................................................................. 93
Obiekty, wszdzie tylko obiekty!................................................................................... 93
Zestawienie typw ......................................................................................................... 94
Znaki.............................................................................................................................. 95
Typy wariantowe ........................................................................................................... 95
Typy definiowane przez uytkownika ................................................................................. 99
Tablice ......................................................................................................................... 100
Tablice dynamiczne ..................................................................................................... 101
Rekordy ....................................................................................................................... 103
Zbiory .......................................................................................................................... 104
Niebezpieczny kod ................................................................................................... 106
Wskaniki .................................................................................................................... 107
Klasy i obiekty............................................................................................................. 110
Aliasy typw................................................................................................................ 111
Rzutowanie i konwersja typw .......................................................................................... 112
Zasoby acuchowe............................................................................................................ 113

Spis treci

Testowanie warunkw ....................................................................................................... 113


Instrukcja if.................................................................................................................. 114
Stosowanie instrukcji case ........................................................................................... 114
Ptle ................................................................................................................................... 115
Ptla for ....................................................................................................................... 115
Ptla while ................................................................................................................... 116
Ptla repeat-until.......................................................................................................... 117
Instrukcja Break........................................................................................................... 117
Instrukcja Continue...................................................................................................... 117
Procedury i funkcje ............................................................................................................ 118
Przekazywanie parametrw ......................................................................................... 119
Zakres ................................................................................................................................ 122
Moduy i przestrzenie nazw ............................................................................................... 123
Klauzula uses............................................................................................................... 124
Cykliczne odwoania do moduw............................................................................... 125
Pakiety i podzespoy .......................................................................................................... 125
Programowanie obiektowe................................................................................................. 126
Stosowanie obiektw Delphi.............................................................................................. 127
Deklaracja i tworzenie egzemplarza ............................................................................ 128
Destrukcja.................................................................................................................... 129
Przodek wszystkich obiektw...................................................................................... 129
Pola.............................................................................................................................. 129
Metody......................................................................................................................... 130
Typy metod.................................................................................................................. 131
Referencje do klas........................................................................................................ 134
Waciwoci................................................................................................................. 135
Zdarzenia ..................................................................................................................... 136
Specyfikatory widocznoci .......................................................................................... 138
Klasy zaprzyjanione................................................................................................... 140
Klasy pomocnicze........................................................................................................ 140
Typy zagniedone ...................................................................................................... 141
Przecianie operatorw .............................................................................................. 142
Atrybuty....................................................................................................................... 142
Interfejsy...................................................................................................................... 143
Ujednolicony mechanizm obsugi wyjtkw ..................................................................... 147
Klasy wyjtkw ........................................................................................................... 150
Przepyw sterowania dziaaniem.................................................................................. 151
Ponowne generowanie wyjtkw................................................................................. 153

   %% &  # !' ! (


2


 +#
/33 %% #

-
Podstawowe podzespoy .................................................................................................... 157
Przegldanie zawartoci podzespow i wystpujcych midzy nimi zalenoci .............. 158
Mechanizm GAC ............................................................................................................... 159
Konstruowanie podzespow ............................................................................................. 160
Dlaczego stosujemy podzespoy .NET?....................................................................... 161
Stosowanie pakietw do budowy podzespow........................................................... 161
Stosowanie bibliotek do budowania podzespow....................................................... 166
Stosowanie podzespow w jzyku Delphi ........................................................................ 170
Stosowanie podzespow z jzyka Delphi w programach C# ............................................ 171
Instalacja pakietw w rodowisku Delphi.......................................................................... 171
Podzespoy ze cis kontrol nazw ................................................................................... 172
Dynamicznie wczytywane podzespoy .............................................................................. 173

Delphi dla .NET. Vademecum profesjonalisty




" #4#5),6
#+ 


Pojcia podstawowe........................................................................................................... 175


Przestrzenie nazw GDI+ .............................................................................................. 175
Klasa Graphics............................................................................................................. 176
Ukad wsprzdnych w systemie Windows................................................................ 176
Rysowanie prostych ........................................................................................................... 178
Klasy Pen i Brush ........................................................................................................ 178
Rysowanie prostych..................................................................................................... 179
Kocwki linii ............................................................................................................. 181
czenie linii klasa GraphicsPath ........................................................................... 183
Rysowanie krzywych ......................................................................................................... 185
Krzywa sklejana typu cardinal..................................................................................... 185
Krzywa sklejana Beziera.............................................................................................. 185
Rysowanie figur ................................................................................................................. 189
Rysowanie prostoktw............................................................................................... 189
Rysowanie elips ........................................................................................................... 190
Rysowanie wieloktw ................................................................................................ 191
Rysowanie wycinkw elips.......................................................................................... 191
Wicej o pdzlu LinearGradientBrush ..................................................................... 193
Klasy GraphicsPath i Region ............................................................................................. 193
Rysowanie za pomoc klasy GraphicsPath.................................................................. 194
Rysowanie za pomoc klasy Region............................................................................ 195
Obszary przycinajce................................................................................................... 197
Praca z obrazami ................................................................................................................ 199
Klasy Image ................................................................................................................. 200
Wczytywanie i tworzenie bitmap................................................................................. 200
Zmiana rozdzielczoci obrazu...................................................................................... 201
Rysowanie obrazw..................................................................................................... 202
Interpolacja .................................................................................................................. 203
Rysowanie efektu zwierciada (lustra) ......................................................................... 204
Stosowanie metod przeksztacania obrazw ................................................................ 206
Tworzenie miniatur...................................................................................................... 210
Przegld ukadw wsprzdnych...................................................................................... 211
Przykad animacji............................................................................................................... 213

1


7
  !" *+%



Cechy rodowiska Mono.................................................................................................... 221
Historia Mono .................................................................................................................... 222
Po co stworzono Mono?..................................................................................................... 223
Mapa drogowa Mono......................................................................................................... 224
Cele Mono 1.0 ............................................................................................................. 224
Cele Mono 1.2 ............................................................................................................. 225
Cele Mono 1.4 ............................................................................................................. 225
Instalacja i ustawienia ........................................................................................................ 226
Instalacja rodowiska uruchomieniowego Mono program Red Carpet................... 226
Tworzenie naszego pierwszego programu Mono............................................................... 229
Uruchamianie w rodowisku Mono (w systemie Linux)
podzespow wygenerowanych w Delphi....................................................................... 230
Wieloplatformowa technologia ASP.NET ......................................................................... 234
Wdraanie rozwiza ASP.NET w rodowisku Mono ................................................ 236
Konfiguracja XSP........................................................................................................ 236
Parametry rodowiska uruchomieniowego XSP .......................................................... 236
Kilka uwag i moliwych kierunkw rozwoju rozszerze zaprezentowanego przykadu...238
Mono i technologia ADO.NET .......................................................................................... 239
Mono i serwer Apache ....................................................................................................... 243
Mono i przestrze nazw System.Windows.Forms ............................................................. 245

Spis treci




8  "( *" 

.
Sposb dziaania mechanizmu odzyskiwania pamici ....................................................... 247
Pokoleniowy algorytm odzyskiwania pamici............................................................. 249
Wywoywanie mechanizmu odzyskiwania pamici..................................................... 252
Konstruktory ...................................................................................................................... 252
Finalizacja.......................................................................................................................... 253
Metoda bezporedniego zwalniania zasobw interfejs IDisposable.............................. 255
Przykad implementacji interfejsu IDisposable............................................................ 255
Automatyczne implementowanie interfejsu IDisposable............................................. 257
Problemy z wydajnoci w aspekcie finalizacji ................................................................. 258

 9
 : %'

2
Interfejsy przestrzeni nazw System.Collections................................................................. 261
Interfejs IEnumerable .................................................................................................. 262
Interfejs ICollection ..................................................................................................... 263
Interfejs IList ............................................................................................................... 263
Interfejs IDictionary..................................................................................................... 263
Interfejs IEnumeration ................................................................................................. 264
Klasy przestrzeni nazw System.Collections....................................................................... 264
Kolekcja typu Stack ..................................................................................................... 265
Klasa Queue................................................................................................................. 268
Klasa ArrayList............................................................................................................ 271
Klasa HashTable.......................................................................................................... 275
Tworzenie kolekcji ze cis kontrol typw ..................................................................... 278
Dziedziczenie po klasie bazowej CollectionBase ........................................................ 278
Stosowanie kolekcji ze cis kontrol typw.............................................................. 282
Tworzenie sownikw ze cis kontrol typw................................................................. 283
Dziedziczenie po klasie bazowej DictionaryBase........................................................ 283
Stosowanie kolekcji ze cis kontrol typw.............................................................. 286


 %+";;< 

1
Typ System.String.............................................................................................................. 287
Niezmienno acuchw w rodowisku .NET............................................................ 288
Operacje na acuchach ............................................................................................... 290
Porwnywanie acuchw ........................................................................................... 291
Klasa StringBuilder............................................................................................................ 295
Metody klasy StringBuilder......................................................................................... 296
Stosowanie obiektw klasy StringBuilder ................................................................... 296
Formatowanie acuchw .................................................................................................. 297
Specyfikatory formatu........................................................................................................ 298
Specyfikatory formatw liczbowych ........................................................................... 299
Specyfikatory formatw daty i czasu........................................................................... 301
Specyfikatory formatw typw wyliczeniowych......................................................... 304

 
  ' %+" 

&9
Klasy przestrzeni nazw System.IO..................................................................................... 307
Praca z systemem katalogw ............................................................................................. 309
Tworzenie i usuwanie katalogw................................................................................. 309
Przenoszenie i kopiowanie katalogw ......................................................................... 310
Analizowanie informacji o katalogach......................................................................... 313
Praca z plikami................................................................................................................... 314
Tworzenie i usuwanie plikw ...................................................................................... 314
Przenoszenie i kopiowanie plikw............................................................................... 315
Analizowanie informacji o plikach .............................................................................. 315

10

Delphi dla .NET. Vademecum profesjonalisty

Strumienie.......................................................................................................................... 315
Praca ze strumieniami plikw tekstowych ................................................................... 316
Praca ze strumieniami plikw binarnych ..................................................................... 319
Asynchroniczny dostp do strumieni ................................................................................. 321
Monitorowanie aktywnoci katalogw .............................................................................. 324
Serializacja......................................................................................................................... 326
Sposb dziaania serializacji ........................................................................................ 327
Formatery..................................................................................................................... 328
Przykad serializacji i deserializacji ............................................................................. 328

 &
   +#% % $"+

&&&
Podstawy budowy komponentw....................................................................................... 334
Kiedy naley tworzy wasne komponenty? ................................................................ 334
Etapy pisania komponentu........................................................................................... 335
Wybr klasy bazowej................................................................................................... 335
Tworzenie moduw komponentw............................................................................. 336
Tworzenie waciwoci................................................................................................ 339
Tworzenie zdarze....................................................................................................... 350
Tworzenie metod ......................................................................................................... 356
Konstruktory i destruktory........................................................................................... 356
Zachowanie w fazie projektowania.............................................................................. 358
Testowanie komponentu .............................................................................................. 359
Doczanie ikony komponentu .................................................................................... 359
Przykadowe komponenty.................................................................................................. 360
ExplorerViewer przykad komponentu dziedziczcego po klasie UserControl ...... 360
SimpleStatusBars przykad uycia dostawcw rozszerze ..................................... 368
Tworzenie komponentw uytkownika kontrolka PlayingCard.................................... 373

 .
 "   % ) 


&1
Procesy............................................................................................................................... 381
Wtki.................................................................................................................................. 382
Wtki w stylu .NET ........................................................................................................... 383
Domeny aplikacji ............................................................................................................... 384
Przestrze nazw System.Threading.................................................................................... 385
Klasa System.Threading.Thread .................................................................................. 385
Typ wyliczeniowy System.Threading.ThreadPriority ................................................. 389
Typ wyliczeniowy System.Threading.ThreadState...................................................... 390
Typ wyliczeniowy System.Threading.ApartmentState................................................ 391
Klasa System.Threading.ThreadPool........................................................................... 391
Klasa System.Threading.Timer.................................................................................... 393
Delegacje ..................................................................................................................... 394
Tworzenie bezpiecznego kodu wielowtkowego w stylu .NET......................................... 396
Mechanizmy blokujce ................................................................................................ 396
Zdarzenia ..................................................................................................................... 401
Lokalna pami wtkw .............................................................................................. 402
Komunikacja midzyprocesowa Win32 ...................................................................... 403
Bezpieczne wielowtkowe klasy i metody rodowiska .NET ...................................... 403
Kwestie dotyczce interfejsu uytkownika ........................................................................ 404
Metoda System.Windows.Forms.Control.Invoke() ..................................................... 405
Waciwo System.Windows.Forms.Control.InvokeRequired................................... 405
Metoda System.Windows.Forms.Control.BeginInvoke() ............................................ 406
Metoda System.Windows.Forms.Control.EndInvoke() ............................................... 406
Metoda System.Windows.Forms.Control.CreateCraphics() ........................................ 407

Spis treci

11

Wyjtki w programach wielowtkowych........................................................................... 409


System.Threading.ThreadAbortException................................................................... 409
System.Threading.ThreadInterruptedException .......................................................... 412
System.Threading.ThreadStateException .................................................................... 412
System.Threading.SynchronizationLockException ..................................................... 412
Odzyskiwanie pamici a wielowtkowo ......................................................................... 412

 -
 7 "  

. &
Odzwierciedlanie podzespow.......................................................................................... 413
Odzwierciedlanie moduw ............................................................................................... 416
Odzwierciedlanie typw..................................................................................................... 417
Dostp do skadowych typu podczas wykonywania (pne wizanie) .............................. 419
Wydajny dostp do skadowych przez wywoywanie typw skadowych ................... 423
Kolejny przykad wywoywania skadowych .............................................................. 423
Emitowanie kodu MSIL przy uyciu odzwierciedlania ..................................................... 427
Narzdzia klasy do emitowania MSIL .................................................................... 427
Proces emitowania ....................................................................................................... 428
Przykad uycia przestrzeni nazw System.Reflection.Emit ......................................... 428

 2
 +=+ ' #"% "

>+?7, !",@; @

.&&
Do czego su mechanizmy wsppracy z istniejcym kodem? ....................................... 433
Powszechne problemy przy wsppracy ............................................................................ 434
Uycie obiektw COM w kodzie .NET ............................................................................. 435
Automatyzacja z pnym dowizywaniem.................................................................. 435
Parametry typw prostych, referencyjne i opcjonalne ................................................. 438
Wczenie dowizywane obiekty COM ........................................................................ 439
Podzespoy poredniczce ........................................................................................... 442
Tworzenie podzespou poredniczcego...................................................................... 443
Zawarto poredniczcej biblioteki typw ................................................................. 444
Uycie zdarze COM................................................................................................... 445
Sterowanie dugoci ycia obiektw COM ................................................................ 447
Obsuga bdw ........................................................................................................... 447
Podstawowe podzespoy poredniczce....................................................................... 448
Dostosowywanie zwykych i podstawowych podzespow poredniczcych.............. 449
Uycie obiektw .NET w kodzie COM ............................................................................. 451
Rejestrowanie podzespou .NET dla automatyzacji..................................................... 451
Automatyzacja z pnym dowizywaniem.................................................................. 452
Poredniczce biblioteki typw ................................................................................... 453
Co zawiera poredniczca biblioteka typw? .............................................................. 454
Implementowanie interfejsw...................................................................................... 455
Typy i szeregowanie parametrw ................................................................................ 457
Obsuga bdw ........................................................................................................... 459
Uycie procedur bibliotek Win32 w kodzie .NET ............................................................. 460
Tradycyjna skadnia Delphi ......................................................................................... 461
Skadnia wykorzystujca atrybuty ............................................................................... 462
Typy i szeregowanie parametrw ................................................................................ 464
Obsuga bdw ........................................................................................................... 466
Kody bdw Win32.................................................................................................... 467
Kody bdw HResult.................................................................................................. 469
Kwestie zwizane z wydajnoci................................................................................. 471
Uycie procedur .NET w kodzie Win32 ............................................................................ 475
Tradycyjna skadnia Delphi ......................................................................................... 476
Typy i szeregowanie parametrw ................................................................................ 477

12

Delphi dla .NET. Vademecum profesjonalisty

)   !    *% 


 
  !   )


.1
 
   )


.1&
Zaoenia projektowe......................................................................................................... 483
Architektura danych odczonych od rda danych.................................................... 483
Integracja z XML-em................................................................................................... 484
Jednolita reprezentacja danych .................................................................................... 484
Oparcie na platformie .NET Framework...................................................................... 484
Wykorzystanie wczeniejszych technologii................................................................. 484
Obiekty ADO.NET ............................................................................................................ 485
Klasy dostpu bezporedniego..................................................................................... 486
Klasy dostpu rozczalnego........................................................................................ 487
Dostawcy danych w .NET.................................................................................................. 487

 1
 >4# 3 %? 

.1
Funkcje obiektu Connection .............................................................................................. 489
Konfiguracja waciwoci ConnectionString ..................................................................... 490
Ustawienia SqIConnection.ConnectionString.............................................................. 490
Ustawienia OleDbConnection.ConnectionString......................................................... 491
Ustawienia OdbcConnection.ConnectionString........................................................... 491
Ustawienia OracleConnection.ConnectionString......................................................... 491
Otwieranie i zamykanie pocze ...................................................................................... 492
Zdarzenia obiektu Connection ........................................................................................... 492
Buforowanie pocze........................................................................................................ 495


 >4# 3 %=?"")  

. 
Wykonywanie polece....................................................................................................... 497
Interfejs IDbCommand ................................................................................................ 497
Polecenia niezwracajce wynikw..................................................................................... 498
Pobieranie pojedynczych wartoci ..................................................................................... 500
Wykonywanie polece jzyka DDL................................................................................... 501
Podawanie parametrw przy uyciu klasy IDbParameter .................................................. 503
Wykonywanie procedur skadowanych.............................................................................. 504
Odczytywanie parametrw................................................................................................. 506
Pobieranie zbiorw wynikowych przy uyciu obiektu DataReader ................................... 508
Interfejs IDataReader................................................................................................... 508
Pobranie zbioru wynikowego............................................................................................. 508
Pobranie wielu zbiorw wynikowych przy uyciu obiektu DataReader ............................ 509
Uycie obiektu DataReader do pobierania danych typu BLOB ......................................... 510
Uycie obiektu DataReader do pobierania informacji na temat schematu ......................... 512

9
 :+#) ); 

- Klasa DataAdapter ............................................................................................................. 515


Struktura klasy DataAdapter........................................................................................ 515
Tworzenie obiektu DataAdapter .................................................................................. 517
Pobieranie wynikw zapytania .................................................................................... 518
Odwzorowywanie wynikw zapytania ........................................................................ 520
Praca z obiektami DataSet ................................................................................................. 523
Struktura klasy DataSet ............................................................................................... 523
Operacje klasy DataSet ................................................................................................ 525
Praca z obiektami DataTable ............................................................................................. 526
Definiowanie kolumn .................................................................................................. 526
Definiowanie kluczy gwnych ................................................................................... 528

Spis treci

13

Praca z ograniczeniami ................................................................................................ 528


Praca z obiektami DataRelation................................................................................... 531
Manipulowanie danymi praca z obiektem DataRow............................................... 534
Wyszukiwanie, sortowanie i filtrowanie danych ......................................................... 536


 :#+ !"# $"+
A3 %#)B  # #

-&
Wywietlanie danych za pomoc DataView i DataViewManager ..................................... 539
Klasa DataView ........................................................................................................... 540
Klasa DataViewManager ............................................................................................. 541
Przykadowe projekty wykorzystujce klasy DataView i DataViewManager ............. 541
Dowizywanie danych ....................................................................................................... 552
Interfejsy dowizywania danych.................................................................................. 552
Dowizanie proste i zoone ........................................................................................ 553
Klasy dowiza danych z formularza WinForm.......................................................... 553
Tworzenie formularzy Windows z dowizaniami danych ........................................... 554


 8+#C=#

-2Aktualizacja rda danych za pomoc klasy SQLCommandBuilder................................ 565


Aktualizacja rda danych za pomoc wasnej logiki aktualizacji.................................... 568
Korzystanie z klasy Command .................................................................................... 568
Korzystanie z klasy SqlDataAdapter ........................................................................... 575
Aktualizacja za pomoc zapamitanych procedur ....................................................... 580
Obsuga wspbienoci .............................................................................................. 586
Odwieanie danych po ich aktualizacji ...................................................................... 590

&
 +%' 3 %#);  *+ % #=

- &
Przetwarzanie transakcyjne................................................................................................ 593
Przykad prostego przetwarzania transakcyjnego ........................................................ 594
Transakcje wykorzystujce obiekt DataAdapter.......................................................... 597
Poziomy izolacji .......................................................................................................... 597
Znaczniki zapisu .......................................................................................................... 599
Zagniedone transakcje.............................................................................................. 599
Obiekty DataSet ze cis kontrol typw.......................................................................... 600
Wady i zalety ............................................................................................................... 600
Tworzenie obiektw DataSet ze cis kontrol typw................................................ 601
Analiza pliku .pas dla obiektu DataSet ze cis kontrol typw ................................. 602
Korzystanie z obiektw DataSet ze cis kontrol typw........................................... 609

.
 :+#+##D<)@ E

2
Przegld architektury ......................................................................................................... 611
Klasy Borland Data Provider ............................................................................................. 612
Klasa BdpConnection .................................................................................................. 613
Klasa BdpCommand .................................................................................................... 614
Klasa BdpDataReader.................................................................................................. 615
Klasa BdpDataAdapter ................................................................................................ 616
Klasy BdpParameter i BdpParameterCollection .......................................................... 617
Klasa BdpTransaction.................................................................................................. 618
Elementy projektowe w rodowisku programistycznym.................................................... 619
Edytor pocze ........................................................................................................... 619
Edytor tekstw polece................................................................................................ 620
Edytor kolekcji parametrw......................................................................................... 620
Okno dialogowe konfiguracji cznika danych ............................................................ 620

14

Delphi dla .NET. Vademecum profesjonalisty

)

   *   +, -$

-
 +#;


2Technologie internetowe jak one dziaaj? ................................................................... 625


Omwienie protokou HTTP ....................................................................................... 625
Pakiet adania protokou HTTP................................................................................... 626
Pakiet odpowiedzi protokou HTTP ............................................................................ 627
ASP.NET jak dziaa? .................................................................................................... 628
Prosta aplikacja internetowa ........................................................................................ 629
Struktura strony ASP.NET........................................................................................... 630
Komunikacja sterowana zdarzeniami .......................................................................... 632
VIEWSTATE i utrzymywanie stanu ........................................................................... 633
Kod poza scen (CodeBehind)..................................................................................... 634
Klasy ASP.NET ................................................................................................................. 635
Klasa HTTPResponse .................................................................................................. 635
Klasa HTTPRequest .................................................................................................... 638
Klasa HTTPCookie...................................................................................................... 640
Obsuga wielokrotnego wysyania danych................................................................... 641

2
   + ;


2.&
Tworzenie stron WWW za pomoc kontrolek ASP.NET .................................................. 643
Przykadowy formularz proby o pobranie produktu................................................... 644
Ukad graficzny strony................................................................................................. 645
Tworzenie formularza.................................................................................................. 645
Przetworzenie zdarzenia zaadowania.......................................................................... 646
Zapis plikw w aplikacjach ASP.NET......................................................................... 647
Kolejno przetwarzania zdarze w formularzach WWW........................................... 649
Wczeniejsze wypenianie kontrolek list ........................................................................... 649
Przeprowadzanie walidacji formularzy .............................................................................. 650
Walidacja po stronie klienta a walidacja po stronie serwera........................................ 651
Klasa BaseValidator .................................................................................................... 651
Kontrolka RequiredFieldValidator .............................................................................. 652
Kontrolka CompareValidator....................................................................................... 653
Kontrolka RegularExpressionValidator ....................................................................... 654
Kontrolka RangeValidator........................................................................................... 656
Kontrolka CustomValidator......................................................................................... 656
Kontrolka ValidationSummary .................................................................................... 657
Formatowanie stron ........................................................................................................... 658
Waciwoci WebControl z typami cisymi ............................................................... 658
Kaskadowe arkusze stylw .......................................................................................... 659
Wykorzystanie klasy stylu ........................................................................................... 660
Przemieszczanie si midzy formularzami Web Forms ..................................................... 661
Przekazywanie danych dziki mechanizmowi POST .................................................. 662
Zastosowanie metody Response.Redirect() i tekstu zapytania..................................... 662
Wykorzystanie metody Server.Transfer() .................................................................... 663
Wykorzystanie zmiennych sesji................................................................................... 664
Wskazwki i ciekawe sztuczki........................................................................................... 665
Uycie kontrolki Panel do symulacji wielu formularzy ............................................... 665
Wysyanie pliku przez klienta...................................................................................... 667
Wysanie listu e-mail z poziomu formularza ............................................................... 669
Wywietlanie obrazw................................................................................................. 670
Dynamiczne dodawanie kontrolek............................................................................... 671

Spis treci

15


   %'3#;


2Dowizywanie danych ....................................................................................................... 675


Proste dowizywanie danych ....................................................................................... 675
Zoone dowizywanie danych.................................................................................... 680
Dowizywanie danych do kontrolek list ............................................................................ 680
Kontrolka CheckBoxList ............................................................................................. 680
Kontrolka DropDownList ............................................................................................ 682
Kontrolka ListBox ....................................................................................................... 685
Kontrolka RadioButtonList.......................................................................................... 687
Dowizywanie danych do kontrolek iteracyjnych.............................................................. 689
Kontrolka Repeater ...................................................................................................... 689
Kontrolka DataList ...................................................................................................... 693
Korzystanie z elementu DataGrid ...................................................................................... 698
Stronicowanie kontrolki DataGrid ............................................................................... 700
Edycja za pomoc kontrolki DataGrid......................................................................... 703
Dodanie elementw do kontrolki DataGrid ................................................................. 709
Sortowanie kontrolki DataGrid.................................................................................... 709
Formularz proby o pobranie pliku oparty na bazie danych i administracja systemem ....... 710

1
 >++ 

 Terminy zwizane z usugami sieciowymi......................................................................... 715


Konstrukcja usug sieciowych............................................................................................ 716
Atrybut [WebService].................................................................................................. 721
Zwracanie danych z usugi sieciowej........................................................................... 722
Atrybut [WebMethod] ................................................................................................. 723
Wykorzystywanie usug sieciowych .................................................................................. 725
Odkrywanie usugi....................................................................................................... 725
Tworzenie klasy poredniczcej .................................................................................. 725
Korzystanie z klasy poredniczcej ............................................................................. 727
Pobranie obiektu DataSet z usugi sieciowej ............................................................... 730
Wywoanie asynchronicznej metody usugi sieciowej................................................. 733
Zabezpieczanie usug sieciowych ...................................................................................... 734


  
 ") 

&
Dostpne obecnie technologie zdalne ................................................................................ 739
Gniazda........................................................................................................................ 739
RPC ............................................................................................................................. 740
Java RMI...................................................................................................................... 740
CORBA ....................................................................................................................... 740
XML-RPC ................................................................................................................... 741
DCOM ......................................................................................................................... 741
Com-Interop................................................................................................................. 741
SOAP........................................................................................................................... 741
.NET Remoting............................................................................................................ 742
Architektury rozproszone................................................................................................... 743
Architektura klient-serwer ........................................................................................... 743
Architektura typu rwny z rwnym.......................................................................... 744
Architektury wielowarstwowe ..................................................................................... 744
Zalety tworzenia aplikacji wielowarstwowych .................................................................. 745
Skalowalno i odporno na bdy ............................................................................. 745
Tworzenie i wdraanie................................................................................................. 747
Bezpieczestwo ........................................................................................................... 747
Podstawy technologii .NET Remoting............................................................................... 747
Architektura ................................................................................................................. 748
Domeny aplikacji......................................................................................................... 748

16

Delphi dla .NET. Vademecum profesjonalisty

Przestrze nazw System.Runtime.Remoting ............................................................... 749


Obiekty zdalnoci ........................................................................................................ 750
Aktywacja obiektu ....................................................................................................... 751
Dzierawcy i sponsorzy ............................................................................................... 753
Porednicy ................................................................................................................... 753
Kanay.......................................................................................................................... 754
Pierwsza aplikacja wykorzystujca .NET Remoting.......................................................... 754
Przygotowanie projektu ............................................................................................... 754
Dodawanie referencji................................................................................................... 756
Plik BankPackage.dll kontakt midzy klientami i serwerami ................................. 757
Implementacja serwera ................................................................................................ 759
Implementacja klienta.................................................................................................. 763

&9
  
 "%'

2
Projekt szablonu................................................................................................................. 767
ledzenie komunikatw ..................................................................................................... 768
Analiza pakietw SOAP .................................................................................................... 770
Aktywacja kliencka............................................................................................................ 772
Wzorzec fabryki........................................................................................................... 773
Testowanie przykadu .................................................................................................. 779
Problemy zwizanie z CAO......................................................................................... 780
Zarzdzanie czasem ycia obiektw .................................................................................. 781
Nieudane odnowienie wynajmu ......................................................................................... 784
Pliki konfiguracyjne........................................................................................................... 785
Konfiguracja serwera................................................................................................... 786
Konfiguracja klienta .................................................................................................... 788
Przejcie z komunikacji HTTP na TCP.............................................................................. 794
Przejcie z formatu SOAP na format binarny .................................................................... 794
Rnice w kodowaniu binarnym i SOAP........................................................................... 796

&
 <   F+%'



Rodzaje bezpieczestwa w ASP.NET................................................................................ 799
Uwierzytelnianie ................................................................................................................ 799
Konfiguracja modelu uwierzytelniania w ASP.NET ................................................... 800
Uwierzytelnianie Windows.......................................................................................... 800
Uwierzytelnianie bazujce na formularzach ................................................................ 802
Uwierzytelnianie Passport ........................................................................................... 809
Autoryzacja ........................................................................................................................ 810
Autoryzacja plikowa .................................................................................................... 810
Autoryzacja URL sekcja <authorization>............................................................... 811
Autoryzacja bazujca na rolach ................................................................................... 812
Podszywanie si........................................................................................................... 814
Wylogowywanie si........................................................................................................... 815

&
 4 %!';


1 
Wdraanie aplikacji ASP.NET........................................................................................... 817
Kwestie zwizane z prostym wdraaniem ................................................................... 817
Wdraanie z wykorzystaniem polecenia XCOPY........................................................ 821
Ustawienia konfiguracji ..................................................................................................... 821
Plik machine.config ..................................................................................................... 822
Plik web.config ............................................................................................................ 822
Wskazwki konfiguracyjne................................................................................................ 827
Obsuga przekierowania bdw.................................................................................. 828
Ponowne uruchomienie procesu wykonawczego......................................................... 829
Zwikszenie wydajnoci przez buforowanie wyjcia................................................... 831

Spis treci

17

Monitorowanie procesu ASP.NET .............................................................................. 831


ledzenie aplikacji ....................................................................................................... 833
Dodawanie i pobieranie wasnych ustawie konfiguracji .................................................. 837
Dodanie lub odczytanie sekcji <appSettings> ............................................................. 837
Dodawanie i odczyt wasnych sekcji konfiguracyjnych .............................................. 838

&&
 <! +  + "%';


1&
Buforowanie stron aplikacji ASP.NET .............................................................................. 839
Buforowanie stron ....................................................................................................... 839
Buforowanie fragmentw stron ................................................................................... 844
Buforowanie danych .................................................................................................... 844
Zalenoci buforowania............................................................................................... 848
Rozszerzenie zalenoci plikw w celu ich uycia z serwerem SQL Server ............... 849
Metody wywoa zwrotnych bufora ............................................................................ 850
Zarzdzanie stanem w aplikacjach ASP.NET .................................................................... 853
Zarzdzanie stanem za pomoc cookies....................................................................... 853
Korzystanie z komponentu ViewState ......................................................................... 855
Zarzdzanie stanem sesji.............................................................................................. 858
Przechowywanie danych sesji na serwerze stanw sesji.............................................. 860
Przechowywanie danych sesji w serwerze SQL Server ............................................... 860
Zdarzenia sesji ............................................................................................................. 861
Zarzdzanie stanem aplikacji ....................................................................................... 863
Buforowanie a stan aplikacji........................................................................................ 864

&.
   +#% %+  #;


12
Kontrolki uytkownika ...................................................................................................... 868
Bardzo prosta kontrolka uytkownika ......................................................................... 868
Omwienie prostej kontrolki ....................................................................................... 871
Kontrolka uytkownika dotyczca logowania ............................................................. 873
Kontrolki WWW................................................................................................................ 875
Tworzenie bardzo prostej kontrolki WWW ................................................................. 875
Wartoci trwae............................................................................................................ 878
Dodanie wasnego renderingu...................................................................................... 879
Okrelenie rodzaju bloku HTML................................................................................. 882
Obsuga danych da zwrotnych................................................................................ 883
Kontrolka TPostBackInputWebControl....................................................................... 884
Kontrolki zoone ........................................................................................................ 888
Implementacja kontrolki zoonej TNewUserInfoControl...................................... 888

"
./
;%

1 

4Q\F\KC

,\[M&GNRJK
Autor: Steve Taixeira
W niniejszym rozdziale zajmiemy si jzykiem wykorzystywanym w zintegrowanym
rodowisku Delphi jzykiem programowania Object Pascal (od pewnego czasu nazywanym po prostu jzykiem Delphi). Najpierw zaprezentujemy podstawy tego jzyka, takie jak jego zasadnicze reguy i konstrukcje, a nastpnie niektre z bardziej zaawansowanych aspektw programowania w Delphi, jak klasy czy obsuga wyjtkw.
Zakadamy przy tym, e masz ju pewne dowiadczenie z innymi wysokopoziomowymi
jzykami programowania. Nie bdziemy w zwizku z tym traci czasu na wprowadzanie najbardziej podstawowych poj dotyczcych tego typu jzykw, a zamiast tego
skupimy si na wyjanianiu elementw typowych dla Delphi. Po uwanym przeczytaniu
rozdziau powiniene rozumie, jak w tym jzyku mona stosowa takie elementy jak
zmienne, typy, operatory, ptle, instrukcje warunkowe, wyjtki i obiekty oraz ktre z tych
elementw maj zwizek z docelow platform .NET Framework. Aby zapewni Ci jak
najlepsze podstawy do pracy nad aplikacjami dla tej platformy, sprbujemy take porwna moliwoci jzyka Delphi z jego bardziej popularnymi kuzynami z rodziny .NET:
jzykami C# i Visual Basic .NET.


 
rodowisko Delphi 8 generuje aplikacje, ktre s w peni zgodne z platform Microsoft
.NET Framework. Oznacza to, e funkcjonalno i cechy kompilatora rodowiska Delphi 8
musz by zgodne z funkcjonalnoci i waciwociami platformy .NET Framework.
Zwizane z tym wymagania mog nie by do koca jasne dla tych programistw, ktrzy
przez lata funkcjonowali w wiecie rdzennego kodu (np. dla platformy Win32). Kompilator takiego kodu moe bowiem robi z kodem rdowym co zechce moliwoci
takiego kompilatora s ograniczane tylko przez zaoenia przyjte przez jego producenta. W wiecie aplikacji .NET dosownie kady fragment programu nawet co tak
trywialnego jak sumowanie dwch liczb cakowitych musi przej przez kompilator
generujcy kod zgodny z waciwociami i typami platformy .NET Framework.
Zamiast generowa rdzenny kod dla jednej platformy, kompilator .NET rodowiska
Delphi 8 musi wytwarza kod w formacie nazywanym jzykiem porednim firmy Microsoft (ang. Microsoft Intermediate Language MSIL), ktry jest reprezentacj kodu
rdowego aplikacji najniszego poziomu.

82

Cz II  Jzyk programowania Delphi for .NET


W rozdziale 2. omwilimy stosowan na platformie .NET Framework kompilacj
w locie (ang. Just in Time JIT). Teraz jest dobry moment, aby na chwil wrci
do informacji przekazanych w tamtym rozdziale.

 
Jzyk Delphi obsuguje trzy typy komentarzy: komentarze w nawiasach klamrowych,
komentarze w nawiasach okrgych z gwiazdkami oraz komentarze poprzedzone dwoma znakami ukonika. Poniej przedstawiono przykady tych trzech typw komentarzy:

      
 

     
   


     

Pierwsze dwa typy komentarzy s do siebie bardzo podobne. Kompilator uznaje za komentarz cay tekst znajdujcy si pomidzy symbolem otwierajcym a odpowiadajcym
mu symbolem zamykajcym. W przypadku komentarzy z dwoma ukonikami sytuacja
wyglda nieco inaczej komentarzem jest cay tekst znajdujcy pomidzy tymi znakami a najbliszym znakiem podziau wiersza.
W jzyku Delphi nie mona zagnieda komentarzy tego samego typu. Chocia z punktu
widzenia skadni jzyka zagniedanie komentarzy rnych typw jest dozwolone,
w praktyce stosowanie takich konstrukcji nie jest zalecane. Oto kilka przykadw:
 

 

 

 


Inn wygodn technik wyczania wybranych czci kodu rdowego, w szczeglnoci


w przypadku stosowania w tym kodzie rnych typw komentarzy, jest stosowanie
dyrektywy kompilatora . Przykadowo w poniszym fragmencie kodu wykorzystano
dyrektyw  do wzicia w komentarz bloku kodu, ktry ma zosta pominity
w procesie kompilacji:
!"#$%#&"%'()"*+,(&"%
 -
.-/0      1 -
!%&$"#

Poniewa identyfikator 


  nie zosta zdefiniowany, kod pomidzy
dyrektywami  i  nie bdzie przetwarzany.


 

Poniewa procedury i funkcje wystpuj niemal we wszystkich jzykach programowania i powinny by znane kademu programicie, nie bdziemy zwizanych z nimi zagadnie szczegowo w tej ksice omawiali. Chcielibymy jedynie zwrci uwag na
kilka unikalnych lub mao znanych kwestii pojawiajcych si w tym obszarze.

Rozdzia 5.  Jzyk Delphi

83

Funkcje, ktre nie zwracaj adnych wartoci (w jzyku  s deklarowane ze zwracanym


typem ) s nazywane procedurami (ang. procedures), natomiast funkcje zwracajce
jakie wartoci s nazywane wanie funkcjami (ang. functions). W jzyku angielskim
czsto stosuje si pojcie routine, ktre odnosi si zarwno do procedur, jak i funkcji,
natomiast terminu metoda (ang. method) uywamy do okrelania funkcji i procedur
nalecych do klas (termin ten jest wic charakterystyczny dla programowania
obiektowego).

 

Jedn z najmniej znanych cech jzyka programowania Delphi jest moliwo opcjonalnego stosowania nawiasw okrgych w wywoaniach bezparametrowych procedur i funkcji.
Oznacza to, e oba ponisze przykady s poprawne skadniowo:
#
23456
#
23456

Moliwo opcjonalnego umieszczania nawiasw bezporednio za nazwami bezparametrowych funkcji i procedur dla wikszoci programistw nie ma oczywicie adnego
znaczenia, jednak moe by wana dla tych osb, ktre dziel swj czas pracy pomidzy jzyk Delphi i taki jzyk programowania jak np. C#, gdzie stosowanie owych nawiasw jest konieczne. Jeli rwnolegle pracujesz w wielu jzykach programowania, nie
musisz dziki tej waciwoci Delphi pamita o stosowaniu rnych regu skadniowych dla wywoa funkcji i procedur w tych jzykach.

 

Jzyk programowania Delphi umoliwia stosowanie techniki nazywanej przecianiem
funkcji, czyli techniki polegajcej na deklarowaniu wielu procedur lub funkcji z t sam
nazw, ale innymi listami parametrw. Wszystkie przecione metody musz by deklarowane z dyrektyw , czyli tak jak w poniszym przykadzie:

 
7"8"
69
 6

 
748
69
 6

 
7$8$-69
 6

Zwr uwag na fakt, e reguy przeciania metod nalecych do klas s nieco inne ni
odpowiednie reguy dla procedur i funkcji deklarowanych poza klasami wyjanimy
to w podrozdziale Przecianie metod.


 
Jzyk Delphi obsuguje take wygodn w wielu przypadkach moliwo deklarowania
domylnych wartoci parametrw czyli moliwo okrelania wartoci domylnej
dla parametru funkcji lub procedury i brak koniecznoci przekazywania tego parametru
w pniejszych wywoaniach tej funkcji lub procedury. Aby zadeklarowa funkcj lub
procedur z domylnymi wartociami parametrw, za typem wybranego parametru
umie znak rwnoci i jego domyln warto; ilustruje to poniszy przykad:

 
7 $:; 48
6"8"
<=6

84

Cz II  Jzyk programowania Delphi for .NET


Procedura  moe by wywoywana na dwa sposoby. Po pierwsze, w wywoaniu tej procedury moemy okreli wartoci obu parametrw:
7 $:; > >/?@6

Po drugie, moemy okreli tylko parametr  i tym samym uy domylnej wartoci dla parametru :
7 $:; > >6 

"0 
  

Jeli zdecydujesz si na stosowanie domylnych wartoci parametrw, musisz pamita


o przestrzeganiu kilku wanych zasad:


Parametry ze zdefiniowanymi wartociami domylnymi musz wystpowa na kocu


listy parametrw. Na licie parametrw procedury lub funkcji parametry bez wartoci
domylnych nie mog by deklarowane za parametrami z takimi wartociami.

Domylne wartoci parametrw mog mie posta liczb cakowitych, acuchw,


liczb zmiennoprzecinkowych, wskanikw lub zbiorw. W jzyku Delphi s
obsugiwane take takie typy jak klasy, interfejsy, tablice dynamiczne oraz
referencje do klas, jednak tylko w przypadku, gdy domyln wartoci jest .

Parametry z zadeklarowanymi wartociami domylnymi musz by


przekazywane przez warto lub jako stae (ze sowem !). Nie mog by
referencjami (, "!) ani parametrami bez typw.

Jedn z najwikszych korzyci wynikajcych z moliwoci deklarowania domylnych


wartoci parametrw jest zwikszanie funkcjonalnoci istniejcych funkcji i procedur
bez utraty ich zgodnoci z dotychczasowymi wywoaniami, a wic bez koniecznoci
modyfikowania istniejcych wywoa. Przypumy na przykad, e udostpniamy modu z rewolucyjn funkcj nazwan #!, ktra dodaje dwie liczby cakowite:
: A""2/"?8"
8"
6
-
B8<"2C"?6
6

Po jakim czasie stwierdzamy, e musimy zaktualizowa t funkcj w taki sposb, by


umoliwiaa sumowanie trzech liczb cakowitych. Nie jestemy jednak przekonani co
do susznoci takiego posunicia, poniewa dodanie jeszcze jednego parametru uniemoliwi kompilowanie istniejcego kodu, w ktrym ta funkcja jest wywoywana. Na
szczcie okazuje si, e dziki domylnym parametrom moemy rozszerzy funkcjonalno funkcji #!, nie powodujc adnych niezgodnoci w istniejcym kodzie.
Oto przykad takiego rozwizania:
: A""2/"?8"
6"D8"
<=6
-
B8<"2C"?C"D6
6

W oglnoci, jeli chcesz zwikszy funkcjonalno funkcji lub procedur i jednoczenie


zachowa zgodno z dotychczasowymi wywoaniami, powiniene raczej stosowa
funkcje i procedury przecione zamiast domylnych wartoci parametrw. Wykonywanie
procedur i funkcji przecionych jest nie tylko bardziej efektywne, ale take zapewnia
wiksz zgodno z pozostaymi jzykami programowania platformy .NET, poniewa
domylne wartoci parametrw nie s obsugiwane w takich jzykach jak C# czy
zarzdzany C++.

Rozdzia 5.  Jzyk Delphi

85


By moe jeste przyzwyczajony do deklarowania zmiennych na zawoanie, czyli
zgodnie z zasad, e jeli w danym miejscu potrzebujesz kolejnej liczby cakowitej, deklarujesz j w rodku bloku kodu, bezporednio przed wyraeniem, w ktrym jest Ci
potrzebna. Takie przyzwyczajenia wystpuj bardzo czsto wrd programistw, ktrzy
przez lata wykorzystywali inne jzyki programowania, takie jak C# czy Visual Basic
.NET. Jeli taki sposb deklarowania zmiennych nie jest Ci obcy, bdziesz musia si
przyzwyczai do zupenie innego modelu wykorzystywania zmiennych w jzyku Delphi. W tym jzyku programowania wszystkie zmienne musz by deklarowane w wyznaczonym do tego celu bloku poprzedzajcym waciwy kod procedury, funkcji lub
programu. By moe do tej pory podchodzie do problemu lokalizowania deklaracji
zmiennych bardzo swobodnie i tworzye funkcje podobne do poniszej:
- 9:

E<26
ECC6
 <?6
: :6
333 333


W jzyku Delphi taki kod musi by uporzdkowany i dostosowany do odpowiedniej


struktury w tym przypadku nasza procedura powinna wyglda nastpujco:

 
#6
9

E/ 8"
6
:8$-6
-
E8<26
 E6
 8<?6
333 333
6

Rnicowanie maych i wielkich liter oraz uywanie wielkich liter w kodzie rdowym
W jzyku programowania Delphi podobnie jak w jzyku Visual Basic .NET, ale inaczej ni w jzyku
C# mae i wielkie litery s traktowane tak samo. W Delphi rna wielko liter ma na celu jedynie uatwienie czytania kodu, zatem peni podobn rol jak style wykorzystywane w ksikach.
Jeli identyfikator funkcji, procedury, zmiennej lub innego elementu skada si z wielu poczonych sw, powinnimy pamita o stosowaniu wielkiej litery na pocztku kadego sowa skadajcego si na taki identyfikator. Przykadowo ponisza nazwa procedury jest niejasna i trudna do
odczytania:

 
    
 
 6

Taki kod jest by moe interesujcy, jednak z punktu widzenia osoby czytajcej, znacznie lepsza
jest nastpujca posta:

 
  &  )
 
,F G
  H  6

86

Cz II  Jzyk programowania Delphi for .NET


By moe zastanawiasz si, jaki jest cel stosowania tak cisej struktury i jakie korzyci z tego pyn. Po jakim czasie programowania w tym jzyku z pewnoci zgodzisz
si z tez, e styl jzyka programowania Delphi z jednoznaczn struktur deklarowania
zmiennych uatwia czytanie i konserwacj kodu, a take pozwala unikn wielu bdw,
ktre czsto wystpujc w jzykach pozbawionych tak surowych wymaga.
Zwr uwag na moliwy w jzyku Delphi sposb grupowania w jednym wierszu wicej ni jednej zmiennej (w tym przypadku wikszej liczby parametrw) tego samego
typu, zgodnie z nastpujc regu skadniow:
;
& 2/;
& ?84 6

Dziki temu nasz kod opracowany w jzyku programowania Delphi moe by znacznie
bardziej skondensowany i czytelny ni podobne deklaracje w innych jzykach, np. C#,
w ktrych kada zmienna lub parametr musi mie osobno okrelony typ.
Pamitaj, e kiedy deklarujesz zmienn w jzyku Delphi, nazwa tej zmiennej musi wystpowa przed jej typem, a pomidzy zmiennymi i typami koniecznie musi si znajdowa znak dwukropka. W przypadku zmiennych lokalnych inicjalizacja zmiennej jest
zawsze oddzielona od jej deklaracji.
Jzyk programowania Delphi zezwala na inicjalizowanie zmiennych globalnych ju w bloku
ich deklaracji (). Oto kilka przykadw demonstrujcych skadni takich operacji:
9

8"
<2=6
48
<>I  >6
$8$-<D32J2KLM6

Preinicjalizacja zmiennych jest dozwolona wycznie w przypadku zmiennych globalnych


nie jest moliwa w przypadku lokalnych zmiennych wykorzystywanych w procedurach
lub funkcjach.
Inicjalizacja wartoci zero
Specyfikacja rodowiska CLR zakada, e wszystkie zmienne s automatycznie inicjalizowane
wartoci 0. Kiedy uruchamiana jest nasza aplikacja lub wywoywana jest jedna z naszych funkcji,
wszystkie zmienne cakowitoliczbowe bd reprezentoway warto $, wszystkie zmienne
zmiennoprzecinkowe bd reprezentoway warto $%$, wszystkie obiekty bd miay warto
, wszystkie acuchy bd puste itd. Oznacza to, e inicjalizowanie w kodzie rdowym
zmiennych wartoci zero mija si z celem.
Inaczej ni w wersjach Delphi dla platformy Win32 automatyczne inicjalizowanie zmiennych dotyczy zarwno zmiennych lokalnych, jak i zmiennych globalnych.


W jzyku Delphi stae s definiowane za pomoc klauzuli !, ktrej znaczenie jest
podobne do znaczenia sowa kluczowego ! znanego z jzyka programowania C#.
Oto przykad trzech deklaracji staych w jzyku C#:

Rozdzia 5.  Jzyk Delphi

87

-  : A$  &-


<D32J6
-  <2=6
-  4
%


4
<N&-  O/&-  O/
&-  OPN6

Gwna rnica pomidzy staymi definiowanymi w jzyku C# a staymi jzyka Delphi


polega na tym, e w tym drugim jzyku (podobnie jak w jzyku Visual Basic .NET) nie
jest wymagane podanie typu staej w jej deklaracji. Kompilator Delphi automatycznie
przydziela waciwy typ dla staej w oparciu o jej warto lub w przypadku staych
skalarnych (np. liczb cakowitych typu !&) kompilator zachowuje jedynie wartoci staych, bez przydzielania im odpowiedniej przestrzeni w pamici. Oto przykad
deklaracji staych w jzyku Delphi:

A$  &-
<D32J6
<2=6
%


4
<>&-  O/&-  O/&-  OP>6

Moemy take wprost okrela typy staych w bloku ich deklaracji. W ten sposb moemy
w peni kontrolowa sposb traktowania tych staych przez kompilator Delphi:

A$  &-
8$-<D32J6
8"
<2=6
%


4
8
<>&-  O/&-  O/&-  OP>6

Bezpieczestwo typw staych z okrelonymi typami


Stae z okrelonymi typami maj jedn zasadnicz przewag nad staymi z typami automatycznie przypisywanymi przez kompilator w przypadku staych bez jawnie zadeklarowanych typw
(z typami przypisywanymi dopiero w fazie kompilacji) nie jest moliwe wywoywanie metod odpowiednich obiektw. Przykadowo, poniszy fragment kodu jest prawidowy:

"8"
<2ML2=L=J6
48
6
-
48<"34
6

Natomiast fragment przedstawiony poniej jest bdny (nie zostanie skompilowany):



"<2ML2=L=J6
48
6
-
48<"34
6

Reguy jzyka Delphi zezwalaj na stosowanie w deklaracjach ! i  (odpowiednio


staych i zmiennych) tzw. funkcji czasu kompilacji. Do tego zbioru nale takie funkcje
jak , ', (" , )", &', *, #+,
, " , &!',
 oraz ,. Przykadowo, cay poniszy kod jest prawidowy:
 
A<

Q233?R:"
6

88

Cz II  Jzyk programowania Delphi for .NET



8I
<4 ':G 6
9

8"
<S6
 84 "<'
> >6
*8*"<
 D32J2KM6
E845
"<B?3L2S?S6
G28G <75A6
G?8G <*A6
H8H5
<H5
J@6

Aby zapewni zgodno z wczeniejszymi wersjami, kompilator Delphi udostpnia


przecznik umoliwiajcy przypisywanie wartoci staym z jawnie zadeklarowanymi
typami (a wic operowanie na tych staych w taki sam sposb jak na zmiennych
typw). Odpowiedni przecznik jest dostpny na zakadce Compiler (kompilator)
okna dialogowego opcji projektu lub poprzez dyrektyw kompilatora -)(#. (
(lub  ). Pamitaj jednak, e stosowanie tej opcji nie jest zalecane, co oznacza,
e powiniene jej unika i jeli nie jest to konieczne nie wcza tej opcji
kompilatora.
Podobnie jak jzyki C# i Visual Basic .NET, take jzyk programowania Delphi
nie wykorzystuje tzw. preprocesora, ktry jest stosowany np. w jzyku C. W jzyku
Delphi nie istnieje pojcie makra, zatem nie ma moliwoci stosowania konstrukcji
rwnowanych np. znanym z jzyka C deklaracjom staych . Chocia w jzyku
Delphi moemy wykorzystywa dyrektyw kompilatora  dla kompilacji
warunkowych (a wic podobnie do odpowiedniego zastosowania dyrektywy 
w jzyku C), dyrektywa ta nie moe suy definiowaniu staych. Wszdzie tam, gdzie
w jzyku C zadeklarowaby sta za pomoc dyrektywy , w jzyku Delphi
powiniene stosowa klauzul !.

! 
Operatory s symbolami wykorzystywanymi w kodzie programu do manipulowania
wszystkimi rodzajami danych. Przykadowo, istniej operatory dodawania, odejmowania, mnoenia i dzielenia danych numerycznych. Istniej take operatory odwoywania
si do konkretnych elementw tablic. W tym podrozdziale wyjanimy niektre spord
operatorw dostpnych w jzyku programowania Delphi i porwnamy je z ich odpowiednikami w jzyku C# i rodowisku CLR.



Jeli nigdy nie pracowae w jzyku programowania Pascal, wykorzystywany w tym jzyku (a wic take w rodowisku i jzyku Delphi) operator przypisania moe by tym
elementem, do ktrego najtrudniej bdzie Ci si przyzwyczai. Aby przypisa danej
zmiennej jak warto, w Delphi uywamy operatora /0; do tej samej operacji w jzykach C# i Visual Basic .NET uylibymy operatora 0. W odniesieniu do tego operatora
programici Delphi uywaj niekiedy okrelenia otrzymuje lub jest przypisywana, zatem
wyraenie w postaci:

Rozdzia 5.  Jzyk Delphi

89

&-
28<K6

czytaj: zmienna "1+2 otrzymuje warto 3 lub warto 3 jest przypisywana do


zmiennej "1+2.




Jeli programowae ju w jzyku Visual Basic .NET, nie powiniene mie adnych
problemw z operatorami porwnania stosowanymi w jzyku Delphi, poniewa operatory wykorzystywane w obu jzykach s niemal identyczne. Operatory tego typu s
standardem prawie we wszystkich jzykach programowania, zatem nie bdziemy ich w tym
podrozdziale szczegowo omawiali.
W jzyku Delphi do logicznego porwnania dwch wyrae lub wartoci wykorzystuje
si operator 0. Stosowany w tym jzyku operator 0 odpowiada stosowanemu w jzyku
C# operatorowi 00, co oznacza, e instrukcja warunkowa C# w postaci:
:E<< 

w jzyku Delphi wygldaaby nastpujco:


:E<

Pamitaj, e w jzyku Delphi operator /0 jest wykorzystywany do przypisywania wartoci


zmiennym, natomiast operator 0 suy jedynie porwnywaniu wartoci dwch operandw
(nigdy operacji przypisania).

Operatorem nierwnoci w jzyku Delphi jest 45. Znaczenie tego operatora jest identyczne jak znaczenie operatora 60 w jzyku programowania C#. Aby okreli, czy dwa
wyraenia (lub wartoci) s od siebie rne, w jzyku Delphi wykorzystujemy nastpujcy kod:
:ETU 5$456

 

W jzyku programowania Delphi operatory logiczne i oraz lub wyraa si za pomoc sw odpowiednio  i  t sam funkcj w jzyku C# peni odpowiednio
symbole 77 oraz 88. Operatory logiczne  i  najczciej wykorzystuje si w instrukcjach warunkowych  oraz ptlach (patrz dwa ponisze przykady):
:  
5
$456
5 


$456

Logicznym operatorem negacji w jzyku programowania Delphi jest sowo ! sowo
to jest wykorzystywane do zaprzeczania wyraeniom logicznym definiowanym w tym
jzyku. W jzyku C# t sam rol peni symbol 6. Sowo ! jest czsto wykorzystywane w instrukcjach warunkowych . Oto przykad:
: 5  6 
: :   /V 333

90

Cz II  Jzyk programowania Delphi for .NET


W tabeli 5.1 zestawiono operator przypisania, operatory porwnania i operatory logiczne stosowane w jzyku programowania Delphi wraz z ich odpowiednikami wykorzystywanymi w jzykach C# i Visual Basic .NET.

  Operator przypisania, operatory porwnania i operatory logiczne

  

 





Przypisanie

8<

<

<

Porwnanie

<

<<

< lub "1

Rne

TU

P<

TU

Mniejsze

Wiksze

Mniejsze lub rwne

T<

T<

T<

Wiksze lub rwne

U<

U<

U<

Logiczne i



WW

A

Logiczne lub

XX

'

Logiczne nie



&

Logiczne lub wyczajce

E

Z

 

Ju teraz powiniene dobrze zna wikszo operatorw arytmetycznych stosowanych
w jzyku Delphi, poniewa w wikszoci przypadkw te same operatory wykorzystuje
si w innych popularnych jzykach programowania. W tabeli 5.2 przedstawiono wszystkie
operatory arytmetyczne Delphi wraz z ich odpowiednikami stosowanymi w jzykach C#
i Visual Basic .NET.
 Operator przypisania, operatory porwnania i operatory logiczne

  

 





Dodawanie

Odejmowanie

Mnoenie

Dzielenie zmiennoprzecinkowe

Dzielenie cakowite

9

Modulo



(

Potga

Brak

Brak

W jzyku programowania Visual Basic .NET  jest operatorem porwnania wykorzystywanym dla
obiektw, natomiast 0 jest operatorem porwnania stosowanym dla wszystkich pozostaych typw.

Rozdzia 5.  Jzyk Delphi

91

By moe zwrcie uwag na to, e w jzykach Delphi i Visual Basic .NET wykorzystuje
si rne operatory dla operacji dzielenia zmiennoprzecinkowego i dzielenia cakowitoliczbowego, chocia w jzyku C# dla obu tych operacji stosuje si ten sam operator.
Operator  automatycznie obcina ewentualn reszt z dzielenia dwch wyrae cakowitoliczbowych.
Pamitaj o stosowaniu waciwych operatorw dzielenia dla wykorzystywanych
wyrae rnych typw. Kompilator Delphi wygeneruje komunikat o bdzie, jeli
sprbujesz podzieli dwie liczby zmiennoprzecinkowe za pomoc operatora dzielenia
cakowitego  lub jeli podejmiesz prb przypisania zmiennej cakowitoliczbowej
wyniku dzielenia dwch liczb cakowitych za pomoc operatora 9; ilustruje to poniszy
fragment kodu:
9

8"
6
8$-6
-
8<JD6
  - 
3
8<D3J9?3D6 0
  -3
6

Jeli musisz podzieli dwie liczby cakowite za pomoc operatora 9, otrzymany wynik
moesz przypisa zmiennej cakowitoliczbowej tylko w sytuacji, gdy uprzednio
przekonwertujesz to wyraenie na liczb cakowit za pomoc funkcji (" 
(obcicie czci uamkowej) lub )" (zaokrglenie).


Operatory bitowe umoliwiaj nam modyfikowanie pojedynczych bitw danej zmiennej
cakowitoliczbowej. Do najczciej stosowanych operatorw binarnych nale operatory
przesunicia bitw w lewo lub w prawo, a take logiczne operatory i, nie, lub
oraz lub wyczajcego dla par liczb cakowitych. W jzyku Delphi operatorami przesunicia w lewo i przesunicia w prawo s odpowiednio symbole ' i ' ich dziaanie
jest identyczne jak w przypadku znanych z jzyka C# operatorw 44 i 55. Pozostae
operatory binarne stosowane w jzyku programowania Delphi s bardzo atwe do zapamitania: , !,  i :. Wszystkie operatory bitowe tego jzyka (wraz z odpowiednimi operatorami wykorzystywanymi w jzykach C# i Visual Basic .NET) przedstawiono
w tabeli 5.3.
 Operatory bitowe

  

 







A

Nie



&

Lub

'

Lub wyczajce

E

Z

Przesunicie w lewo

5

TT

Brak

Przesunicie w prawo

5

UU

Brak

92

Cz II  Jzyk programowania Delphi for .NET

  

!

Operatory zwikszania i zmniejszania s wygodnym narzdziem wykorzystywanym do
dodawania i odejmowania wartoci od zmiennych cakowitoliczbowych. Jzyk Delphi
nie obsuguje co prawda operatorw zwikszania i zmniejszania podobnych do bardzo
popularnych wrd programistw jzyka C# operatorw ;; i <<, ale udostpnia procedury
  i  , ktre dziaaj w ten sam sposb.
Procedury   i   moemy wywoywa z jednym lub z dwoma parametrami. Przykadowo, zademonstrowane poniej dwa wiersze kodu odpowiednio zwikszaj i zmniejszaj zmienn + o 2:
" 9
 -6
$ 9
 -6

Dwa ponisze wiersze kodu odpowiednio zwikszaj i zmniejszaj zmienn + o =:


" 9
 -/D6
$ 9
 -/D6

W tabeli 5.4 zestawiono operatory zwikszania i zmniejszania wykorzystywane w rnych jzykach programowania.
 Operatory zwikszania i zmniejszania

  

 





Zwikszenie

" 

CC

Brak

Zmniejszenie

$ 

[[

Brak

Zwr uwag na rnic w sposobie dziaania operatorw w jzyku C# operatory ;;


i << zwracaj warto, czego nie robi wykorzystywane w jzyku Delphi procedury
  i  . Wartoci s zwracane przez dostpne w jzyku Delphi funkcje " 
i
, jednak adna z tych funkcji nie modyfikuje otrzymanego parametru.

"#
Jzyk Delphi nie oferuje wygodnych operatorw typu zrb i przypisz, ktre znamy
np. z jzyka programowania C#. Takie operatory (np. ;0 i >0) wykonuj operacje arytmetyczne (w tym przypadku odpowiednio dodawanie i mnoenie) jeszcze przed przeprowadzeniem operacji przypisania. W jzyku Delphi tego typu operacje musz by
wykonywane przez zastosowanie dwch osobnych operatorw. Oznacza to, e poniszy
fragment kod napisanego w jzyku C#:
EC<K6

miaby nastpujc posta w jzyku Delphi (pozbawionym wygodnych operatorw typu


zrb i przypisz):
E8<ECK6

Rozdzia 5.  Jzyk Delphi

93

!"# ! 
Jedn z najwikszych zalet jzyka programowania Delphi jest dua liczba dostpnych
typw, ktra sprawia, e jzyk ten doskonale nadaje si do programowania aplikacji dla
platformy .NET Framework. Zaoenia przyjte przez twrcw tej platformy przewiduj
konieczno zapewniania zgodnoci rzeczywistych typw zmiennych przekazywanych do
procedur i funkcji z formalnymi identyfikatorami tych parametrw w definicjach procedur lub funkcji w praktyce oznacza to, e sam musisz pamita o konwersji typw.
Waciwoci jzyka Delphi w zakresie obsugi typw umoliwiaj przeprowadzania odpowiednich testw kodu rdowego, ktry ma na celu zapewnienie zgodnoci stosowanych typw. W kocu najatwiejsze do usunicia s te bdy, o ktrych poinformuje
nas kompilator!

 $  %


Jednym z najwaniejszych zagadnie zwizanych z podstawowymi typami obsugiwanymi przez kompilator Delphi for .NET jest moliwo konwersji wszystkich typw
wartociowych do postaci odpowiednich klas. Konwersja zmiennej typu wartociowego
do postaci obiektu i konwersja obiektu w zmienn typu wartociowego w terminologii
przyjtej przez programistw aplikacji .NET jest okrelana odpowiednio jako opakowywanie (ang. boxing) oraz odpakowywanie (ang. unboxing). Liczby cakowite, acuchy,
liczby zmiennoprzecinkowe i wszystkie inne typy wartociowe nie s ju implementowane w postaci typw prostych kompilatora (tak jak w przypadku platformy Win32), ale
s odwzorowywane do typw wartociowych obsugiwanych albo przez platform .NET
Framework, albo przez bibliotek RTL lub VCL firmy Borland. Inaczej ni w wersjach
Delphi dla platformy Win32 te typy wartociowe mog mie wasne procedury i funkcje,
ktre rozszerzaj funkcjonalno metod dostpnych w odpowiednich klasach wykorzystywanych podczas realizowanego w tle opakowywania i odpakowywania tych typw.
Taki mechanizm umoliwia stosowanie konstrukcji skadniowych, ktre nie byy wykorzystywane w rdzennych kompilatorach (chocia wydaj si zupenie naturalne dla programistw, ktrzy mieli do czynienia z takimi jzykami jak Java czy SmallTalk):
9

48
6
"8"
6
-
"8<J?6
48<"34
6(0 V-  ^1  "
P

Typ !& jest wykorzystywany podczas tworzenia aplikacji szczeglnie czsto. Nie
oznacza to, e inne typy s mniej wane, jednak wielu programistw ocenia jzyki
programowania wanie pod ktem moliwoci w zakresie przetwarzania acuchw.
acuchom powicimy cay rozdzia 11., zatem nie bdziemy ich szczegowo
omawiali w tym miejscu.

94

Cz II  Jzyk programowania Delphi for .NET

&

Jzyk programowania Delphi wyrnia si przede wszystkim du liczb typw prostych
obsugiwanych w rodowisku uruchomieniowym CLR. W tabeli 5.5 zestawiono i porwnano ze sob podstawowe typy wystpujce w jzyku Delphi, w jzyku C# oraz obsugiwane w rodowisku CLR. Tabela zawiera take informacje o zgodnoci poszczeglnych typw ze specyfikacj CLS.
 Zestawienie typw stosowanych w jzyku Delphi, w jzyku C# i obsugiwanych
w rodowisku CLR
  !""#

 



$%

&'"()
 #*+,
$-

8-bitowa liczba cakowita ze znakiem

45
"

- 

4 34G 

Nie

8-bitowa liczba cakowita bez znaku

G 

- 

4 3G 

Tak

5


4 3"2@

Tak

16-bitowa liczba cakowita ze znakiem 4 "


16-bitowa liczba cakowita bez znaku

I


32-bitowa liczba cakowita ze znakiem "

32-bitowa liczba cakowita bez znaku

H
 

64-bitowa liczba cakowita ze znakiem "@J

5


4 3+"2@

Nie



4 3"D?

Tak



4 3+"D?

Nie



4 3"2@J

Tak

64-bitowa liczba cakowita bez znaku

+"@J



4 3+"2@J

Nie

Liczba zmiennoprzecinkowa
pojedynczej precyzji

4

: 

4 34

Tak

Liczba zmiennoprzecinkowa
podwjnej precyzji

$-

-

4 3$-

Tak

Staoprzecinkowa liczba dziesitna

Brak

  

4 3$  

Tak

Staoprzecinkowa liczba dziesitna


Delphi

H



Brak

Brak

Nie

Data-czas

$ 2

Brak

4 3$ 

Tak

Wariant

;
 ,
';
 

Brak

Brak

Nie

1-bajtowy znak

AH5

Brak

Brak

Nie

2-bajtowy znak

H5
, IH5

4 3H5

Tak

acuch bajtowy staej dugoci

45
4


Brak

Brak

Nie

Dynamiczny acuch 1-bajtowy

A4


Brak

Brak

Nie

Dynamiczny acuch 2-bajtowy


,
I4





4 34


Tak

Warto logiczna

G 

-

4 3G 

Brak

Typ $  jest rekordem doczajcym do klasy 4 3$  metody i przecione operatory,
ktre tylko w minimalnym stopniu wpywaj na zachowanie 4 3$ , ale jednoczenie zapewniaj
zgodno z typem $  stosowanym w jzyku Delphi dla platformy Win32.

Rozdzia 5.  Jzyk Delphi

95

&
 
Jzyk Delphi obsuguje trzy typy znakowe:


-' ten typ znakowy (zgodny ze specyfikacj CLS) ma rozmiar dwch

bajtw i reprezentuje pojedynczy znak w formacie Unicode.




' ten typ jest jedynie aliasem typu -'. W wersji Delphi dla
platformy Win32 typ ' by aliasem typu #'.

#' ten typ reprezentuje pojedynczy znak w przestarzaym,

jednobajtowym formacie ANSI.


W swoim kodzie nigdy nie powiniene z gry zakada rozmiaru zmiennej typu '
(ani adnego innego typu). Zamiast staych wartoci odczytanych ze specyfikacji w odpowiednich miejscach zawsze powiniene stosowa funkcj ,.
Standardowa procedura 4 ': zwraca wyraany w bajtach rozmiar typu lub zmiennej.

'

Klasa ! jest ciekaw implementacj idei pojemnika dla wielu innych typw.
Oznacza to, e w czasie wykonywania programu moemy zmienia rodzaj reprezentowanych danych w ramach wariantu. Przykadowo, poniszy fragment kodu zostanie
prawidowo skompilowany i wykonany:
9

;8;
 6
"8""
: 6
-
;8<>$5 
P>6
 
 5  O  5
;8<26
 
 5 
 -1 
;8<2?D3DJ6
 
 5 
 -1 
 
;8<
6
 
 5 

^ 
;8<"6
 
 5 

: 
6

Warianty obsuguj szeroki zakres typw, wcznie z tak skomplikowanymi typami jak
tablice czy interfejsy. Poniszy fragment kodu skopiowany z moduu .% %!
dobrze pokazuje mnogo obsugiwanych typw, ktre s identyfikowane za pomoc
specjalnych wartoci, tzw. typw ((?@:
 
;
 <"
6
$ 1 XA
     V
9
% <!====6<=X+ /&
9
&<!===26<2X&/4 3$G&
9
4 "<!===?6<?X"?/4 3"2@
9
"
<!===D6<DX"J/4 3"D?
9
4<!===J6<JXBJ/4 34
9
$-<!===K6<KXBS/4 3$-
9
H

 <!===@6<@XG
 3$534 3H



96

Cz II  Jzyk programowania Delphi for .NET


9
$ <!===L6<LXG
 3$534 3$ 
9
4
<!===S6<SXI4
/4 34

9
%


<!===A6<2=X%E /4 3%E 
9
G <!===G6<22XG/4 3G 
9
'-  <!===H6<2?X'-  /4 3'-  
9
$  <!===%6<2JX4 3$  
9
45
"<!==2=6<2@X"2/4 34G 
9
G <!==226<2LX+2/4 3G 
9
I
<!==2?6<2SX+?/4 3+"2@
9
*I
<!==2D6<2MX+J/4 3+"D?
9
"@J<!==2J6<?=X"S/4 3"@J
9
+"@J<!==2K6<?2X+S/4 3+"2@
9
H5
<!==2@6<??XIH5
/4 3H5

9
$ <!==2L6<?DX4 3$ 6
9
#
<9
% 6
9
* <9
$ 6
9
A

<!?===6<?X4 3A

/$   A


9
 ( <!=###6<?
9
+:<[26

W razie wystpienia takiej koniecznoci warianty umoliwiaj przeksztacanie samych


siebie w dowolne obsugiwane typy w czasie wykonywania funkcji przypisania wartoci.
Przykadowo:
9

;8;
 6
"8"
6
-
;8<>2>6;
 5 >2>
"8<;6&  
  "
6"

  

^2
6


    
W jzyku Delphi moemy wprost rzutowa typy wyrae na typ !. Przykadowo,
wynikiem wywoania w postaci:
;
 Z6

jest typ !, ktrego kod typu (((?@) odpowiada wynikowi wyraenia A moe
to by liczba cakowita, liczba zmiennoprzecinkowa, staoprzecinkowa liczba dziesitna
Delphi (" ?), acuch, znak, data-czas, klasa lub warto logiczna.
Moemy take przeprowadza rzutowanie typw w drug stron od wariantu do odpowiedniego typu prostego. Przykadowo, jeli mamy w kodzie instrukcj przypisania
w postaci:
;8<23@6

gdzie  jest zmienn typu !, po wykonaniu poniszych instrukcji przypisania


otrzymamy wyniki zgodne z treci zawart w komentarzach:
48<
;6  4-1  
  O  5>23@>
  "  
   -0   -    
 ?

Rozdzia 5.  Jzyk Delphi

97

"8<"
;6
G8<G ;6  G 

^
/ 0; 
V0=
$8<$-;6  $ 

^23@

Otrzymane rezultaty wynikaj z konkretnych regu konwersji typw przyjtych dla typw
wariantowych. Reguy konwersji szczegowo zdefiniowano w dokumentacji jzyka Delphi.
Nawiasem mwic, w powyszych przykadach instrukcji przypisania niepotrzebnie zastosowalimy rzutowanie typw wariantowych na pozostae typy danych. Poniszy fragment kodu bdzie dziaa tak samo:
;8<23@6
48<;6
"8<;6
G8<;6
$8<;6

Kiedy w jednym wyraeniu zastosujemy wiele zmiennych typu !, moe si okaza,
e w zwizku z niejawnymi (wykonywanymi w tle) operacjami wymuszania odpowiednich typw faktycznie wykonywanych jest znacznie wicej instrukcji ni zdefiniowalimy w naszym wyraeniu. Jeli w takich przypadkach masz absolutn pewno co do typw
przechowywanych w wariantach, lepszym rozwizaniem bdzie zastosowanie w wyraeniu jawnego rzutowania typw, ktre przyspieszy jego przetwarzanie.

    


 
Warianty moemy stosowa w wyraeniach z nastpujcymi operatorami: ;, <, >, 9, , 1,
', ', , , :, !, /0, 0, 45, 4, 5, 40 oraz 50. Take standardowe funkcje  ,
 , ("  i )" s poprawnymi skadnikami wyrae ze zmiennymi wariantowymi.
Kiedy stosujemy warianty w wyraeniach, kompilator Delphi podejmuje decyzje odnonie
wykonywanych operacji w oparciu o typy przechowywane w tych wariantach. Przykadowo, jeli dwa warianty, 2 i B, zawieraj liczby cakowite, wynikiem wyraenia
2C;CB bdzie suma tych dwch liczb cakowitych (a wic take liczba cakowita). Jeli
jednak zmienne wariantowe 2 i B zawieraj acuchy, wynikiem takiego samego wyraenia bdzie konkatenacja tej pary acuchw. Jaki jednak bdzie wynik podobnego
wyraenia, jeli uyte warianty 2 i B zawieraj dwa rne typy danych? W Delphi
wykorzystuje si specjalne reguy opisujce sposb postpowania w tego typu sytuacjach.
Przykadowo, jeli zmienna 2 zawiera acuch DE%3D, a zmienna B zawiera liczb
zmiennoprzecinkow, zmienna 2 zostanie przekonwertowana do postaci liczby zmiennoprzecinkowej i nastpnie dodana do liczby reprezentowanej przez zmienn B. Ilustruje
to poniszy fragment kodu:
9

;2/;?/;D8;
 6
-
;28<>2==>6 O  5
;?8<>K=>6 O  5
;D8<?==6 -  
;28<;2C;?C;D6
6

98

Cz II  Jzyk programowania Delphi for .NET


Zgodnie z tym, o czym wspomnielimy odnonie specjalnych regu jzyka Delphi, na
pierwszy rzut oka wydaje si, e efektem wykonania powyszego kodu bdzie przypisanie
zmiennej 2 liczby cakowitej rwnej =3$. Jeli jednak przeanalizujemy ten fragment
nieco dokadniej, okae si, e w tym przypadku bdzie zupenie inaczej. Poniewa
domylna kolejno wykonywania dziaa przewiduje pierwszestwo skrajnie lewego
operatora, najpierw zostanie wykonana operacja dodawania 2C;CB. Poniewa oba operandy s wariantami reprezentujcymi acuchy, wykonana zostanie ich konkatenacja,
a zatem otrzymamy acuch D2$$3$D. Do tego wyniku zostanie nastpnie dodana
warto przechowywana w wariancie =. Poniewa = jest liczb cakowit, wynik pierwszej operacji (D2$$3$D) zostanie przekonwertowany do postaci liczby cakowitej (2$$3$)
i dodany do wartoci =, a wic efektem caej operacji przypisania bdzie warto
2$B3$ w wariancie 2.
W jzyku Delphi warianty s przeksztacane do postaci najwikszych typw numerycznych uytych w wyraeniu, co w wikszoci przypadkw gwarantuje poprawno
otrzymanego wyniku. Jeli jednak wyraenie zawiera dwa warianty, ktrych kompilator
Delphi nie moe w aden sensowny sposb do siebie dopasowa, generowany jest wyjtek !(?@!. Tak sytuacj ilustruje poniszy fragment kodu:
9

;2/;?8;
 6
-
;28<LL6
;?8<> >6
;28<;2;?6
  
  
6

Jak ju wspomnielimy, w niektrych sytuacjach warto jawnie rzutowa typ wariantowy


na konkretny typ danych dotyczy to tych przypadkw, w ktrych dokadnie wiemy,
jakie typy powinny by zastosowane w wyraeniu i jakie typy faktycznie w tym wyraeniu wystpuj. Przeanalizujmy poniszy wiersz kodu:
;J8<;2;?;D6

Zanim moliwe bdzie wygenerowanie wyniku tego wyraenia, kada operacja jest obsugiwana przez funkcj czasu wykonywania, ktra analizuje j na wszystkie sposoby
celem okrelenia zgodnoci typw reprezentowanych przez par operandw (w tym
przypadku zmiennych wariantowych). Dopiero po przeprowadzeniu wnikliwej analizy
wykonywane s operacje konwersji do waciwych typw. Taka technika przetwarzania
wyrae wie si oczywicie z dodatkowymi kosztami czasowymi i zwikszonym
rozmiarem kodu. Lepszym rozwizaniem jest wic w takim przypadku rezygnacja ze
stosowania wariantw. Jeli jednak wykorzystanie wariantw jest w danym programie
konieczne, moemy take zastosowa dla tych zmiennych jawne rzutowanie typw, dziki
czemu wszystkie niezbdne operacje uzgadniania typw bd wykonywane ju w fazie
kompilacji:
;J8<"
;2$-;?"
;D6

Pamitaj, e rozwizanie z jawnym rzutowaniem typw wymaga od Ciebie znajomoci


typw danych, do ktrych uyte warianty mog by bezpiecznie konwertowane.

Rozdzia 5.  Jzyk Delphi

99

  


 
Dwie specjalne wartoci zmiennych wariantowych wymagaj krtkiego omwienia.
Pierwsz z tych wartoci jest & (nieprzypisana), ktra oznacza, e danemu wariantowi nie przypisano jeszcze adnej wartoci. & jest wartoci pocztkow
kadego wariantu. Drug z tych wartoci jest ", ktra tym si rni od wartoci
&, e reprezentuje przypisan warto, a nie brak jakiejkolwiek wartoci. Rozrnienie pomidzy brakiem wartoci a wartoci " jest szczeglnie wane w przypadku
ich stosowania w tabelach bazy danych. Wicej informacji na temat programowania
aplikacji baz danych znajdziesz w czci IV, Programowanie aplikacji bazodanowych
z wykorzystaniem technologii ADO.NET.
Kolejna rnica pomidzy tymi wartociami jest widoczna w momencie wykonywania
operacji na reprezentujcych je wariantach zastosowanie jakiejkolwiek operacji dla
wariantu zawierajcego warto & powoduje przeksztacenie tej wartoci w liczb $ (w przypadku operacji numerycznych) lub acuch pusty (w przypadku operacji na
acuchach). Inaczej jest w przypadku wariantw z wartoci " kiedy wykorzystamy taki wariant w wyraeniu, prba wykonania na nim operacji moe spowodowa
wygenerowanie wyjtku !(?@!.
Jeli chcemy zastosowa operacj przypisania lub porwnania wariantu z jedn z tych
dwch specjalnych wartoci, moemy wykorzysta odpowiednie warianty zdefiniowane
w module ?!1% %! (nazwane odpowiednio & i ").
Kontrolowanie zachowania wariantw
Ustawienie wartoci (" dla waciwoci !%"! !@! umoliwia nam kontrol
nad generowaniem wyjtkw w przypadku wykonywania operacji arytmetycznych na wariantach
z wartoci ". Poniej wymieniono pozostae przeczniki (flagi) umoliwiajce kontrolowanie
zachowa wariantw z wartoci " w przypadku ich konwersji do postaci acuchw i wartoci
logicznych.
&%_  B8&H
B6
&( B8&H
B6
&A4
; 8
6
&4
 H'9
8G 6
G 4
B8G 4
B6
G 
A'
 ; 8"
6

!  $ ! %$ 


Liczby cakowite, acuchy i liczby zmiennoprzecinkowe czsto nie s wystarczajcymi
rodkami do waciwego reprezentowania zmiennych wykorzystywanych podczas rozwizywania rzeczywistych problemw, przed jakimi staj programici. W podobnych
przypadkach konieczne jest tworzenie wasnych typw, ktre bd lepiej reprezentoway
zmienne niezbdne do rozwizania danego problemu. W jzyku programowania Delphi
takie typy definiowane przez uytkownika (lub po prostu typy uytkownika) zwykle
przyjmuj posta rekordw lub klas definiujemy je za pomoc sowa kluczowego (?@.

100

Cz II  Jzyk programowania Delphi for .NET

' 
Jzyk programowania Delphi umoliwia nam tworzenie tablic dla dowolnych typw
zmiennych. Przykadowo, zmienna zadeklarowana jako tablica omiu liczb cakowitych
bdzie miaa nastpujc posta:
9

A8A

Q=33LR:"
6

Powysza instrukcja jest rwnowana nastpujcej deklaracji napisanej w jzyku programowania C#:
AQSR6

Istnieje take deklaracja rwnowana w jzyku Visual Basic .NET:


$AS "

Tablice stosowane w jzyku Delphi maj specjaln wasno, ktra odrnia je od podobnych struktur stosowanych w innych jzykach programowania indeksy tablic
Delphi nie musz si rozpoczyna od z gry okrelonej liczby (w innych jzykach jest
to liczba $ lub 2). Oznacza to, e moemy zadeklarowa trjelementow tablic, ktra
bdzie si rozpoczynaa od indeksu BF, oto przykad:
9

A8A

Q?S33D=R:"
6

Poniewa nie mamy gwarancji, e tablice stosowane w jzyku Delphi rozpoczynaj si


od indeksu $ lub 2, musimy zachowa ostrono podczas iteracyjnego przegldania
tych tablic w ptli . Kompilator Delphi oferuje wbudowane funkcje nazwane &'
i *, ktre zwracaj odpowiednio grn i doln granic dla zmiennej lub typu tablicowego. Stosujc te funkcje podczas kontrolowania zakresu dla ptli , moesz unikn
wielu bdw i bardzo uatwi konserwowanie swojego kodu rdowego:
9

A8

Q?S33D=R:"
6
8"
6
-
:
8<*A75A4
1
^  1:
P
AQR8<6
6

Do tworzenia tablic wielowymiarowych w jzyku Delphi wykorzystuje si listy zakresw oddzielone przecinkami:
9

 
  -  -  5 "

A8

Q233?/233?R:"
6

Aby uzyska dostp do elementu wielowymiarowej tablicy, naley uy przecinkw


oddzielajcych indeksy poszczeglnych wymiarw:
"8<AQ2/?R6

Rozdzia 5.  Jzyk Delphi

101

' 
 

Tablice dynamiczne s strukturami z dynamicznie przydzielan pamici, a wic s to takie tablice, ktrych wymiary nie s znane w czasie kompilacji programu. Aby zadeklarowa tablic dynamiczn, musimy po prostu uy znanej nam deklaracji tablic, ale bez
okrelania konkretnych wymiarw, oto przykad:
9

     -  O  5V8


4A8

:
6

Zanim bdziemy mogli uy tak zadeklarowanej tablicy, musimy zastosowa procedur


! &!', ktra przydzieli tej tablicy odpowiedni przestrze w pamici:
-

 

O DDV8
4*54A/DD6

Po przydzieleniu pamici moesz ju w normalny sposb (identyczny jak w przypadku


tablic statycznych) uzyskiwa dostp do elementw tablicy dynamicznej:
4AQ=R8<>-) 5 -V>6
8<4AQ=R6

Tablice dynamiczne zawsze s indeksowane poczwszy od wartoci $.

Tablice dynamiczne s zarzdzane w czasie wykonywania przez rodowisko uruchomieniowe platformy .NET, zatem nie ma potrzeby (a w rzeczywistoci nie ma nawet
moliwoci) zwalniania zajmowanej przez nie pamici, poniewa i tak w pewnym momencie (po opuszczeniu pewnego zakresu kodu) zostan usunite przez mechanizm odzyskiwania (odmiecania) pamici. Moesz jednak mie do czynienia z sytuacj, w ktrej
chciaby zada od rodowiska uruchomieniowego .NET usunicia dynamicznej tablicy z pamici jeszcze przed opuszczeniem danego zakresu kodu (np. w przypadku, gdy
taka tablica wykorzystuje zbyt du ilo pamici). W tym celu wystarczy przypisa takiej
zmiennej tablicowej warto :
4A8<60    1    
  - 14A

Zauwa, e przypisanie wartoci  nie powoduje automatycznego zwolnienia pamici


przydzielonej wczeniej tablicy # w ten sposb zwalniamy jedynie jedn referencj
do tej tablicy, poniewa moe istnie wicej ni jedna zmienna wskazujca na tablic,
na ktr wskazywaa take zmienna #. Dopiero po zwolnieniu ostatniej referencji do
tej tablicy dynamicznej wykorzystywany w rodowisku uruchomieniowym .NET mechanizm odzyskiwania pamici zwolni pami zajmowan przez t tablic (ale dopiero
w kolejnym cyklu dziaania tego mechanizmu).
Na tablicach dynamicznych operujemy zgodnie z reguami semantycznymi przyjtymi
dla referencji, a nie wedug zasad semantycznych dla zmiennych wartociowych, w tym
tablic statycznych. Oto szybki test: Jaka bdzie warto elementu #2G$H po wykonaniu
poniszego fragmentu kodu?

102

Cz II  Jzyk programowania Delphi for .NET


9

A2/A?8

:"
6
-
4*5A2/J6
A?8<A26
A2Q=R8<26
A?Q=R8<?@6

Poprawna odpowied brzmi BI, poniewa przypisanie #BC/0C#2 nie tworzy nowej tablicy,
a jedynie sprawia, e #2 jest referencj do tej samej tablicy, na ktr wskazuje zmienna
tablicowa #B. Oznacza to, e wszystkie modyfikacje zmiennej #B spowoduj zmiany
w zmiennej #2. Jeli zamiast tworzenia nowej referencji chcesz skopiowa tablic #2 do
zmiennej #B, powiniene uy standardowej funkcji @?:
A?8<H A26

Po wykonaniu powyszego wiersza kodu, zmienne #B i #2 bd dwiema osobnymi tablicami, ktre pocztkowo bd zawieray te same dane. Zmiany w jednej z tych tablic nie
bd powodoway zmian w drugiej. Dodatkowo moesz wykorzysta opcjonalne parametry funkcji @? do okrelenia elementu pocztkowego i cznej liczby elementw
do skopiowania; poniej przedstawiono przykad takiego zastosowania tej funkcji:
 ? /  
 8
A?8<H A2/2/?6

Podobnie jak tablice statyczne, take tablice dynamiczne mog by wielowymiarowe.


Aby zdefiniowa wicej wymiarw, w deklaracji tablicy dla kadego z wymiarw uyj
dodatkowego wyraenia ?C:
9

 
  -      -  58
"A8

:

:"
6

Aby przydzieli pami takiej wielowymiarowej tablicy, przeka rozmiary dla poszczeglnych wymiarw w postaci dodatkowych parametrw procedury ! &!':
-
"A-1  -  -  5 
5K`K
4*5"A/K/K6

Uzyskiwanie dostpu do elementw dynamicznych tablic wielowymiarowych niczym


nie rni si od sposobu uzyskiwania takiego samego dostpu do wielowymiarowych
tablic statycznych indeksy dla poszczeglnych wymiarw umieszczamy wewntrz
jednej pary nawiasw kwadratowych i oddzielamy przecinkami:
"A=/DR8<?S6

W jzyku programowania Delphi jest take obsugiwana skadnia dostpu do tablic


wielowymiarowych znana z rodziny jzykw C (C, C++, C#):
"AQ=RQDR8<?S6

Rozdzia 5.  Jzyk Delphi

103

( 
Struktura zdefiniowana przez uytkownika jest w jzyku programowania Delphi nazywana rekordem i odpowiada konstrukcji !" ! znanej z jzyka C# oraz konstrukcji (?@
stosowanej w jzyku Visual Basic .NET. Przykadowo, poniej przedstawiono definicj
rekordu w Delphi wraz z rwnowanymi definicjami w jzykach C# i Visual Basic .NET:
$5
 
( B <
 

8"
6
8$-6
6
Ha
- 
 ( B

6
-6

>; G 
 ( B
A"

A$-
% 

Pracujc ze strukturami tego typu, wykorzystujemy symbol kropki do uzyskiwania dostpu


do poszczeglnych pl rekordu. Oto przykad:
9

&8( B 6
-
&38<?D6
&38<D3J6
6

Dla rekordw definiowanych w jzyku Delphi for .NET moliwe jest stosowanie metod,
mechanizmu przeciania operatorw oraz implementacji interfejsw. Takich moliwoci
nie mielimy we wczeniejszych wersjach kompilatora Delphi (dla platformy Win32).
Wszystkie te elementy omwimy bardziej szczegowo w dalszej czci rozdziau
podczas analizy typw . W poniszym przykadowym kodzie przedstawiono
skadni dla wymienionych elementw stosowanych dla rekordw (zademonstrowana
skadnia rni si od omawianej pniej skadni deklarowania klas):
"G 5<
: 

 
-
6
6
#<
 
"G 5

 
: "G 5
A#8"
6

 
-
6
  

A /-8#8#6
 0C


6

104

Cz II  Jzyk programowania Delphi for .NET

&
Zbiory s unikalnym typem wystpujcym tylko w jzyku programowania Delphi nie
maj swoich odpowiednikw ani w jzyku C#, ani w jzyku Visual Basic .NET. Zbiory
s efektywnym i wygodnym narzdziem reprezentowania wielu elementw typw porzdkowych, znakw typu #' lub wartoci wyliczeniowych. Nowy typ zbioru moemy deklarowa za pomoc sw kluczowych !C  poprzedzajcych typ elementw
zbioru lub podzakres moliwych wartoci zbioru. Oto przykad takiej deklaracji:
 
H5
4<:AH5
60 - 8a=[a?KK
%<( / /I /5
 /#
 6
%4<:%6 -V
0 
^- 1V%
4-
4<:2332=60 - 82[2=

Zwr uwag na ograniczenie odnonie maksymalnej liczby elementw w zbiorze, ktra


wynosi 255. Dodatkowo naley pamita, e po sowach kluczowych !C  mog wystpowa wycznie identyfikatory typw porzdkowych. Oznacza to, e ponisze deklaracje s niepoprawne:
 
"4<:"
6&
8 - V
4
4<:
6&
8
  
 

Zbiory przechowuj swoje elementy w wewntrznym formacie bitowym, dziki czemu


s bardzo efektywne zarwno w obszarze szybkoci przetwarzania, jak i iloci wykorzystywanej pamici.
Jeli przenosisz kod z platformy Win32 na platform .NET Framework, miej na uwadze
istniejce rnice w mechanizmie reprezentowania znakw w wiecie .NET wykorzystuje
si format 2-bajtowy, natomiast w aplikacjach dla platformy Win32 stosowano format
1-bajtowy. Oznacza to, e deklaracja !CC' jest przez kompilator .NET zamieniana
na deklaracj !C #', co w niektrych przypadkach moe prowadzi do
zmiany pierwotnego znaczenia kodu rdowego. Kompilator wygeneruje wwczas
odpowiednie ostrzeenie z zaleceniem zamiany tej deklaracji na jawn deklaracj
zbioru !CC#'.


 
Podczas konstruowania wartoci zbioru na podstawie jednego lub wicej elementw powiniene uywa nawiasw kwadratowych. Poniszy fragment kodu demonstruje sposb
deklarowania zmiennych typu ! oraz przypisywania im wartoci:
 
H5
4<:AH5
60 - 8a=[a?KK
%<( / /I /5
 /#
 6
%4<:%6 -V
0 
^- 1V%
9

H5
48H5
46

Rozdzia 5.  Jzyk Delphi

105

%48%46
4-
48:2332=60 - 82[2=
A5 48:>A>33> >60 8>A>[> >
-
H5
48<Q>A>33>,>/> >/>>R6
%48<Q4 
 /4 R6
4-
48<Q2/?/J33@R6
A5 48<QR6 -V
 [-
V
6


   
Jzyk programowania Delphi oferuje wiele operatorw, ktre mona stosowa do manipulowania na zbiorach. Moemy uywa tych operatorw do okrelania elementw nalecych do zbiorw, do czenia (sumowania) zbiorw, do okrelania rnicy oraz do
wyznaczania czci wsplnej pary zbiorw.
Przynaleno. Operator  suy do okrelania, czy dany element naley do konkretnego
zbioru. Przykadowo, poniszy fragment kodu mona wykorzysta do sprawdzenia, czy
wspomniany przed chwil zbir '! zawiera liter DD:
:>4>H5
45

V- 

Poniszy fragment kodu ma na celu okrelenie, czy zbir "1! nie zawiera elementu
?:
:( %45

V- 

Suma i rnica. Za pomoc operatorw ; i < lub pary procedur  " i : "
moemy dodawa i usuwa elementy do i ze zmiennej typu ! (czyli do i ze zbioru):
" H5
4/> >6  -
> >
H5
48<H5
4CQ>->R6  -
>->
%E H5
4/>E>6   -
>E>
H5
48<H5
4[Q> >/> >R6   -
 > >> >

Wszdzie tam, gdzie jest to moliwe, staraj si stosowa par procedur  "
i : " odpowiednio do dodawania i odejmowania pojedynczych elementw,
poniewa wspomniane procedury s bardziej efektywne od operatorw ; i <.

Iloczyn zbiorw. Do wyznaczania iloczynu (czci wsplnej) dwch zbiorw moemy


uywa operatora >. Wynikiem wyraenia w postaci !2C>C!B jest zbir zawierajcy
wszystkie te elementy ze zbioru !2, ktre nale take do zbioru !B. Przykadowo,
poniszy fragment kodu moe by uyty w roli efektywnego narzdzia do okrelania,
czy dany zbir zawiera powtarzajce si elementy:
:Q> >/>->/> >RH5
4<Q> >/>->/> >R5

V- 

106

Cz II  Jzyk programowania Delphi for .NET

" 
# 
Na tym etapie programici, ktrzy maj dowiadczenie w pracy z jzykiem Delphi dla
platformy Win32, mog stwierdzi: do tej pory wszystko si zgadza, ale co si stao ze
wskanikami?. Chocia w jzyku programowania Delphi for .NET wskaniki nadal s
dostpne, z punktu widzenia specyfikacji platformy .NET Framework s traktowane jak
konstrukcje niebezpieczne, poniewa umoliwiaj bezporedni dostp do pamici. Oznacza to, e wykorzystanie wskanikw w tworzonych aplikacjach .NET bdzie wymagao
odpowiedniego ustawienia kompilatora zezwolenia na akceptowanie niebezpiecznego
kodu. Aby umoliwi pisanie i kompilowanie takiego kodu, musisz wykona nastpujce
kroki:
 Doczy dyrektyw J #CK do moduu zawierajcego

niebezpieczny kod.
 Oznaczy sowem kluczowym " wszystkie funkcje, ktre zawieraj

niebezpieczny kod.
Oto przykad. Poniszy niebezpieczny kod zostanie pomylnie skompilowany przez
kompilator Delphi for .NET.
!+&4A#%H'$%'&

 
BI54 
6 :6
9

A8

Q=33D2R:H5
6
)8)H5
6)H5
 N-   N 
-
A8<> : :
>6   - 1  V
)8<bAQ=R6   
 
)Q=R8<>4>6  
 
( GE345A6    - 1
6

Zwr uwag na sposb wykorzystania dostpnego w jzyku Delphi operatora L (tzw.


operatora adresu) w celu uzyskania adresu wybranej struktury danych.
Stosowanie niebezpiecznego kodu jest bardzo niemile widziane w aplikacjach dla
platformy .NET Framework, poniewa tak zbudowane aplikacje nie mog przej
testw stosowanego na tej platformie narzdzia PEVerify, przez co mog by objte
jeszcze powaniejszymi ograniczeniami w zakresie bezpieczestwa. Z drugiej
strony, niebezpieczny kod moe by doskonaym sposobem na wypenienie
przepaci dzielcej wiat platformy Win32 od wiata platformy .NET. Przenoszenie
caych duych aplikacji z platformy Win32 na platform .NET w jednym kroku i tak
jest bardzo trudne, jednak zastosowanie niebezpiecznego kodu umoliwia nam
w miar sprawne przenoszenie przynajmniej fragmentw takich aplikacji i sukcesywne
dostosowywanie poszczeglnych moduw do wymaga stawianych przez platform
docelow.

Moesz zakada, e fragmenty kodu prezentowane w tej czci rozdziau musz by


kompilowane z dyrektyw J #CK i sowami kluczowymi " (z oczywistych wzgldw oba te elementy nie we wszystkich przykadach s widoczne).

Rozdzia 5.  Jzyk Delphi

107

) *
 
Wskanik (ang. pointer) jest zmienn reprezentujc konkretn lokalizacj w pamici.
Przykad wskanika (typ
') miae ju okazj zobaczy wczeniej w tym rozdziale.
Stosowany w jzyku Delphi wskanik oglny zosta zrcznie nazwany
!. Czsto
mwi si, e
! jest wskanikiem bez typu, poniewa reprezentuje wycznie adres
w pamici i kompilator nie utrzymuje adnych dodatkowych informacji na temat danych
wskazywanych przez ten wskanik. Pojcie wskanika bez typu stoi jednak w sprzecznoci z jedn z podstawowych cech jzyka Delphi, jak jest gwarancja bezpieczestwa
typw, zatem wszdzie tam, gdzie jest to moliwe, powinnimy w naszym kodzie stosowa wskaniki z typami.
W rodowisku .NET do reprezentowania wskanikw bez typw jest wykorzystywany
typ ?!1%!
!.

Wskaniki z typami s deklarowane za pomoc operatora M (tzw. operatora wskanika)


w znajdujcej si na pocztku programu czci (?@. Wskaniki z typami uatwiaj kompilatorowi dokadne ledzenie rodzaju typw wskazywanych przez poszczeglne
wskaniki, a wic umoliwiaj kompilatorowi ledzenie tego, co robisz (i co moesz zrobi) ze swoimi zmiennymi wskanikowymi. Oto kilka przykadw typowych deklaracji
wskanikw:
 
)"<Y"
6)" 
 .  -1 
#<
 




c-- c8
6
4
:8$-6
6
)#<Y#6)#  .   #
9

)8)
6 .-  
)?8)#6 
)#

Programici C/C++ z pewnoci zwrcili uwag na podobiestwo pomidzy stosowanym


w jzyku Delphi operatorem M, a znanym z jzykw C i C++ operatorem >. Dostpny
w jzyku Delphi typ
! (wskanika bez typu) odpowiada uywanemu w jzykach
C i C++ typowi C>.

Pamitaj, e zmienna wskanikowa przechowuje jedynie adres w pamici. Za przydzielenie odpowiedniej iloci pamici dla struktur wskazywanych przez wskaniki zawsze
odpowiada programista. Poprzednie wersje jzyka programowania Delphi oferoway
wiele funkcji, za pomoc ktrych programici mogli przydziela i zwalnia pami; poniewa jednak bezporednie przydzielanie pamici jest operacj wykonywan bardzo
rzadko w aplikacjach .NET, zazwyczaj wykorzystuje si do tego celu metody udostpniane przez klas ?!1%)"!1%!@ % '. Poniszy fragment kodu
demonstruje sposb wykorzystania tej klasy do tworzenia i zwalniania blokw pamici,
a take kopiowania danych do i z tego bloku.
!+&4A#%H'$%'&
 
A

<

Q=33D2R:H5
6

108

Cz II  Jzyk programowania Delphi for .NET



 
A

H 6 :6


9

A28A

6
A?8

: 5
6
)8")
6
-
A28<>G  O
 >6   - 1  V
4*5A?/75A

C26
)8<(
5 3A 7c- 75A

C26


(
5 3H A2/=/)/75A

C26 A2
(
5 3H )/A?/=/75A

C26 A?
( GE345A?6    - 1
: 
(
5 3#
7c- )6
6
6

Jeli chcesz uzyska dostp do danych wskazywanych przez konkretny wskanik, uyj
operatora M bezporednio za nazw zmiennej wskanikowej. T technik nazywa si
niekiedy dereferencj (usuwaniem porednioci) wskanika. Wanie tak metod pracy
ze wskanikami zademonstrowano w poniszym przykadzie:

 
)
#6 :6
9

"8"
6
)"8Y"
6
-
"8<J?6
)"8<b26   "
)"Y8<?J6  "
( GE345"34
6
6

Kompilator Delphi wykorzystuje mechanizm cisego kontrolowania typw wskanikowych. Przykadowo, kompilator wykae brak zgodnoci typw dla tak zadeklarowanych
zmiennych wskanikowych  i +:
9

 8Y"
6
-8Y"
6

Okazuje si, e rwnowane deklaracje zmiennych wskanikowych w jzyku C nie powoduj podobnych problemw w kompilatorze tego jzyka:
 6
-

Wynika to z faktu, e jzyk Delphi tworzy unikalny typ dla kadej deklaracji wskanika do
typu oznacza to, e jeli chcemy bez problemw przypisywa wartoci ze zmiennej  do
zmiennej +, musimy stworzy i nazwa specjalny typ dla tych zmiennych:
 
)
"
<Y"
6
    
9

 8)
"
6
-8)
"
6    5 -
 

Rozdzia 5.  Jzyk Delphi

109

Kiedy wskanik na nic nie wskazuje (jego warto jest rwna $), programici Delphi
mwi, e jest rwny , a o samym wskaniku mwi, e jest wskanikiem pustym.

 


Wczeniej w tym rozdziale wspominalimy o trzech obsugiwanych w jzyku Delphi
rodzajach acuchw zakoczonych znakiem pustym:
',
#' oraz
-'.
Zgodnie z tym kady z nich reprezentuje acuch znakw innego formatu (wspominalimy ju, e w jzyku Delphi istniej trzy formaty reprezentowania znakw). W jzyku
Delphi for .NET typ
' jest aliasem typu
-'; w jzyku Delphi dla platformy
Win32 ten sam typ by aliasem typu
#'. W tym rozdziale bdziemy stosowa
pewne uproszczenie do kadego z tych typw acuchowych bdziemy si odwoywali za pomoc nazwy
'. W jzyku Delphi for .NET udostpniono typ
' przede
wszystkim w celu zapewnienia zgodnoci z aplikacjami napisanymi we wczeniejszych
wersjach tego jzyka. Typ ten jest definiowany jako wskanik na acuch zakoczony
znakiem pustym (zerem). Poniewa
' jest surowym, niezarzdzanym i niebezpiecznym typem wskanikowym, pami dla tych typw nie jest automatycznie ani przydzielana, ani zarzdzana przez rodowisko uruchomieniowe .NET.
W wersji jzyka Delphi dla platformy Win32 zmienne wskanikowe typu
' byy
zgodne (przynajmniej w obszarze operacji przypisania) ze zmiennymi typu !&. Jednak w wersji dla platformy .NET zrezygnowano ze zgodnoci tych typw, co znacznie
ogranicza moliwoci ich stosowania w wiecie aplikacji .NET.


  

Jzyk programowania Delphi obsuguje take rekordy wariantowe, ktre umoliwiaj


wzajemne nakadanie si rnych struktur danych w tej samej czci pamici wykorzystywanej przez dany rekord. Rekordw tego typu nie naley myli z wariantowym typem
danych (!) rekordy wariantowe umoliwiaj niezaleny dostp do wszystkich
nachodzcych na siebie pl danych. Jeli masz dowiadczenie w programowaniu w jzyku C,
z pewnoci dostrzegasz podobiestwo pomidzy stosowanymi w Delphi rekordami
wariantowymi a uniami (") wewntrz struktur (!" !) definiowanych w jzyku C.
Przedstawiony poniej fragment kodu pokazuje przykad takiego rekordu wariantowego, w ktrym wszystkie uyte zmienne (typw "+, !& i ') s przechowywane w tej samej przestrzeni pamiciowej:
 
;
 B 
<
 

&4
#8)H5
6
"#8"
6
 "
:
=8$8$-6
28"8"
6
?8H8H5
6
6

Reguy jzyka programowania Delphi zakadaj, e cz wariantowa rekordu nie moe


zawiera adnych typw zarzdzanych w czasie wykonywania aplikacji. Do zabronionych
typw nale klasy, interfejsy, warianty, tablice dynamiczne oraz acuchy.

110

Cz II  Jzyk programowania Delphi for .NET


Poniej przedstawiono deklaracj struktury w jzyku C, ktra jest rwnowana powyszej deklaracji rekordu wariantowego jzyka Delphi:

 +4
 

 5
4
#6
"#6


-$6
6
 5
 6
6
6

Poniewa rekordy wariantowe zakadaj jawny dostp do rozplanowania pamici, tego


rodzaju konstrukcje s take uwaane za typy niebezpieczne.
Rozkad pamici wykorzystywanej przez rekord moe by kontrolowany przez programist
aplikacji .NET za porednictwem atrybutw !" ! ?"! i !.

+ 
Klasa jest typem wartociowym, ktry moe zawiera dane, waciwoci, metody i operatory. Model obiektowy zastosowany w jzyku programowania Delphi omwimy
znacznie bardziej szczegowo w dalszej czci tego rozdziau, w podrozdziale Stosowanie obiektw Delphi na tym etapie skupimy si jedynie na podstawowych reguach
skadniowych dla deklaracji klas jzyka Delphi. Klas definiuje si w nastpujcy sposb:
 
H5'-  <  )
'-  
-
4;
8"
6

 
4)
 6
6

Powysza deklaracja jest rwnowana nastpujcej deklaracji stworzonej w jzyku programowania C#:
-   H5'-  8)
'-  

- 4;
6
- 94)
 6


Metody klas s definiowane w sposb niemal identyczny jak normalne procedury i funkcje (patrz podrozdzia Procedury i funkcje) jedyn rnic jest dodatkowo umieszczana przed nazw procedury lub funkcji nazwa klasy wraz z oddzielajc kropk:

 
H5'-  34)
 6
-
    1
 

6

Rozdzia 5.  Jzyk Delphi

111

Stosowany w jzyku Delphi symbol kropki ma podobne znaczenie jak wykorzystywany


w jzykach C# i Visual Basic .NET identyczny operator sucy do odwoywania si do
skadowych klas.

,
Jzyk programowania Delphi daje moliwo tworzenia nowych nazw (tzw. aliasw)
dla wczeniej zdefiniowanych typw. Przykadowo, jeli chcemy dla typu !& stworzy now nazw, w tym przypadku ?)?!?!&, moemy uy w naszym
kodzie nastpujcej deklaracji:
 
( B  &: "
<"
6

Nowo zdefiniowany alias typu jest pod kadym wzgldem zgodny z typem, ktry reprezentuje. Oznacza to, e w tym przypadku moemy uywa typu ?)?!?!&
wszdzie tam, gdzie moglibymy uy standardowego typu !&.
W jzyku Delphi istnieje jednak moliwo definiowania aliasw z mocniejsz kontrol
typw, ktre z punktu widzenia kompilatora s zupenie nowymi, unikalnymi typami.
Aby zdefiniowa taki alias, uyj sowa zastrzeonego !?@ w nastpujcy sposb:
 
( '5
& "
< "
6

Dziki zastosowaniu takiej skadni, typ ?!'!!& bdzie w razie koniecznoci


konwertowany na typ Integer (np. w celu prawidowego wykonania operacji przypisania), jednak typ ten nie bdzie zgodny ze standardowym typem !& w roli parametrw  i "!. Oznacza to, e poniszy fragment kodu jest syntaktycznie prawidowy:
9

('&"8( '5
& "
6
"8"
6
-
"8<26
('&"8<"6

Z drugiej jednak strony skompilowanie poniszego fragmentu jest niemoliwe:



 
c9
; 8"
6
-
 
6
9

(8( '5
& "
6
-
(8<?M6
c(6G8(     "

Poza wspomnianymi problemami z wymuszan przez kompilator cis zgodnoci typw


okazuje si, e podczas kompilacji dla kadego aliasu z mocniejsz kontrol typw automatycznie s generowane odpowiednie informacje czasu wykonywania. Dziki temu
moliwe jest tworzenie dla poszczeglnych typw unikalnych edytorw waciwoci
patrz rozdzia 8., Mono. Wieloplatformowe rodowisko. NET.

112

Cz II  Jzyk programowania Delphi for .NET

&$   $ !'$


Rzutowanie typw jest technik, dziki ktrej moesz wymusi na kompilatorze traktowanie zmiennej pewnego typu jak zmiennej innego typu. Z uwagi na stosowan w jzyku
programowania Delphi cis kontrol typw, z pewnoci zauwaysz bardzo ma tolerancj kompilatora tego jzyka w obszarze dopasowywania formalnych i rzeczywistych
typw parametrw wywoa funkcji. W efekcie bdziesz niekiedy zmuszony do rzutowania zmiennej jednego typu na posta zmiennej innego typu, aby z jednej strony osign zaoony cel i jednoczenie zadowoli kompilator. Przypumy na przykad, e
musimy przypisa warto zmiennej znakowej (typu ') do zmiennej typu -:
9

 8 5
6
8I
6
-
 8<>>6
8< 6 
 0 - 
 
3

W poniszym przykadzie zastosowany mechanizm rzutowania typw jest wymagany


do konwersji zmiennej na typu -. Efektem wykorzystania tego mechanizmu jest
zasygnalizowanie kompilatorowi tego, e programista wie, co robi, i rzeczywicie chce
przekonwertowa jeden typ na drugi:
9

 8H5
6
8I
6
-
 8<>>6
8<I
 6
  -1 
3

Rzutowanie zmiennej z jednego na inny typ jest moliwe tylko w sytuacji, w ktrej
rozmiar zmiennych obu typw jest identyczny. Przykadowo, nie moemy rzutowa
liczby zmiennoprzecinkowej typu "+ na liczb cakowit typu !&. Konwersja
liczby zmiennoprzecinkowej na liczb cakowit wymaga zastosowania funkcji (" 
(przycinania czci uamkowej) lub )" (zaokrglania). Przeksztacenie odwrotne
zamiana liczby cakowitej na liczb zmiennoprzecinkow wymaga tylko operatora
przypisania: !C/0C!. Moemy take jawnie lub niejawnie konwertowa
typy za pomoc specjalnych operatorw konwersji zdefiniowanych dla wykorzystywanych
klas (wicej informacji na temat przeciania operatorw znajdziesz w dalszej czci
tego rozdziau).

Jzyk programowania Delphi obsuguje take specjalny mechanizm rzutowania typw


obiektowych w oparciu o operator . Operator ten dziaa identycznie jak standardowe
funkcje rzutowania typw z tym wyjtkiem, e w przypadku bdu zamiast generowa
wyjtek, zwraca warto ".

Rozdzia 5.  Jzyk Delphi

113

()

$
Jzyk Delphi oferuje klauzul " !&, dziki ktrej programista ma moliwo
umieszczania zasobw acuchowych bezporednio w kodzie rdowym tworzonej
aplikacji. Zasoby acuchowe s po prostu staymi acuchowymi (zwykle tymi, ktre
s wywietlane przed uytkownikiem), ktre fizycznie nale do zasobw doczonych
do aplikacji lub biblioteki, a wic nie s wbudowane w jej kod rdowy. W naszym
kodzie rdowym powinnimy si jednak odwoywa do zasobw acuchowych, a nie
do z gry zdefiniowanych staych tego typu. Oddzielajc zawarto tych acuchw od
kodu rdowego, moemy uatwi przysze tumaczenie naszej aplikacji na inne jzyki
przy zastosowaniu odpowiedniej konstrukcji aplikacji takie tumaczenie bdzie dotyczyo wycznie zasobw acuchowych. Zasoby acuchowe s deklarowane w klauzuli
" !& za pomoc wyrae w postaci  
C0C   
 , oto
przykad:




B4
2<>F V- O  5 
2>6
B4
?<>F V- O  5 
?>6
B4
D<>F V- O  5 
D>6

Zgodnie z reguami syntaktycznymi zasoby acuchowe mog by wykorzystywane w naszym kodzie rdowym w sposb, przypominajcy stosowanie funkcji zwracajcych
acuchy:




B4
2<> >6
B4
?<> >6
9

4
28
6
-
4
28<B4
2C>>CB4
?6
3
3
3
6

 $  $ '$


W tym podrozdziale sprbujemy porwna stosowane w jzyku programowania Delphi
konstrukcje  i  z ich odpowiednikami wykorzystywanymi w jzykach C# i Visual
Basic .NET. Zakadamy, e w swojej pracy stosowae ju tego typu konstrukcje programistyczne, zatem nie bdziemy powica zbyt duo czasu na wyjanianie ich znaczenia i funkcjonowania.

114

Cz II  Jzyk programowania Delphi for .NET

-
 !.
Instrukcja warunkowa  umoliwia nam okrelanie, czy dane warunki s spenione
jeszcze przed wykonaniem konkretnego bloku kodu. Poniej zaprezentowano przykadow instrukcj warunkow  w jzyku programowania Delphi wraz z jej odpowiednikami w jzykach C# i Visual Basic .NET:
$5
:E<J5 8<E6
Ha
:E<<J <E6
>; G 
":E<J5 <E

Jeli wykorzystujesz w swoim kodzie instrukcj warunkow , w ktrej sprawdzasz


wicej ni jeden warunek, dla jasnoci upewnij si, e kady z tych warunkw znajduje
si w osobnej parze nawiasw okrgych:
:E<L  <S5

Unikaj jednoczenie konstrukcji podobnych do tej z poniszego przykadu (w tym


przypadku kompilator zasygnalizuje bd):
:E<L  <S5

W jzyku programowania Delphi stosuje si sowa kluczowe +& i  niemal tak samo
jak w jzyku C# wykorzystywane s nawiasy klamrowe J i K. Przykadowo, ponisz
konstrukcj moemy zastosowa, jeli chcemy wykona wicej ni jeden wiersz kodu
w przypadku spenienia warunku instrukcji  (w tym przypadku :C0CI):
:E<@5-
$456
$45%6
$A5
56
6

Moemy take czy wiele wzajemnie sprzecznych warunkw za pomoc konstrukcji


<:
:E<2==5
4# 6
:E<?==5
4'5
# 6
-
45%6
%
 6
6

/

 ! 
Instrukcja  w jzyku programowania Delphi ma niemal identyczne znaczenie jak
instrukcja *! ' w jzyku C#. Instrukcja  jest wygodnym narzdziem wybierania
jednego warunku spord wielu moliwoci bez koniecznoci stosowania rozbudowanych

Rozdzia 5.  Jzyk Delphi

115

konstrukcji <C < itd. Poniej przedstawiono przykad instrukcji  zbudowanej w jzyku Delphi:
4"
;
 -:
2=28$456
?=?8-
$456
$45%6
6
D=D8$A5
56
$5$: 6
6

Selektor instrukcji  musi by zmienn typu porzdkowego. Stosowanie w roli


selektora zmiennej typw nieporzdkowych, np. acuchw, jest traktowane w jzyku
Delphi jak bd. Pozostae jzyki programowania dla platformy .NET, w tym jzyk C#,
zezwalaj na wykorzystywanie acuchw w roli selektorw.

Poniej przedstawiono instrukcj *! ' z jzyka C#, ktra jest rwnowana zaprezentowanej powyej instrukcji :
 54"
;
 -

 2=28$456-
 6
 ?=?8$456
$45%6-
 6
 D=D8$A5
56-
 6
: 8$5$: 6


"
Ptla jest konstrukcj umoliwiajc wielokrotne wykonywanie okrelonych dziaa.
Konstrukcje ptli dostpnych w jzyku programowania Delphi s bardzo podobne do
swoich odpowiednikw, ktre powiniene doskonale zna z innych jzykw, zatem powicanie w tym podrozdziale zbyt wiele miejsca na wprowadzanie podstaw ptli nie
ma wikszego sensu. Poniej krtko omwimy rne konstrukcje ptli wykorzystywane
w jzyku Delphi.

.
Zastosowanie ptli  jest idealnym rozwizaniem w sytuacji, gdy musimy powtrzy
jakie dziaanie tak liczb razy, ktr mona okreli z gry. Poniej przedstawiono
przykadowy fragment kodu z ptl , ktra dziesi razy dodaje do zmiennej A swj
indeks (w praktyce stosowanie tego kodu oczywicie nie miaoby sensu):
9

"/Z8"
6
-
Z8<=6
:
"8<22=
" Z/"6
3

116

Cz II  Jzyk programowania Delphi for .NET


Poniej przedstawiono odpowiednik tego programu zbudowany w jzyku programowania C#:
9 

E<=6
:
<26T<2=6CC
EC<6


Poniszy przykad przedstawia t sam ptl, tyle e napisan w jzyku programowania


Visual Basic .NET:
$ZA"

:
"<22=
Z<ZC"
&E"

 
Konstrukcj ptli *' stosujemy w sytuacjach, gdzie jaka cz naszego kodu musi
by wykonana wielokrotnie, o ile speniony jest jaki warunek. Warunki ptli *' s
testowane jeszcze przed wykonaniem jej pierwszej iteracji klasycznym przykadem
zastosowania ptli *' jest wielokrotne przeprowadzanie tych dziaa na otwartym
pliku a do osignicia jego koca. Poniej przedstawiono przykad ptli *', w ktrej
odczytujemy kolejne wiersze (po jednym w kadej iteracji) z pliku tekstowego i wywietlamy je na ekranie:


#"6
!A))d)%H'&4'*%
9

:8E#6
8
6
-
A#:/>:3E>6
B:6


5%'#:
-

 :/46

46
6
: 
H#:6
6
3

Stosowana w jzyku Delphi ptla *' dziaa tak samo jak odpowiadajce jej konstrukcje dostpne w jzykach programowania C# (take ptla *') oraz Visual Basic
.NET (ptla  -').

Rozdzia 5.  Jzyk Delphi

117

0

Ptla @!<"! jest wykorzystywana do rozwizywania problemw nalecych do
tej samej klasy co problemy rozwizywane za pomoc ptli *' obie konstrukcje
rni si jednak podejciem do problemu. Ptla @!<"! powtarza wykonywanie
danego bloku kodu tylko do momentu, w ktrym pewien warunek stanie si prawdziwy.
Inaczej ni w przypadku ptli *' blok kodu zawarty w ptli @!<"! jest zawsze wykonywany przynajmniej raz, poniewa warunek ptli jest sprawdzany dopiero na
jej kocu. Stosowana w jzyku programowania Delphi ptla @!<"! jest w oglnoci rwnowana znanej z jzyka C# konstrukcji <*' z t rnic, e odwrcony
jest warunek przerwania wykonywania ptli.
Przykadowo, w poniszym fragmencie kodu instrukcja zwikszajca licznik : o jeden
jest powtarzana w ptli @!<"! do momentu, w ktrym warto tego licznika
przekroczy 2$$:
9

E8"
6
-
E8<26

 
 E6
EU2==6
3

-
 !1
Wywoanie instrukcji .N z wntrza ptli *',  lub @!<"! powoduje natychmiastowe przejcie na koniec aktualnie wykonywanej ptli. Ta metoda opuszczania
bloku kodu wewntrz ptli jest szczeglnie przydatna w sytuacjach, w ktrych z uwagi
na pewne okolicznoci wykryte wewntrz ptli musimy przerwa jej wykonywanie. Dostpna w jzyku Delphi instrukcja .N jest odpowiednikiem znanej z jzyka programowania C# instrukcji +N oraz stosowanej w jzyku Visual Basic .NET instrukcji
:!. W poniszej ptli wykorzystano instrukcj .N do przerwania wykonywania ptli
ju po piciu iteracjach:
9

8"
6
-
:
8<22======
-
( G=6     .1
:<K5G
 6
6
6

-
 !2


Instrukcj !" wywoujemy wewntrz ptli w sytuacji, gdy chcemy pomin nastpujcy po niej blok kodu i przekaza sterowanie do kolejnej iteracji ptli. Zwr
uwag na sposb wykorzystania tej instrukcji w poniszym przykadzie kodu cz

118

Cz II  Jzyk programowania Delphi for .NET


kodu wystpujca po instrukcji !" zostanie pominita w pierwszej iteracji uytej
ptli :
9

8"
6
-
:
8<2D
-

/>/)
:  >6
:<25 6

/>/):  >6
6
6


 

Jako programista z pewnym dowiadczeniem w pracy z jzykami programowania powiniene ju teraz zna podstawy stosowania procedur i funkcji. Procedura jest wyodrbnion czci programu, ktra po swoim wywoaniu wykonuje okrelone zadanie i zwraca
sterowanie do czci kodu, w ktrej zostaa wywoana. Funkcja dziaa w ten sam sposb
z jedn rnic po zakoczeniu dziaania wraz ze sterowaniem przekazywanym do
wywoujcej czci programu funkcja zwraca take swoj warto (patrz listing 5.1).
$ "&  Przykadowy program wykorzystujcy funkcj i procedur
28
?8
D8
J8
K8
@8
L8
S8
M8
2=8
228
2?8
2D8
2J8
2K8
2@8
2L8
2S8
2M8
?=8
?28
??8
?D8
?J8
?K8
?@8
?L8



# )
 6
!A))d)%H'&4'*%

 
G
5 "8"
6
I   
 / " 1 2=3
-
:"U2=5

> 5V
 3>6
6
: ")9"8"
8G 6
F

^
/ " 
V=-  - /
-
^# / "  - 
-
B8<"U<=6
6
9

&8"
6
-
&8<?D6
G
5 &6
:")9&5

&/>,  3>6


&/>,  3>6
3

Rozdzia 5.  Jzyk Delphi

119

Zmienna Result
Wykorzystana w funkcji 
! zmienna lokalna )"! wymaga krtkiego omwienia.
Kada funkcja jzyka programowania Delphi zawiera deklarowan niejawnie zmienn lokaln
nazwan )"!, ktra przechowuje warto zwracan przez t funkcj. Zauwa, e w przeciwiestwie do znanej z jzyka C# instrukcji !" przypisanie wartoci do zmiennej )"! nie jest
rwnowane z zakoczeniem dziaania danej funkcji.
Jeli chcesz otrzyma w jzyku Delphi podobn funkcjonalno, jak w jzyku C# daje instrukcja
!", moesz bezporednio po przypisaniu wartoci do zmiennej )"! wywoa instrukcj :!,
ktra powoduje natychmiastowe opuszczenie biecej funkcji lub procedury.
Alternatywnym sposobem zwracania wartoci funkcji jest uycie wewntrz jej kodu operacji
przypisania wartoci do nazwy funkcji. Jest to standardowa skadnia jzyka programowania Delphi,
ktra pochodzi jeszcze ze starszych wersji jzyka Borland Delphi. Jeli zdecydujesz si uy nazwy
funkcji w jej ciele, musisz pamita o zasadniczej rnicy pomidzy jej umieszczeniem po lewej
stronie operatora przypisania, a dowolnym innym miejscem w tworzonym kodzie. Nazwa funkcji
wykorzystana w roli lewego operandu operatora przypisania oznacza, e przypisujemy funkcji zwracan pniej warto. Wykorzystanie tej nazwy w dowolnym innym miejscu kodu bdzie oznaczao rekurencyjne wywoanie danej funkcji!
Pamitaj take, e wykorzystywanie niejawnie deklarowanej zmiennej )"! nie bdzie akceptowane przez kompilator, jeli na zakadce Compiler okna dialogowego ustawie projektu (wywoywanego przez wybr opcji Project/Options) wyczymy opcj Extended Syntax lub jeli w naszym
kodzie uyjemy dyrektywy JA(O(#ACK (bd dyrektywy JA<K).

 

Jzyk programowania Delphi umoliwia nam przekazywanie parametrw funkcji i procedur przez wartoci lub przez referencje. Przekazywane przez nas parametry mog by
zmiennymi typu prostego, zmiennymi typu uytkownika lub tablicami otwartymi (tablice
otwarte omwimy w dalszej czci tego rozdziau). Jeli dana funkcja lub procedura nie
modyfikuje otrzymywanych parametrw, moemy je przekaza w formie wartoci staych.

!
  

Stosowanie parametrw wartociowych jest w jzyku Delphi domylnym trybem przekazywania parametrw do funkcji i procedur. Kiedy przekazujemy jaki parametr przez
warto, automatycznie tworzona jest lokalna kopia tej zmiennej, na ktrej moemy
potem operowa z poziomu kodu funkcji lub procedury. Przeanalizujmy teraz poniszy
przykad:

 
#"8"
6

Kiedy wywoamy tak zadeklarowan procedur, zostanie utworzona lokalna kopia


przekazanej zmiennej cakowitoliczbowej  wanie na tej kopii bdzie operowa kod
procedury . Oznacza to, e moemy z poziomu tej procedury modyfikowa warto lokalnej kopii zmiennej , nie zmieniajc przy tym oryginalnej zmiennej przekazanej do procedury .

120

Cz II  Jzyk programowania Delphi for .NET

!
 
"

 #

Jzyk Delphi umoliwia przekazywanie do funkcji i procedur zmiennych przez ich referencje; parametry przekazywane w ten sposb s take nazywane parametrami zmiennymi. Przekazywanie przez referencje oznacza, e funkcja lub procedura otrzymujca
dan zmienn moe zmodyfikowa jej oryginaln warto. Przekazywanie zmiennych
przez referencje wymaga uycia sowa kluczowego  na licie parametrw w instrukcji wywoania procedury lub funkcji:

 
H5 (9
E86
-
E8<?6  E
 
         
6

Zamiast tworzy kopi zmiennej :, wskutek uycia sowa kluczowego  do procedury
'&  jest przekazywana kopia adresu tego parametru, dziki czemu moemy w kodzie tej procedury bezporednio modyfikowa t zmienn.
Technika polegajca na stosowaniu w jzyku Delphi sowa kluczowego  dla parametrw przekazywanych przez referencje ma swoje odpowiedniki w jzyku C# (sowo
kluczowe ) oraz jzyku Visual Basic .NET (dyrektywa .?)).

!
  # 

Podobnie jak parametry zmienne (deklarowane ze sowem kluczowym ), parametry


wyjciowe (deklarowane ze sowem kluczowym "!) s jedn z metod zwracania z funkcji i procedur wartoci do kodu wywoujcego za porednictwem parametrw. Rnica
polega jednak na tym, e parametry zmienne musz by inicjalizowane poprawn wartoci jeszcze przed wywoaniem funkcji lub procedury takie wymaganie nie dotyczy
parametrw wyjciowych, poprawno przekazywanej wartoci w ogle nie jest weryfikowana. W przypadku typw referencyjnych oznacza to, e w momencie wywoania procedury lub funkcji taka referencja jest usuwana.

 
B
('8'-  6
-
'8<4'-  3H
 6
6

Oto prba przedstawienia reguy stosowania tych parametrw w najwikszym skrcie:


sowo kluczowe  stosuje si dla parametrw wejcia-wyjcia, natomiast sowo kluczowe
"! stosuje si wycznie dla parametrw wyjciowych.

!
 $

Jeli nie chcesz, aby warto przekazywana do funkcji lub procedury bya zmieniana,
moesz j zadeklarowa ze sowem kluczowym !. Poniej przedstawiono przykadow deklaracj procedury, ktra otrzymuje w wywoaniu stay parametr acuchowy:

 
c 8
6

Rozdzia 5.  Jzyk Delphi

121



  

Otwarte parametry tablicowe daj nam moliwo przekazywania do funkcji i procedur


zmieniajcych si liczb argumentw. Moemy deklarowa albo otwarte tablice wybranego jednolitego typu, albo stae tablice rnych typw. Przykadowo, za pomoc poniszego kodu deklarujemy funkcj przyjmujc otwart tablic liczb cakowitych:
: A%+A8

:"
8"
6

Do funkcji i procedur przyjmujcych otwarte parametry tablicowe moemy przekazywa


zmienne, stae oraz wyraenia reprezentujce dowolne typy tablic (dynamiczne, statyczne lub otwarte). Poniszy kod demonstruje wywoanie zadeklarowanej przed chwil
funkcji #1 @ z przekazaniem otwartego parametru tablicowego w postaci zestawu
czterech rnych elementw (odpowiednio zmiennej, wyraenia i dwch staych):
9

"/B 8"
6

,<?D6
-
"8<S6
B 8<A%+Q"/"CK=/,/SMR6

Do funkcji lub procedury przyjmujcej otwarty parametr tablicowy moemy take bezporednio przekazywa istniejc zmienn (lub sta) tablicow:
9

A8

:
6
-
4*5A/2=6
:
8<*A75A
AQR8<6
B 8<A%+HA6

Podczas przetwarzania otwartych tablic wewntrz danej funkcji lub procedury moemy
wykorzystywa funkcje &', * i &!', za pomoc ktrych bez trudu mona
uzyska podstawowe informacje na temat przekazanej tablicy. Ilustruje to poniszy
fragment kodu, w ktrym zaimplementowano funkcj #1 @ zwracajc sum
wszystkich liczb cakowitych nalecych do przekazanej tablicy #:
: A%+A8

:"
8"
6
9

8"
6
-
B8<=6
:
8<*A75A
 B/AQR6
6

Jzyk programowania Delphi obsuguje take tablice staych elementw (?CC !),
ktre umoliwiaj przekazywanie do funkcji i procedur tablic z heterogenicznymi typami danych. Skadnia definiowania funkcji i procedur przyjmujcych takie tablice ma
nastpujc posta:

 
I5 7 9"cA8

: 6

122

Cz II  Jzyk programowania Delphi for .NET


Moemy wywoa powysz procedur np. za pomoc nastpujcej instrukcji:
I5 7 9"cQ> - >/M=/K3@/D32J2KM/
/>>R6

Kompilator przekazuje kady z elementw tego parametru tablicowego w postaci obiektu


klasy ?!1%+P !, dziki czemu mona te elementy stosunkowo atwo przetwarza
w docelowej funkcji lub procedurze. Przykadem pracy z tablicami staych elementw jest
ponisza implementacja procedury -'!Q!, w ktrej zastosowano ptl  iteracyjnie przetwarzajc kolejne elementy tej tablicy i wywietlajc na ekranie komunikaty wskazujce na typy danych przekazanych na poszczeglnych pozycjach tabeli:

 
I5 7 9"cA8

: 6
9

8"
6
-
:
8<*A75A
I
*>">/"/>8>/AQR3c 3#& 6
B *6
6

 
Zakres (zasig) jest pewn czci Twojego programu, w ktrej dana funkcja lub
zmienna jest widoczna dla kompilatora. Przykadowo, staa globalna mieci si w zakresie (jest zasigu) wszystkich punktw programu, natomiast zdefiniowana w danej
procedurze zmienna lokalna mieci si tylko w zakresie tej procedury. Przeanalizuj poniszy listing 5.2.
$ "& Przykadowy program wykorzystujcy funkcj i procedur
28
?8
D8
J8
K8
@8
L8
S8
M8
2=8
228
2?8
2D8
2J8
2K8
2@8
2L8
2S8
2M8
?=8
?28
??8
?D8
?J8



#6
!A))d)%H'&4'*%

4H <2==6
9

4c- 8"
6
$8$-6

 
4)
 6
9

$/* $8$-6
-
* $8<2=3=6
$8<$[* $6
6
-
4c- 8<4H 6
$8<J3KMD6
4)
 6
3

Rozdzia 5.  Jzyk Delphi

123

Staa 1!! oraz zmienne 1Q+ i  maj zasig globalny ich wartoci s
znane kompilatorowi we wszystkich punktach powyszego programu . Procedura
1
  definiuje dwie zmienne ( i  ), ktrych zasig ogranicza si tylko do
tej procedury. Jeli sprbujesz uzyska dostp do zmiennej   poza kodem procedury 1
 , kompilator wywietli bd nieznanego identyfikatora. Jeli natomiast
wykorzystasz zmienn  wewntrz procedury 1
 , bdziesz si odwoywa do
lokalnej wersji (nie do zmiennej  zdefiniowanej globalnie); jeli jednak uyjesz zmiennej  poza t procedur, bdziesz si odwoywa do wersji globalnej (jedynej, jaka jest
widoczna dla kompilatora procedur 1
 ).

*!    $


Moduy s wyodrbnionymi czciami kodu rdowego, ktre skadaj si na program
napisany w jzyku Delphi. Modu jest dobrym miejscem do grupowania funkcji i procedur, ktre bd pniej wywoywane z poziomu kodu rdowego gwnego programu.
Kady modu musi si skada co najmniej z trzech czci:


Instrukcji "! (nagwka) kady modu musi w swoim pierwszym wierszu


(bez poprzedzajcych komentarzy, spacji czy pustych wierszy) zawiera instrukcj
okrelajc, e dany plik jest moduem, i jednoczenie definiujc jego nazw
(jednak bez rozszerzenia pliku). Przykadowo, w module .%@ taki
nagwek miaby posta:
#G
6

Czci !  (interfejsu) zaraz po instrukcji "! kolejny funkcjonalny


wiersz kodu powinien zawiera instrukcj ! . Wszystkie elementy
znajdujce si po tej instrukcji, ale przed instrukcj 1@1!!, powinny
by deklaracjami tych typw, staych, zmiennych, procedur i funkcji, ktre
chcemy udostpni naszemu gwnemu programowi i innym moduom. Pamitaj,
e w czci interfejsu mog si znajdowa wycznie deklaracje nigdy ciaa
udostpnianych funkcji i procedur. Instrukcja !  powinna mie posta
pojedynczego sowa w osobnym wierszu:

: 

Czci 1@1!! (implementacji) cz implementacji nastpuje


w kodzie moduu po czci interfejsu. Chocia w czci 1@1!! umieszcza
si przede wszystkim procedury i funkcje danego moduu, mona w tej czci
take deklarowa dowolne typy, stae i zmienne, ktrych nie chcemy udostpnia
poza tym moduem. Wanie w czci implementacji powinnimy zdefiniowa
wszystkie funkcje i procedury, ktre zadeklarowalimy wczeniej w czci
interfejsu. Instrukcja 1@1!! powinna mie posta pojedynczego sowa
w osobnym wierszu:
 

Modu moe take zawiera dwie czci opcjonalne:




Cz !,! (inicjalizacji) ta cz moduu umieszczana blisko


koca jego pliku zawiera kod inicjalizacji zdefiniowany dla danego moduu.
Kod nalecy do tej czci jest wykonywany tylko raz, przed rozpoczciem
wykonywania kodu gwnego programu.

124

Cz II  Jzyk programowania Delphi for .NET




Cz ,! (finalizacji) ta cz moduu umieszczana pomidzy


czci inicjalizacji a kocem moduu (oznaczonym za pomoc sowa %)
zawiera zdefiniowany dla danego moduu kod finalizacji (nazywany czsto
kodem czyszczcym), ktry jest wykonywany w momencie koczenia pracy
gwnego programu. Cz finalizacji zostaa wprowadzona w wersji 2.0
jzyka programowania Delphi. W wersji 1.0 do finalizowania moduw mona
byo wykorzysta specjalne procedury wyjcia dodawane za pomoc funkcji
#:!
 . Jeli dostosowujesz aplikacj napisan w jzyku Delphi 1.0
do jego nowszej wersji, powiniene przenie kod zawarty w procedurach
wyjcia do czci finalizacji swoich moduw.

Moduy definiuj take przestrzenie nazw. Przestrze nazw umoliwia organizowanie


aplikacji lub biblioteki w logiczn i hierarchiczn struktur. Do tworzenia zagniedonych
przestrzeni nazw mona wykorzysta notacj z kropk, ktra zapobiega ewentualnym
konfliktom identycznych identyfikatorw. Bardzo czsto spotyka si nazwy zagniedone
na trzech poziomach: 1%@"N!%,,; przykadowo: .%@'%?!1
lub .% %!.
Jeli wicej ni jeden uyty (doczony) modu zawiera kod zdefiniowany w czci
inicjalizacji i (lub) finalizacji, odpowiednie bloki kodu s wykonywane w kolejnoci
napotykania doczanych moduw przez kompilator (najpierw wykonywany jest kod
pierwszego moduu klauzuli " gwnego programu, potem pierwszy modu
uwzgldniony w klauzuli " tego moduu itd.). Pamitaj take, e nie naley
w moduach tworzy takiego kodu inicjalizujcego i (lub) finalizujcego, ktrego
dziaanie jest uzalenione od tej kolejnoci, poniewa w takim przypadku stosunkowo
niewielka zmiana w klauzuli " moe by rdem trudnego do zlokalizowania bdu.

+
W klauzuli " umieszczamy list przestrzeni nazw, ktre chcemy doczy do tworzonego programu lub moduu. Przykadowo, jeli chcemy zbudowa program nazwany

&, ktry bdzie wykorzystywa funkcje i typy nalece do dwch rnych przestrzeni nazw ( !# i !.), powinnimy zastosowa instrukcj @&1 i klauzul "
w sposb nastpujcy:


#)
6
+A/+G6

Moduy mog zawiera dwie klauzule " jedn w czci interfejsu i jedn w czci
implementacji.
Poniej przedstawiono przykad prostego moduu z dwiema klauzulami ":
#G
6

: 
G
#6
  1  .^
- 
 

Rozdzia 5.  Jzyk Delphi

125

G
# 6
  1  .^

 
: : 
 
 
  5 1 
: 
  
 1  .^  
:  
 1  .^ 3   
3

W klauzuli " moemy wykorzystywa pene kwalifikatory doczanych przestrzeni


nazw lub co jest dopuszczalne w jzyku Delphi tylko najbardziej wewntrzne
identyfikatory przestrzeni nazw. Ta druga moliwo wynika z troski autorw tego
jzyka programowania o zgodno z jego wczeniejszymi wersjami (przykadem jest
przestrze nazw Controls). Odpowiednie ustawienia dotyczce prefiksw przestrzeni
nazw s dostpne we waciwym oknie dialogowym (wywietlanym przez wybr opcji
Tools/Options/Delphi Options/Library).

2  
 
 
Moesz si spotka z sytuacj, w ktrej modu !# odwouje si w klauzuli " do moduu !., ktry z kolei w swojej klauzuli " odwouje si do moduu !#. Nazywamy to cyklicznymi odwoaniami do moduw. Wystpienia tego typu sytuacji z reguy
wskazuj na bdy popenione w fazie projektowania aplikacji. Powiniene unika tworzenia tego typu struktur w swoich programach. Optymalnym rozwizaniem tego problemu
jest w wikszoci przypadkw przeniesienie tej czci danych, do ktrej odwouj si
oba moduy, do nowego, trzeciego moduu. Okazuje si jednak, e podobnie jak wielu
innych niewygodnych konstrukcji, take cyklicznych odwoa do moduw nie zawsze
mona unikn w tak prosty sposb. Pamitaj, e takie odwoania s niepoprawne, jeli
w obu moduach znajduj si w czci implementacji lub w obu moduach nale do
czci interfejsu. Wobec tego w wielu przypadkach najlepszym rozwizaniem jest przeniesienie odpowiedniej klauzuli " w jednym module do czci implementacji i pozostawienie cyklicznej klauzuli " drugiego moduu w dotychczasowej lokalizacji (lub
odwrotnie). Zazwyczaj w ten sposb mona rozwiza problem cyklicznych odwoa
do moduw3.

 ! !


Pakiety Delphi umoliwiaj nam umieszczanie wybranych czci naszej aplikacji w wyodrbnionych moduach, ktre w postaci tzw. podzespow .NET mog by nastpnie wspdzielone przez wiele aplikacji opracowanych dla tej platformy.
Pakiety i podzespoy .NET omwimy bardziej szczegowo w rozdziale 6., Podzespoy
.NET, biblioteki i pakiety.
3

Wicej informacji na temat cyklicznego odwoania do moduw znajdzie Czytelnik w rozdziale 4.,
Programy, moduy i przestrzenie nazw przyp. red.

126

Cz II  Jzyk programowania Delphi for .NET

$  ( $


Na temat koncepcji programowania obiektowego, nazywanego take programowaniem
zorientowanym obiektowo (ang. Object-Oriented Programming OOP), napisano ju
mnstwo ksiek. Programowanie obiektowe jest czsto traktowane bardziej jak religia
ni jedna z metodologii projektowania wielu programistw stara si w sposb sztuczny
wymyla i prezentowa niezliczone zalety tej techniki, nie dopuszczajc do siebie adnych argumentw jej przeciwnikw. Nie jestemy ortodoksyjnymi zwolennikami programowania obiektowego i nie mamy zamiaru prezentowa w tej ksice faktycznych
bd wyimaginowanych zalet tej metodologii chcemy jedynie uczciwie przedstawi
najwaniejsze podstawy, na ktrych opiera si jzyk programowania Delphi.
Programowanie obiektowe jest metodologi przewidujc stosowanie wyodrbnionych
obiektw zawierajcych zarwno dane, jak i kod w roli blokw wykorzystywanych
podczas budowy aplikacji. Chocia metodologia OOP niekoniecznie musi prowadzi do
uproszczenia procesu tworzenia kodu, efektem jej stosowania w praktyce tradycyjnie jest
otrzymywanie kodu atwiejszego do konserwacji. Poczenie danych i kodu obiektw
upraszcza proces wyszukiwania bdw w aplikacjach, naprawiania tych bdw i ograniczania do minimum ich wpywu na pozostae obiekty a wic przyczynia si do
udoskonalenia tworzonych aplikacji. Tradycyjnie kady jzyk obiektowy zawiera implementacj przynajmniej trzech zasadniczych waciwoci koncepcji programowania
obiektowego:


Hermetyzacja4 jest zwizana z waciwym czeniem uzalenionych


od siebie pl danych i jednoczesnym ukrywaniem odpowiednich szczegw
implementacyjnych. Do korzyci pyncych z zapewniania hermetycznoci
naley moliwo dzielenia programw na odseparowane moduy oraz atwo
izolowania od siebie poszczeglnych czci kodu.
Dziedziczenie wie si z moliwoci tworzenia nowych obiektw
w oparciu o waciwoci i funkcjonalno ich obiektw macierzystych.
Dziedziczenie umoliwia nam konstruowanie hierarchii obiektw podobnej
do struktury biblioteki VCL, w ktrej mamy jeden najbardziej oglny obiekt
oraz jego obiekty potomne, ktre na kadym kolejnym poziomie s coraz
bardziej szczegowe.
Zalet dziedziczenia jest moliwo wspdzielenia tego samego kodu.
Na rysunku 5.1 przedstawiono przykad dziedziczenia, gdzie jeden obiekt
bazowy (Owoc) jest przodkiem wszystkich obiektw reprezentujcych owoce,
w tym obiektu Melon. Obiekt Melon jest w przodkiem wszystkich obiektw
reprezentujcych melonowate, w tym dla obiektu Arbuz. Przeanalizuj teraz
ten rysunek.

Polimorfizm polimorfizm dosownie oznacza wielopostaciowo.


Wywoania wirtualnych metod zmiennej obiektowej powoduj wywoania
kodu waciwego dla rzeczywistego egzemplarza tego obiektu, ktry aktualnie
(w czasie wykonywania programu) jest reprezentowany przez t zmienn.

Moesz si rwnie spotka z okreleniem enkapsulacja przyp. red.

Rozdzia 5.  Jzyk Delphi

127

%#" 
Przykadowa struktura
dziedziczenia

Zwr uwag na brak moliwoci stosowania znanego z jzyka C++ mechanizmu wielokrotnego (wielobazowego) dziedziczenia w rodowisku uruchomieniowym .NET CLR
takiej moliwoci nie daje take jzyk programowania Delphi for .NET.
Zanim przejdziemy do omawiania podstawowych poj zwizanych z metodologi programowania obiektowego, musimy si upewni, e dobrze rozumiesz nastpujce terminy
nieodcznie zwizane z t metodologi:


Pole pola s zmiennymi reprezentujcymi dane przechowywane wewntrz


obiektw. Pola w obiektach peni identyczn rol jak pola stosowane w rekordach
definiowanych w jzyku Delphi. W jzyku C# pola s niekiedy nazywane
danymi skadowymi lub atrybutami.

Metoda jest to nazwa uywana dla procedur i funkcji nalecych do obiektw.


W jzyku C# metody s czasami nazywane funkcjami skadowymi.

Waciwo jest to konstrukcja penica rol akcesora do danych i kodu


zawartego w danym obiekcie, stanowi wic poczenie koncepcji pola i metody.
Waciwoci przypominaj pola, poniewa okrelaj taki sposb dostpu do pl
i metod, ktry ukrywa przed uytkownikiem szczegy implementacji danego
obiektu.
W oglnoci uwaa si, e bezporednie udostpnianie pl obiektu jest zym stylem
programowania obiektowego, poniewa utrudnia przysze zmiany szczegw
implementacyjnych obiektu. Zamiast bezporednich odwoa do pl obiektu
powiniene uywa odpowiednich waciwoci dostpowych, ktre z jednej strony
stworz standardowy interfejs obiektu, a z drugiej nie bd zmuszay uytkownika
do zagbiania si w struktur jego implementacji. Waciwoci zostan omwione
w punkcie Waciwoci w dalszej czci podrozdziau.

$  ( '$# ! 


Jak ju wspomnielimy, klasy s strukturami, ktre mog zawiera zarwno dane, jak i kod
(metody). Obiekty s tworzonymi w czasie wykonywania programu egzemplarzami
tych klas. Klasy w jzyku Delphi daj nam wszystkie moliwoci wynikajce z podstawowych cech koncepcji programowania obiektowego, a wic dziedziczenie, hermetyczno i polimorfizm.

128

Cz II  Jzyk programowania Delphi for .NET

  !

Zanim bdziemy mogli stosowa obiekty w naszym kodzie, oczywicie musimy go najpierw zdefiniowa za pomoc sowa kluczowego . Wspominalimy ju w tym rozdziale, e klasy s deklarowane w czci !?@ moduu lub programu:
 
#'-  <  6

Poza sam deklaracj klasy zazwyczaj bdziemy dodatkowo wykorzystywali zmienn


tego typu (egzemplarz tej klasy) zadeklarowan w czci :
9

#'-  8#'-  6

W jzyku programowania Delphi egzemplarze obiektu tworzy si przez wywoanie jednego z jej konstruktorw. Konstruktor odpowiada nie tylko za stworzenie egzemplarza
naszego obiektu, ale take za przydzielenie mu odpowiedniej iloci pamici lub inicjalizacj wszystkich niezbdnych pl, dziki ktrym obiekt bdzie gotowy do uycia po opuszczeniu konstruktora. Obiekty w jzyku Delphi musz zawiera przynajmniej jeden konstruktor nazwany ! moemy jednak tworzy dla poszczeglnych obiektw
wicej konstruktorw. W zalenoci od typu obiektu konstruktor ! moe pobiera
rn liczb parametrw wejciowych. W tym rozdziale skupimy si na najprostszym
przypadku, w ktrym konstruktor nie pobiera adnych parametrw.
Konstruktory obiektw w jzyku Delphi nie s wywoywane automatycznie za ich
wywoywanie zawsze odpowiada programista. Skadnia takich wywoa jest nastpujca:
#'-  8<#'-  3H
 6

Zwr uwag na unikalno skadni stosowanej w wywoaniach konstruktorw. Odwoujemy si do konstruktora klasy (metody !) przez typ, a nie przez egzemplarz, jak
w przypadku pozostaych metod zdefiniowanych w wykorzystywanych klasach. Takie
rozwizanie na pierwszy rzut oka moe si wydawa nieco dziwne, jednak ju po dokonaniu krtkiej analizy nie bdziesz mia wtpliwoci, e jest to technika sensowna.
Zmienna +P ! jest w czasie tego wywoania niezdefiniowana, a typ (+P !
jest statyczn struktur przechowywan w pamici. Statyczne wywoanie jej konstruktora
! jest wic w peni poprawne.
Proces wywoania konstruktora celem stworzenia egzemplarza obiektu jest czsto nazywany konkretyzowaniem obiektu lub po prostu tworzeniem egzemplarza (ang. instantiation).
Kiedy wykorzystujemy konstruktor do stworzenia egzemplarza obiektu, odpowiednie
mechanizmy rodowiska uruchomieniowego CLR upewniaj si, e wszystkie pola
naszego obiektu s inicjalizowane wartoci zero. Moesz bez obaw zakada, e
wszystkie zmienne liczbowe bd miay warto $, wszystkie obiekty bd rwne
, wszystkie zmienne logiczne przyjm warto  oraz e wszystkie acuchy
bd puste.

Rozdzia 5.  Jzyk Delphi

129

 !
Wszystkie klasy wykorzystywane w aplikacjach dla platformy .NET Framework dziedzicz funkcj nazwan ,, ktra moe zosta przykryta w kodzie klasy i wykonywa wszystkie operacje odzyskiwania zasobw, ktre programista uzna za konieczne.
Metoda , jest wywoywana automatycznie dla kadego egzemplarza klasy
przez stosowany w rodowisku CLR mechanizm odzyskiwania pamici. Pamitaj jednak, e nigdy nie ma gwarancji co do tego, kiedy metoda , faktycznie zostanie
wywoana, oraz czy w niektrych okolicznociach w ogle zostanie wywoana.
Z tych powodw nie zaleca si zwalniania krytycznych lub ograniczonych zasobw (takich jak ogromne bufory pamici, poczenia z baz danych lub uchwyty systemu operacyjnego) za pomoc metody ,. Zamiast tego programici Delphi powinni
przykrywa destruktor !? swoj wersj tej metody, ktra zwolni wszystkie cenne
zasoby. Wicej informacji na ten temat znajdziesz w rozdziale 9., Zarzdzanie pamici
i odmiecanie.

    


By moe zadajesz sobie pytanie, jak to moliwe, e wszystkie te metody mieszcz si
w Twoim niewielkim obiekcie. Z pewnoci sam tych metod nie deklarowae w swoim
kodzie rdowym, prawda? Omawiane metody w rzeczywistoci s dziedziczone po
standardowej klasie ?!1%+P ! udostpnianej wszystkim aplikacjom platformy .NET.
Wykorzystywana w jzyku Delphi klasa (+P ! jest jedynie aliasem oglnodostpnej
klasy ?!1%+P !. W tworzonych w jzyku Delphi aplikacjach .NET wszystkie
obiekty zawsze s bezporednimi lub porednimi potomkami klasy (+P !, niezalenie
od tego, czy jawnie zadeklarowae to dziedziczenie. Oznacza to, e deklaracja:
 
#<  
6

jest rwnowana deklaracji:


 
#<  '-  
6


Podczas dodawania pl do klasy wykorzystuje si skadni bardzo podobn do tej, ktra
jest stosowana dla deklaracji zmiennych w bloku . Przykadowo, poniszy fragment
kodu dodaje do klasy ( po jednym polu typu !&, !& i "+:
 
#<  '-  
"8"
6
48
6
$8$-6
6

130

Cz II  Jzyk programowania Delphi for .NET


Jzyk programowania Delphi obsuguje take pola statyczne czyli takie, ktre reprezentuj dane wspdzielone przez wszystkie egzemplarze danej klasy. Pola tego typu
mona dodawa do deklaracji klasy za pomoc jednego lub wicej blokw C. Ilustruje to poniszy fragment kodu, w ktrym do klasy ( dodajemy trzy pola statyczne:
 
#<  '-  
"8"
6
48
6
$8$-6
  9

"e4  8"
6
4e4  8
6
$e4  8$-6
6

Warto pamita, e wewntrz definicji klasy mona umieci (cho z punktu widzenia
regu syntaktycznych nie jest to konieczne) blok  definiujcy normalne pola klasy.
Odpowiednikiem stosowanego w jzyku Delphi bloku C  jest znane z jzyka
programowania C# sowo kluczowe !! . Pamitaj, e definiowane wewntrz klas
bloki C i  kocz si na nastpujcych elementach:


innym bloku C lub ,

deklaracji wasnoci,

dowolnej deklaracji metody,

specyfikatorze widocznoci.

3
Metody s funkcjami i procedurami nalecymi do danego obiektu zadaniem metod
jest zapewnienie obiektom moliwoci dziaania, dziki czemu nie s to struktury przeznaczone wycznie do reprezentowania danych. Specjalnymi typami metod s omwione przed chwil konstruktory i destruktory. W naszych obiektach moemy jednak
tworzy wasne metody, ktre bd odpowiaday za wykonywanie rozmaitych zada.
Tworzenie metody jest procesem dwuetapowym. W pierwszej kolejnoci musimy zadeklarowa now metod w deklaracji typu obiektu, a dopiero potem powinnimy t metod zdefiniowa we waciwej czci kodu. Poniszy fragment kodu demonstruje proces deklarowania i definiowania przykadowej metody:
 
G&5<  
$  8G 6

 
$576
6

 
G&53$576
-
$  8<
6
6

Rozdzia 5.  Jzyk Delphi

131

Zauwa, e podczas definiowania ciaa metody konieczne jest stosowanie jej penej nazwy skadajcej si z nazw klasy i metody. Warto take zwrci uwag na bezporedni dostpno pola   z poziomu ciaa definiowanej metody.

'
W klasach moemy deklarowa nastpujce typy metod: normalne, statyczne (!! ),
wirtualne (!"), klasowe statyczne ( C!! ), klasowe wirtualne ( C!"),
dynamiczne (?1 ) oraz obsugujce komunikaty (1&). Przeanalizujmy poniszy
przykad deklaracji obiektu:
#<  

 
"A&
 6
  
 
"AAH (56
  
 
"AA4  6  6

 
"AA;
 69
 6
  
 
"AA;
 H (569
 6

 
"AA$   6   6

 
"AA( 9
(8( 6 I(e4'(%(%44Ac%6
6

%
  

#11 jest normaln metod Delphi. Jest to domylny typ metod w tym jzyku
metody takie jak #11 dziaaj podobnie jak zwyke procedury i funkcje. Kom-

pilator zna adresy metod tego typu, dziki czemu w momencie wywoania metody
statycznej moe statycznie doczy odpowiednie informacje do wykonywanego kodu.
Metody statyczne s w zwizku z tym wykonywane najszybciej, jednak ze wzgldu na
brak moliwoci ich przykrywania nasze konstrukcje oparte na tych metodach faktycznie trac wasno polimorfizmu.

%
 

#1# !' jest specjalnym, specyficznym dla jzyka Delphi rodzajem metody

statycznej. Metody klasowe mog by wywoywane nawet bez uprzedniego stworzenia


egzemplarza danej klasy, a w przypadku istnienia takich egzemplarzy implementacja
tych metod jest wspdzielona przez wszystkie te egzemplarze. Metody klasowe zawieraj jednak specjalny i ukryty parametr , ktry jest przekazywany przez kompilator
celem zapewnienia moliwoci wywoywania polimorficznych (wirtualnych) metod
klasowych. Dodatkowo metody klasowe mog by wirtualne. Elementy nieklasowe lub
niestatyczne s niedostpne z poziomu ciaa metody klasowej.

%
  

#1#!!  jest prawdziw, zgodn ze specyfikacj platformy .NET metod statyczn.


Podobnie jak pola statyczne implementacja metod tego typu jest wspdzielona przez
wszystkie egzemplarze danej klasy. Oznacza to, e elementy niestatyczne s niedostpne
z poziomu ciaa metody statycznej. Do metod statycznych nie jest przekazywany parametr
, zatem metody niestatyczne nie mog by wywoywane przez metody statyczne.

132

Cz II  Jzyk programowania Delphi for .NET

%
  

#1#!" jest metod wirtualn. Metody tego typu s wywoywane w taki sam spo-

sb jak metody statyczne, jednak z uwagi na brak moliwoci przykrywania metod wirtualnych, kompilator nie zna adresu konkretnej metody wirtualnej w momencie jej wywoania w kodzie programu. W zwizku z tym stosowany w rodowisku .NET kompilator
JIT buduje specjaln tablic metod wirtualnych (ang. Virtual Method Table VMT),
ktra w czasie wykonywania aplikacji jest przeszukiwana pod ktem adresw wywoywanych funkcji wirtualnych. Przez t tablic musz przej wszystkie pojawiajce si
w czasie wykonywania programu wywoania metod wirtualnych. Tablica VMT dla obiektu
zawiera nie tylko informacje na temat wszystkich deklarowanych w tym obiekcie funkcji
wirtualnych, ale dane o wszystkich takich funkcjach deklarowanych w jego przodkach.

%
   

#1#?1  jest metod dynamiczn. Inaczej ni kompilator Win32 (ktry zapewnia

osobny mechanizm obsugi metod dynamicznych), kompilator .NET odwzorowuje metody dynamiczne w odpowiednie metody wirtualne.

%
 $&#'
  
#1# & jest metod obsugujc komunikaty. Uyta dyrektywa 1& powoduje

utworzenie metody, ktra moe odpowiada na dynamicznie pojawiajce si komunikaty.


Warto zadeklarowana bezporednio za sowem 1& okrela, na jakie komunikaty dana
metoda bdzie odpowiadaa. W komponentach udostpnianych przez bibliotek VCL
metody obsugujce komunikaty s wykorzystywane do generowania automatycznych
odpowiedzi na komunikaty systemu Windows, zatem w oglnoci nie s bezporednio
wywoywane przez programistw.

!  


Przykrywanie metod jest oferowan w jzyku Delphi implementacj koncepcji polimorfizmu jednego z podstawowych elementw metodologii programowania obiektowego.
Dziki technice przykrywania metod moemy modyfikowa dziaanie metod na poszczeglnych poziomach dziedziczenia. Jzyk programowania Delphi umoliwia przykrywanie tylko tych metod, ktre zostay wczeniej zadeklarowane jako wirtualne (!"),
dynamiczne (?1 ) lub jako metody obsugujce komunikaty (1&). Aby przykry
metod wirtualn lub dynamiczn, wystarczy w typie obiektu potomnego zamiast sowa
dyrektywy !" lub ?1 uy dyrektywy . Aby przykry metod obsugujc komunikaty, w klasie potomnej naley powtrzy dyrektyw 1& wraz z tym
samym identyfikatorem komunikatu, ktry uyto w klasie macierzystej (bazowej).
Przykadowo, za pomoc poniszej deklaracji klasy potomnej (' moemy przykry metody #1#!", #1#?1  i #1# & zadeklarowane wczeniej
w klasie bazowej (:
#H5<  #

 
"AA;
 69

6

 
"AA$   69

6

 
"AA( 9
(8( 6 I(e4'(%(%44Ac%6
6

Rozdzia 5.  Jzyk Delphi

133

Dyrektywa  zastpuje w tablicy VMT wpis dotyczcy oryginalnej metody informacjami o nowej metodzie. Gdybymy ponownie zadeklarowali metody #1#!"
i #1#?1  ze sowami kluczowymi !" lub ?1 zamiast dyrektywy ,
stworzylibymy nowe metody, zamiast przykry odpowiednie metody klasy bazowej
(. Taki zabieg zazwyczaj bdzie powodowa wygenerowanie ostrzeenia kompilatora,
chyba e wczeniej dodamy do deklaracji tych metod dyrektyw !"  (omwion krtko w dalszej czci tego podrozdziau). Naley take pamita, e prba przykrycia w typie potomnym standardowej metody spowoduje, e metoda statyczna w nowej
klasie sprawi, e metoda ta nie bdzie dostpna dla uytkownikw klasy potomnej.

!
 '


Podobnie jak zwyke funkcje i procedury jzyka Delphi, take metody mog by przeciane, co oznacza, e pojedyncza klasa moe zawiera wiele metod o tej samej nazwie
i rnych listach parametrw. Przeciane metody musz by oznaczane dyrektyw
, chocia stosowanie tej dyrektywy dla pierwszego wystpienia danej nazwy
metody w hierarchii klas jest opcjonalne. Poniszy fragment kodu jest przykadem deklaracji klasy zawierajcej trzy metody przecione:
 
4H <  

 
A(5"8"
69
 6

 
A(548
69
 6

 
A(5$8$-69
 6
6

!
 


Moe si zdarzy, e bdziesz chcia w taki sposb doda metod do jednej ze swoich
klas, aby zastpi metod wirtualn o takiej samej nazwie, ktr zadeklarowano w wykorzystywanej klasie bazowej. W takim przypadku nie powiniene przecia oryginalnej
metody udostpnianej przez klas bazow lepszym rozwizaniem jest jej cakowite
ukrycie i zastpienie now metod. Jeli po prostu dodasz now metod i skompilujesz
swj program, kompilator wygeneruje ostrzeenie wyjaniajce, e nowa metoda ukrywa
identycznie nazwan metod klasy bazowej. Aby przerwa generowanie tego typu ostrzee, w deklaracji metody w klasie potomnej powiniene uy dyrektywy !" .
Poniszy fragment kodu przedstawia przykad prawidowego wykorzystania tej dyrektywy:
 
4G <  

 
H
69
 6
6
4H <  

 
H
6

 6
6

134

Cz II  Jzyk programowania Delphi for .NET

!
 
"
Niejawnie deklarowana zmienna nazwana  jest dostpna wewntrz wszystkich metod
obiektw.  jest referencj do tego egzemplarza klasy, za porednictwem ktrego
wywoano dan metod. Zmienna  jest przekazywana przez kompilator do wszystkich
metod w postaci ukrytego parametru. Odpowiednikiem zmiennej referencyjnej 
w jzyku C# jest zmienna !', natomiast w jzyku Visual Basic .NET jest to zmienna .

(.
! 
Chocia zwyke zmienne mog przechowywa referencje do obiektw, w jzyku Delphi
istnieje take pojcie referencji do klasy, czyli referencji do zdefiniowanego typu
obiektowego. Za pomoc referencji do klas moemy nie tylko wywoywa metody klasowe i statyczne, ale take tworzy egzemplarze tych klas. Poniszy fragment kodu ilustruje
skadni deklaracji klasy (nazwanej 1) i referencji do nowego typu obiektowego:
 
4H <  
 
 
H
 69
 6
  
 
#6
6
4H B:<  :4H 6

Moemy wykorzysta te typy do wywoania metody klasowej 1% za porednictwem naszej nowej referencji do klasy 1 czyli 1) oto przykad
takiego zastosowania tej referencji:
9

4HB:84H B:6
-
4HB:8<4H 6
4HB:3#6

Podobnie, w oparciu o zdefiniowan referencj, moemy stworzy egzemplarz klasy


1:
9

4HB:84H B:6
4H84H 6
-
4HB:8<4H 6
4H8<4HB:3H
 6

Zauwa, e tworzenie egzemplarzy za porednictwem referencji do klasy wymaga zdefiniowania w tej klasie przynajmniej jednego wirtualnego konstruktora. Takie konstruktory
s unikalnymi strukturami stosowanymi wycznie w jzyku programowania Delphi
dziki nim moemy tworzy klasy przez referencje, a wic w sytuacji, gdy konkretny typ
klasy nie jest znany w czasie kompilacji.

Rozdzia 5.  Jzyk Delphi

135

)   
W zrozumieniu sensu istnienia i funkcjonowania waciwoci moe pomc zaoenie,
e s to specjalne pola dostpowe, ktre umoliwiaj nam modyfikowanie danych i wykonywanie kodu zawartego w naszych klasach. W przypadku komponentw to wanie
waciwoci s tymi elementami, ktre s wywietlane w panelu Object Inspector po ich
zaznaczeniu (np. na tworzonym formularzu). Poniszy przykad ilustruje uproszczony
obiekt z jedn wasnoci:
( '-  <  

9 
4; 8"
6

 
44; A; 8"
6
-


 ; 8"

 4; 
44; 6
6

 
( '-  344; A; 8"
6
-
:4; TUA; 5
4; 8<A; 6
6

( ?+P ! jest obiektem zawierajcym nastpujce skadowe: jedno pole (liczba cakowita
1"), jedn metod (procedura nazwana !1") oraz jedn waciwo nazwan ". Zasadniczym zadaniem procedury !1" jest ustawienie wartoci
pola 1". Wasno " w rzeczywistoci nie zawiera adnych danych jest
jedynie akcesorem zdefiniowanym dla pola 1". Dopiero kiedy zadamy waciwoci
" pytanie o reprezentowan przez ni warto, waciwo ta odczyta warto ze zmiennej 1". Kiedy podejmiemy prb ustawienia wartoci waciwoci ", waciwo ta wywoa metod !1", ktra zmodyfikuje warto zmiennej 1".

Takie rozwizanie jest korzystne z kilku powodw. Po pierwsze, umoliwia programicie tworzenie naturalnego mechanizmu pobierania i ustawiania waciwoci (np. podczas ponownego wyznaczania wartoci rwnania lub odwieania widoku kontrolki).
Po drugie, umoliwia nam prezentowanie przed uytkownikami naszej klasy prostej
zmiennej bez koniecznoci zasypywania ich szczegami zwizanymi z implementacj
tej klasy. I wreszcie po trzecie, moemy zezwoli uytkownikom na przykrywanie metod dostpowych (tzw. akcesorw) w klasach potomnych zgodnie z zasad polimorfizmu obiektw.
Podobnie jak w przypadku omwionych wczeniej pl i metod jzyk programowania
Delphi obsuguje take waciwoci statyczne, ktre take deklaruje si ze sowem kluczowym . Poniszy fragment kodu demonstruje klas ze statyczn waciwoci zapewniajc dostp do pola statycznego:
( H <  '-  
  9
#; 8"
6
  
 
4; ; 8"
6  6
  

 ; 8"

 #; 
4; 6
6

Pamitaj, e statyczne waciwoci mog obsugiwa dostp tylko do pl statycznych i wykorzystywa jedynie statyczne metody dostpowe.

136

Cz II  Jzyk programowania Delphi for .NET

&

Jzyk programowania Delphi obsuguje dwa rne typy zdarze: pojedyncze i grupowe.
Zdarzenia pojedyncze s obsugiwane w jzyku Delphi od jego pierwszej wersji. S deklarowane w postaci waciwoci, ktrych typami s typy procedur z akcesorami odczytu () i zapisu (*!). Zdarzenia pojedyncze mog mie zdefiniowane najwyej
po jednej procedurze nasuchujcej. Do czenia tych procedur ze zdarzeniami wykorzystuje si zwyky operator przypisania przypisanie zdarzeniu wartoci  jest
rwnowane z rozczeniem tego zdarzenia i jego dotychczasowej procedury nasuchujcej. Na listingu 5.3 przedstawiono przykadowy kod deklarujcy i wykorzystujcy
zdarzenie pojedyncze.
$ "& Przykadowy program wykorzystujcy zdarzenie pojedyncze
28
?8
D8
J8
K8
@8
L8
S8
M8
2=8
228
2?8
2D8
2J8
2K8
2@8
2L8
2S8
2M8
?=8
?28
??8
?D8
?J8
?K8
?@8
?L8
?S8
?M8
D=8
D28
D?8
DD8
DJ8
DK8
D@8
DL8
DS8
DM8
J=8



96
!A))d)%H'&4'*%
 
( %9<
 
4
8'-  6(8
:-  6
H I5%9<  

9 
#A%98( %96
-

 
#
%96


 A%98( %9
 #A%9
#A%96
6
*
<  

 
%97 
4
8'-  6(8
6
6
H I5%9

 
H I5%93#
%96
-
:A#A%95
#A%94:/> 
  O >6
6
*


 
*
3%97 
4
8'-  6(8
6
-
I
*>F
    3I ^8>/(6
6
9

*8*
6
HI%8H I5%96
-
*8<*
3H
 6
-
HI%8<H I5%93H
 6

Rozdzia 5.  Jzyk Delphi


J28
J?8
JD8
JJ8
JK8

137

HI%3A%98<*3%97 
6
 
 
1- 

HI%3#
%96    

HI%3A%98<6
  
 
1- 

B *6
3

Oto dane wyjciowe wygenerowane przez program z listingu 5.3:


F
    3I ^8 
  O 

Zdarzenia grupowe zostay dodane do najnowszej wersji jzyka Delphi, aby zapewni
zgodno ze specyfikacj platformy .NET, ktra przewiduje moliwo stosowania
wielu procedur nasuchujcych dla pojedynczego zdarzenia. Zdarzenie grupowe jest
wasnoci, ktrej typem jest typ proceduralny i ktra wymaga zdefiniowania akcesorw  i 1. Do dodawania i usuwania procedur nasuchujcych dla zdarzenia grupowego wykorzystuje si odpowiednio procedury  " i : ".
Listing 5.4 zawiera przykadowy kod deklarujcy i wykorzystujcy zdarzenie grupowe.
$ "&Przykadowy program wykorzystujcy zdarzenie grupowe
28
?8
D8
J8
K8
@8
L8
S8
M8
2=8
228
2?8
2D8
2J8
2K8
2@8
2L8
2S8
2M8
?=8
?28
??8
?D8
?J8
?K8
?@8
?L8
?S8
?M8
D=8
D28
D?8
DD8
DJ8
DK8
D@8



96
!A))d)%H'&4'*%

4 +6
 
( %9<
 
4
8'-  6(8
:-  6
H I5%9<  

9 
#A%98( %96
-

 
#
%96


 A%98( %9 #A%9
9#A%96
6
*
<  

 
%97 
4
8'-  6(8
6
6
H I5%9

 
H I5%93#
%96
-
:A#A%95
#A%94:/> 

>6
6
*


 
*
3%97 
4
8'-  6(8
6
-
I
*>F
    3I ^8>/(6
6

138

Cz II  Jzyk programowania Delphi for .NET


DL8
DS8
DM8
J=8
J28
J?8
JD8
JJ8
JK8
J@8
JL8
JS8
JM8
K=8
K28

*2/*?8*
6
HI%8H I5%96
-
*28<*
3H
 6
-
*?8<*
3H
 6
HI%8<H I5%93H
 6
" HI%3A%9/*23%97 
6
 
 
1-


" HI%3A%9/*?3%97 
6
 
 
1-


HI%3#
%96    

%E HI%3A%9/*23%97 
6
  
 
1- 

%E HI%3A%9/*?3%97 
6
  
 
1- 

B *6
3

Oto dane wyjciowe wygenerowane przez program z listingu 5.3:


F
    3I ^8 


F
    3I ^8 



Zwr uwag na fakt, e takie zastosowanie procedury  ", w ktrym do listy procedur nasuchujcych dodalimy t sam metod wicej ni raz, spowoduje, e w przypadku wystpienia obsugiwanego zdarzenia metoda ta zostanie wywoana wielokrotnie.
Aby zachowa zgodno z pozostaymi jzykami rodowiska uruchomieniowego CLR
platformy .NET Framework, kompilator Delphi implementuje semantyk grupow take
dla zdarze pojedynczych, tworzc dla nich akcesory dodawania i usuwania (odpowiednio
 i 1). W przypadku zdarze pojedynczych wywoanie metody  powoduje
zastpienie dotychczasowej wartoci.

/ .  


 
Jzyk Delphi oferuje moliwoci jeszcze dalej idcej kontroli zachowania naszych
obiektw umoliwia nam deklarowanie pl i metod z takimi dyrektywami jak @<
! (prywatne), ! !C @! (cile prywatne), @! ! (chronione), ! !C @<
! ! (cile chronione), @"+ (publiczne) i @"+' (publikowane). Poniszy
przykad ilustruje skadni stosowan dla tych dyrektyw:
4'-  <  

9 
A)
9 ;
 -8"
6
A5
)
9 ;
 -8G 6

 
9 

 
A4
 )
9 (56

 

 
A)
 )
 
6
: )
 (8G 6

 
 

 
A4
 )
 (56

Rozdzia 5.  Jzyk Delphi

139

-
 
 
A)- H
 
6

 
$
 69

6-  


-5


 A)

 8"


 A)
9 ;
 -
A)
9 ;
 -6
6

W kadym z blokw wyznaczanych przez te dyrektywy moemy umieszcza dowoln


liczb pl i metod. Zgodnie ze stylem programowania powiniene w tych blokach stosowa takie same wcicia jak w caym kodzie klasy (wzgldem jej nazwy). Poniej przedstawiono znaczenie poszczeglnych dyrektyw z tej grupy:


@! te skadowe naszego obiektu s dostpne tylko z poziomu kodu


znajdujcego si wewntrz tego samego moduu co implementacja danego
obiektu. Dyrektyw @! wykorzystujemy nie tylko do ukrywania szczegw
implementacji naszych obiektw przed ich uytkownikami, ale take w celu
zapobiegania bezporednim modyfikacjom kluczowych skadowych
dokonywanym przez uytkownikw.

! !C@! te skadowe naszego obiektu s dostpne tylko wewntrz

klasy deklarujcej nie s dostpne w pozostaych czciach tego samego


moduu. Dyrektyw ! !C@! wykorzystujemy do zapewnienia jeszcze
cilejszej izolacji skadowych ni w przypadku dyrektywy @!.


@! ! chronione skadowe naszego obiektu s dostpne dla jego obiektw
potomnych. Dziki temu moemy ukrywa szczegy implementacji naszych
obiektw przed ich uytkownikami, nie tracc przy tym elastycznoci
niezbdnej podczas tworzenia efektywnych obiektw potomnych.

! !C@! ! te skadowe naszego obiektu s dostpne tylko wewntrz


klasy deklarujcej i w jej potomkach, ale nie s dostpne z pozostaych blokw
kodu moduw deklarujcych te klasy. Dyrektyw ! !C@! !
wykorzystujemy do zapewnienia nieco cilejszej izolacji skadowych ni
w przypadku dyrektywy @! !.

@"+ te pola i metody s dostpne ze wszystkich miejsc naszego

programu. Konstruktory i destruktory obiektu zawsze powinny by


deklarowane z dyrektyw @"+ .


@"+' z punktu widzenia dostpnoci skadowych znaczenie tej


dyrektywy jest identyczne jak w przypadku dyrektywy @"+ . Dyrektywa
@"+' oferuje jednak dodatkow korzy w postaci moliwoci dodania
atrybutu G.*+!"H do zawartych w tym bloku waciwoci w ten
sposb powodujemy, e podczas pracy w trybie projektowania (Designer) tak
zdefiniowane waciwoci s widoczne w panelu Object Inspector. Atrybuty
omwimy w dalszej czci tego rozdziau.
Znaczenie dyrektywy @"+' dobrze pokazuje subtelne odejcie od koncepcji
lecych u podstaw implementacji jzyka programowania Delphi dla platformy Win32.
W tamtych wersjach tego jzyka dla waciwoci zadeklarowanych z t dyrektyw
byy generowane informacje o typach RTTI (od ang. Runtime Type Information).
Odpowiednikiem mechanizmu RTTI jest odbicie, jednak okazuje si, e generowanie
odbi jest moliwe dla wszystkich skadowych klas, niezalenie od uytych specyfikatorw
widocznoci (dostpnoci).

140

Cz II  Jzyk programowania Delphi for .NET


Poniej przedstawiono kod definiujcy wprowadzon ju wczeniej klas ( ?+P ! tym
razem jednak zastosowano dyrektywy poprawiajce spjno tego obiektu:
( '-  <  

9 
4; 8"
6

 
44; A; 8"
6
-5


 ; 8"

 4; 
44; 6
6

 
( '-  344; A; 8"
6
-
:4; TUA; 5
4; 8<A; 6
6

Teraz uytkownicy naszego obiektu nie bd ju mogli bezporednio modyfikowa


wartoci pola 1" podczas modyfikowania danych tego obiektu bd musieli
wykorzystywa specjalnie w tym celu zaprojektowany interfejs, ktry opiera si na waciwoci ".

+!*


W jzyku C++ istnieje pojcie tzw. klas zaprzyjanionych (czyli takich, ktre maj dostp
do prywatnych pl i metod nalecych do pozostaych klas). W jzyku programowania C++
mona byo stosowa ten mechanizm za pomoc sowa kluczowego . Jzyki .NET,
w tym Delphi i C#, oferuj podobn moliwo, cho zaimplementowan w zupenie
inny sposb. Wszystkie skadowe klasy zadeklarowane w bloku rozpoczynajcym si od
dyrektywy @! lub @! ! (ale bez dodatkowego specyfikatora ! !) s widoczne
i dostpne dla pozostaych klas i kodu zadeklarowanego wewntrz tej samej przestrzeni
nazw moduu.

+
 
Klasy pomocnicze s wygodnym sposobem rozszerzenia funkcjonalnoci klas wykorzystywanych do tej pory bez koniecznoci ich modyfikowania. Zamiast wprowadza
zmiany, moemy stworzy now klas pomocnicz ('@) i faktycznie przekaza jej
metody do klasy oryginalnej. Dziki temu uytkownicy naszej klasy oryginalnej maj
moliwo wywoywania metod udostpnianych przez klas '@ w taki sam sposb,
jak wywouj metody nalece do klasy oryginalnej.
Poniszy kod jest przykadem utworzenia prostej klasy wraz z klas pomocnicz; demonstruje take sposb wywoywania metody nalecej do klasy '@:


7
6
!A))d)%H'&4'*%
 
#<  

Rozdzia 5.  Jzyk Delphi

141


 
A)
 6
6
#7
<  5
:
#

 
A7
)
 6
6
#

 
#3A)
 6
-
I
*>#3A)
 >6
6
#7


 
#7
3A7
)
 6
-
I
*>#7
3A7
)
 >6
A)
 6
6
9

#8#6
-
#8<#3H
 6
#3A7
)
 6
3

Klasy pomocnicze s interesujcym mechanizmem, jednak w oglnoci ich stosowanie


nie jest potrzebne w przypadku dobrze zaprojektowanego oprogramowania. Utrzymano
ten mechanizm przede wszystkim dlatego, e firma Borland staraa si maksymalnie
ukry rnice pomidzy standardowymi klasami platformy .NET a ich odpowiednikami
tworzonymi w jzyku Delphi dla Win32. Waciwie przeprowadzona faza projektowania
aplikacji powinna bardzo ograniczy lub nawet wykluczy konieczno stosowania klas
pomocniczych.

'


Jzyk programowania Delphi umoliwia umieszczanie klauzuli !?@ wewntrz deklaracji klasy, powodujc tym samym zagniedanie typw wewntrz danej klasy. Do takich
zagniedonych typw moemy si odwoywa zgodnie ze skadni  %
 
 ilustruje to poniszy przykadowy fragment kodu:
 
'H <  

 
4)
 6
 
"H <  

 
4'5
)
 6
6
6
9

"H8'  3"H 6

142

Cz II  Jzyk programowania Delphi for .NET

 

Jzyk programowania Delphi obsuguje technik przeciania operatorw definiowanych
dla klas i rekordw. Skadnia przeciania operatora jest rwnie prosta jak deklarowanie
metody klasowej z konkretn nazw i dodatkow dyrektyw. Pena lista operatorw,
ktre mona przecia w budowanych klasach, jest dostpna na stronach pomocy internetowej dla jzyka Delphi pod hasem Operator Overloads. Zademonstrowany poniej
przykadowy fragment kodu pokazuje sposb, w jaki mona przeciy w kodzie klasy
operatory dodawania i odejmowania:
'9
 '<  

9 
##8"
6
-
  

A /-8'9
 '8'9
 '6
  

4-
 /-8'9
 '8'9
 '6
6
 

'9
 '3A /-8'9
 '8'9
 '6
-
B8<'9
 '3H
 6
B3##8< 3##C-3##6
6
 

'9
 '34-
 /-8'9
 '8'9
 '6
-
B8<'9
 '3H
 6
B3##8< 3##[-3##6
6

Zauwa, e przecione operatory s deklarowane z dyrektyw C@! (operatorw


klasowych) i pobieraj klas deklarujc w formie swoich parametrw. Poniewa ; i < s
operatorami binarnymi, obie metody dodatkowo zwracaj klas deklarujc.
Po zadeklarowaniu operatorw mona je wykorzystywa w sposb zbliony do tego z poniszego przykadu:
9

=2/=?/=D8'9
 '6
-
=28<'9
 '3H
 6
=?8<'9
 '3H
 6
=D8<=2C=?6
6

,
Jednym z najciekawszych elementw, jakie daje programistom platforma .NET Framework,
jest moliwo tworzenia aplikacji opartych na atrybutach nad tak koncepcj wytwarzania oprogramowania od wielu lat pracowali twrcy kilku rnych jzykw programowania. Atrybuty maj na celu wizanie metadanych z takimi elementami jzyka jak
klasy, waciwoci, metody, zmienne i inne konstrukcje wszystkie te zabiegi maj na
celu zapewnienie klientom szerszego zbioru informacji na temat tych elementw.

Rozdzia 5.  Jzyk Delphi

143

Atrybuty s deklarowane za pomoc specjalnej notacji z nawiasami kwadratowymi.


Przykadowo, poniszy wycinek kodu demonstruje sposb uycia atrybutu  1@!,
ktry sygnalizuje platformie .NET konieczno zaimportowania danej metody ze wskazanego pliku biblioteki DLL:
Q$"
>
D?3>R
: ( G 8*I
8G 6E
 6

A kodzie aplikacji dla platformy .NET Framework atrybuty mona wykorzystywa do


rozmaitych celw. Przykadowo, zdefiniowany dla waciwoci atrybut .*+ okrela,
czy dana waciwo powinna by wywietlana i udostpniana w panelu Object Inspector
rodowiska programowania Delphi:
QG
 -
R


 #8

 ##
##6

System atrybutw platformy .NET jest z natury rzeczy rozszerzalny, poniewa same
atrybuty s implementowane w postaci klas. Dziki temu moemy niemal bez ogranicze rozbudowywa ten system tworzy wasne atrybuty od podstaw lub wykorzystywa mechanizm dziedziczenia po klasach istniejcych definiujcych atrybuty i dalej
stosowa nasze nowe atrybuty w innych klasach.

-
.!
Jzyk Delphi oferuje naturaln obsug interfejsw, ktre mwic najprociej definiuj zbir funkcji i procedur wykorzystywanych przez uytkownika do operowania na
obiektach. Definicja interfejsu jest znana zarwno dla czci implementujcej udostpniane elementy, jak i dla klienta tego interfejsu interfejs peni wic rol umowy
pomidzy czci implementacji a klientem, ktra z jednej strony okrela sposb jego
realizacji, a z drugiej strony definiuje sposb jego praktycznego wykorzystania. Pojedyncza klasa moe implementowa wiele interfejsw, oferujc tym samym rne oblicza
danej klasy, za porednictwem ktrych klient moe j kontrolowa.
Jak sama nazwa wskazuje, interfejs definiuje wycznie mechanizm poredniczcy w komunikacji klienta z obiektem. Za obsug interfejsu i odpowiedni implementacj kadej
z jego funkcji i procedur odpowiada klasa.
Inaczej ni w jzyku Delphi dla platformy Win32, interfejsy definiowane w jzyku
Delphi for .NET nie s niejawnymi potomkami interfejsw !  ani  N*.
Oznacza to, e interfejsy definiowane w aplikacjach .NET nie implementuj ju takich
elementw jak R"?! , S#) czy S). Rzutowanie typw jest
teraz wykorzystywane do zapewniania zgodnoci typw, a mechanizm zliczania
referencji jest elementem wbudowanym w platformie .NET.

(
"  

"
#
Skadnia definiowania interfejsu jest bardzo podobna do skadni stosowanej w przypadku
klas. Zasadnicza rnica dotyczy moliwoci tworzenia opcjonalnego cza pomidzy interfejsem a identyfikatorem unikalnym globalnie (ang. Globally Unique Identifier GUID),
ktry peni rol unikalnego reprezentanta danego interfejsu. Poniszy kod definiuje nowy interfejs nazwany , ktry implementuje pojedyncz metod nazwan 2:

144

Cz II  Jzyk programowania Delphi for .NET


 
"#<
: 
: #28"
6
6

Pamitaj, e stosowanie identyfikatorw GUID nie jest wymagane w definicjach interfejsw


dla platformy .NET, cho byy i s one konieczne w aplikacjach dla platformy Win32.
Wykorzystywanie tych identyfikatorw jest wic zalecane tylko wtedy, gdy tworzony
kod ma mie charakter wieloplatformowy lub kiedy wykorzystujesz mechanizm .NET
COM Interop zapewniajcy wspprac pomidzy aplikacj .NET a obiektami COM.
Uycie kombinacji klawiszy Ctrl + Shift + G spowoduje automatyczne wygenerowanie
przez rodowisko programowania Delphi nowych identyfikatorw GUID dla Twoich
interfejsw.

Poniszy fragment kodu definiuje nowy interfejs, ktry jest potomkiem zdefiniowanego
przed chwil interfejsu :
 
"G
<
: "#
: #?8"
6
6

) 



"
#
Poniszy fragment kodu demonstruje sposb, w jaki mona zaimplementowa interfejsy
 oraz . w naszej klasie nazwanej (.:
#G
8
 
#G
<  '-  /"#/"G

: #28"
6
: #?8"
6
6
: #G
3#28"
6
-
B8<=6
6
: #G
3#?8"
6
-
B8<=6
6

Zwr uwag na moliwo wypisywania dowolnej liczby interfejsw bezporednio za


klas przodka w pierwszym wierszu deklaracji klasy umieszczenie w tym miejscu
wicej ni jednego identyfikatora oznacza, e bdziemy implementowali wiele interfejsw.
Proces wizania funkcji zadeklarowanej w naszym interfejsie z konkretn funkcj nalec do klasy odbywa si w tym samym czasie, w ktrym kompilator dopasowuje sygnatury
metod wymienionych w interfejsie do sygnatur metod zdefiniowanych w danej klasie.
W przypadku braku moliwoci znalezienia implementacji jednej lub wicej metod interfejsu w klasie implementujcej ten interfejs kompilator wygeneruje odpowiedni komunikat o bdzie.

Rozdzia 5.  Jzyk Delphi

145

Metody interfejsu uatwiaj prac


Interfejsy s oczywicie wspaniaym rozwizaniem, jednak samodzielne wpisywanie kodu wewntrz klasy, ktry jest niezbdny do zaimplementowania metod interfejsu, moe by bardzo
pracochonne! Poniej przedstawiono moliwoci, jakie daje w tym zakresie rodowisko Delphi
wykonujc ponisze kroki, moesz implementowa wszystkie metody interfejsu przez nacinicie kilku kombinacji klawiszy i kilkukrotne kliknicie mysz:
1. Dodaj do deklaracji swojej klasy interfejs, ktry chcesz zaimplementowa.
2. Umie kursor w dowolnym miejscu wewntrz klasy i nacinij kombinacj klawiszy
Ctrl + Spacja, aby wywoa mechanizm automatycznego wykaczania kodu.
W wywietlonym oknie wykaczania kodu zostan na czerwono wywietlone
niezaimplementowane jeszcze metody.
3. Zaznacz na licie wszystkie metody oznaczone kolorem czerwonym przytrzymujc
wcinity klawisz Shift, uyj klawiszy strzaek lub myszy.
4. Nacinij klawisz Enter metody interfejsu zostan automatycznie dodane do definicji klasy.
5. Nacinij kombinacj klawiszy Ctrl + Shift + C, aby wykoczy cz implementacyjn
dla nowo dodanych metod.
6. Teraz musisz ju tylko odpowiednio wypeni cz implementacyjn kadej z dodanych metod!

Jeli nasza klasa implementuje wiele interfejsw, ktre zawieraj metody oznaczone takimi samymi sygnaturami, musimy dla tych metod stworzy odpowiednie aliasy ilustruje to przedstawiony poniej krtki przykad kodu rdowego:
 
"#<
: 
: #28"
6
6
"G
<
: 
: #28"
6
6
#G
<  '-  /"#/"G

     
: "#3#2<##26
: "G
3#2<G
#26
 
: 
: ##28"
6
: G
#28"
6
6
: #G
3##28"
6
-
B8<=6
6
: #G
3G
#28"
6
-
B8<=6
6

Stosowana w jzyku Delphi dla platformy Win32 dyrektywa 1@1! nie jest ju
dostpna w aktualnej wersji kompilatora Delphi dla platformy .NET.

146

Cz II  Jzyk programowania Delphi for .NET



"
#
Ze stosowaniem w naszych aplikacjach zmiennych typu interfejsowego wie si kilka
istotnych regu jzykowych. Podobnie jak inne typy wykorzystywane w platformie .NET
take interfejsy s zarzdzane w czasie wykonywania programu. Mechanizm odzyskiwania pamici zwolni pami zajmowan przez obiekt dopiero wtedy, gdy zostan zwolnione lub wyjd poza biecy zakres wszystkie referencje do tego obiektu i jego zaimplementowanych interfejsw. Przed uyciem typy interfejsowe s zawsze inicjalizowane
wartoci . Rczne przypisanie wartoci  do zmiennej interfejsu powoduje zwolnienie referencji do odpowiedniego obiektu, ktry jest implementacj danego interfejsu.
Inn unikaln regu dotyczc zmiennych interfejsowych jest ich zgodno (w operacjach
przypisania) z obiektami, ktre te interfejsy implementuj. Naley jednak pamita, e
ta zgodno wystpuje tylko w jedn stron moemy przypisywa referencji do obiektu
referencj do interfejsu, ale nie moemy wykona operacji odwrotnej. Przykadowo,
poniszy fragment kodu jest poprawnym wykorzystaniem zdefiniowanej wczeniej klasy
(.:

 
#G8#G

9

#8"#6
-
#8<#G6- / 0#G  
: "#
3
3
3

Gdyby zmienna . nie bya referencj do klasy implementujcej interfejs , powyszy
fragment kodu zostaby co prawda skompilowany, ale referencja do interfejsu miaaby
warto . W takim przypadku kada kolejna prba wykorzystania tej referencji powodowaaby w czasie wykonywania programu generowanie wyjtku ") : @!.
Jzyk programowania Delphi umoliwia take stosowanie operatora rzutowania typw 
do przeksztacania danej zmiennej referencyjnej do jednego interfejsu w zmienn referencyjn wskazujc na inny interfejs tego samego obiektu. Ilustruje to poniszy fragment kodu:
9

#G8#G
6
#8"#6
G8"G
6
-
#G8<#G
3H
 6
#8<#G6- / 0#G  
: "#
G8<# "G
6
  "G

3
3
3

Gdyby docelowy typ rzutowania nie by zgodny z typem biecym, wynikiem wyraenia
byaby warto .

Rozdzia 5.  Jzyk Delphi

147

+   
 
 
($,'$
Mechanizm obsugi wyjtkw (ang. Structured Exception Handling SEH) jest zcentralizowan i ustandaryzowan metod obsugi bdw, ktry oferuje zarwno nieinwazyjn
obsug wyjtkw na poziomie kodu rdowego aplikacji, jak i moliwo zgrabnego
operowania na niemal wszystkich rodzajach uwarunkowa bdcych rdem wystpowania bdw. Mechanizm SEH dostpny w jzyku programowania Delphi jest odwzorowaniem metod stosowanych w rodowisku uruchomieniowym CLR platformy .NET.
Najkrcej mwic, wyjtki s po prostu klasami, ktre od czasu do czasu przechowuj
informacje o lokalizacji i naturze konkretnego bdu. Dziki zastosowaniu takiego modelu
wyjtki s bardzo atwe w implementacji i stosowaniu nie tylko w naszych aplikacjach,
ale take we wszystkich pozostaych klasach jzyka Delphi.
Platforma .NET udostpnia wiele predefiniowanych wyjtkw reprezentujcych mnstwo
rozmaitych bdw pojawiajcych si w programach dla tej platformy, w tym wyczerpanie pamici, dzielenie przez zero, przekroczenie (w gr lub w d) zakresu liczb czy
bdy operacji wejcia-wyjcia na pliku. Firma Borland zaoferowaa uytkownikom swojego zintegrowanego rodowiska programowania Delphi dodatkowe klasy wyjtkw
umieszczone w bibliotekach RTL i VCL. Oczywicie nic nie stoi na przeszkodzie, abymy
sami definiowali wasne klasy wyjtkw, ktre w jak najwikszym stopniu bd odpowiaday potrzebom naszych aplikacji.
Na listingu 5.5 zademonstrowano sposb wykorzystania mechanizmu obsugi wyjtkw dla
operacji wejcia-wyjcia na pliku tekstowym.
$ "& Operacje wejcia-wyjcia przeprowadzane na pliku z wykorzystaniem mechanizmu
obsugi wyjtkw
28
?8
D8
J8
K8
@8
L8
S8
M8
2=8
228
2?8
2D8
2J8
2K8
2@8
2L8
2S8
2M8
?=8



#"'6
!A))d)%H'&4'*%
4 3"'6
9

#8E#6
48
6
-
A##/>#''3Z>6


B#6


B *#/46
I
*46
: 
H##6
6
E 

148

Cz II  Jzyk programowania Delphi for .NET


?28
??8
?D8
?J8
?K8

4 3"'3"'%E 


I
*>G
 1P>6
6
B *6
3

Na listingu 5.5 wewntrzny blok !?<? jest wykorzystywany do upewnienia si,


e przetwarzany plik tekstowy zostanie zamknity niezalenie od tego, czy podczas samego
przetwarzania wystpi jaki wyjtek. Znaczenie tego bloku mona by wyjani w nastpujcy sposb: Sprbuj wykona instrukcje pomidzy sowami !? i ?. Niezalenie od tego, czy uda si je wykona czy te podjta prba doprowadzi do wygenerowania
wyjtku, wykonaj instrukcje pomidzy sowami ? i . Po wykonaniu tych instrukcji
przejd do kolejnego bloku obsugi wyjtkw. Oznacza to, e przetwarzany plik tekstowy
w kadym przypadku zostanie zamknity, a ewentualny bd bdzie waciwie obsuony
niezalenie od tego, do jakiej kategorii bdzie nalea.
Instrukcje umieszczone po sowie ? w bloku !?<? s wykonywane
niezalenie od ewentualnych wystpie wyjtkw. Upewnij si, e kod zdefiniowany
w bloku ? nie zakada wystpienia jakiegokolwiek wyjtku. Poniewa instrukcja
? w aden sposb nie wstrzymuje przekazywania ewentualnego wyjtku, przepyw
wykonywania programu bdzie w normalny sposb kontynuowany w kolejnych instrukcjach
obsugujcych wyjtki.

Zewntrzny blok !?<: @! jest wykorzystywany do obsugi ewentualnych wyjtkw


wystpujcych w czasie wykonywania programu. Po zamkniciu przetwarzanego pliku
tekstowego w bloku ? kod zawarty w bloku : @! wywietla na konsoli komunikat informujcy uytkownika o wystpieniu bdu operacji wejcia-wyjcia.
Jedn z kluczowych zalet takiego mechanizmu obsugi wyjtkw (przynajmniej w porwnaniu z tradycyjnymi metodami tego typu opartymi najczciej na weryfikacji wartoci zwracanych przez funkcj) jest moliwo penego oddzielenia kodu wykrywajcego bdy od kodu korygujcego wykryte bdy. Takie rozwizanie jest korzystne
przede wszystkim dlatego, e uatwia czytanie i konserwowanie naszego kodu pozwala skupi si w danym momencie tylko na konkretnym obszarze funkcjonalnoci
analizowanej aplikacji.
Due znaczenie ma fakt, e nie moemy za pomoc blokw !?<? zastawia
puapek tylko na z gry okrelone, konkretne wyjtki. Kiedy stosujemy w naszym kodzie blok !?<?, oznacza to, e tak naprawd nie interesuje nas, jakiego rodzaju
wyjtki mog wystpi chcemy jedynie mie pewno, e pewne zadania zostan
prawidowo wykonane niezalenie od ewentualnych wystpie bdw. Blok ?
jest idealnym miejscem do zwalniania przydzielonych wczeniej zasobw (takich jak
pliki czy zasoby systemu Windows), poniewa kod zawarty w tym bloku zostanie wykonany take w przypadku wystpienia bdw. W wielu przypadkach musimy jednak
zastosowa taki mechanizm obsugi bdw, ktry zapewni moliwo rnego reagowania w zalenoci od rodzaju wykrytych bdw. Moemy zastawia puapki na
konkretne wyjtki za pomoc blokw !?<: @! ilustruje to kod z listingu 5.6.

Rozdzia 5.  Jzyk Delphi

149

$ "&. Przykad zastosowania bloku obsugi wyjtkw try-except


28
?8
D8
J8
K8
@8
L8
S8
M8
2=8
228
2?8
2D8
2J8
2K8
2@8
2L8
2S8
2M8
?=8
?28
??8
?D8
?J8



7 "6
!A))d)%H'&4'*%
9

$2/=?/$D8$-6
-


I
>)  -18>6
B *$26
I
>)  1 -18>6
B *$?6
I
>
 1 -1
 
 
333>6
$D8<$2$?6
I
>'.8>/$D8K8?6
E 
4 3'9
:%E 
I
>)

   P>6
4 3$9G F
%E 
I
>&0  ^
  
P>6
G
 3$534 3%"9 
I
>)   -  
 P>6
6
3

Chocia zastosowanie bloku !?<: @! umoliwia nam zastawianie puapek tylko na
okrelone z gry wyjtki, moemy take przechwytywa i obsugiwa wszystkie pozostae
wyjtki, dodajc do tej konstrukcji klauzul . Skadnia konstrukcji !?<: @!<
jest nastpujca:



E 
'%4%E 456

  -   5 V
6

Stosujc konstrukcj !?<: @!<, powiniene pamita, e w czci  bd


przechwytywane i obsugiwane wszystkie wyjtki, wcznie z tymi, ktrych moesz si
w tym miejscu nie spodziewa w tym bdw wyczerpania pamici lub innych
wyjtkw biblioteki uruchomieniowej. W zwizku z tym uywaj klauzuli  bardzo
ostronie i staraj si robi to moliwie rzadko. Kady przechwycony w ten sposb
(a wic troch przypadkowo) wyjtek powiniene ponownie generowa. Wicej
informacji na ten temat znajdziesz w punkcie Ponowne generowanie wyjtkw.

Ten sam efekt, ktry uzyskujemy za pomoc konstrukcji !?<: @!<, moemy
uzyska take za pomoc uproszczonej wersji bloku !?<: @!, w ktrej nie okrelimy
klasy wyjtku oto przykad:



E 
          
6

150

Cz II  Jzyk programowania Delphi for .NET

+! 
Wyjtki s po prostu specjalnymi egzemplarzami obiektw. Odpowiednie egzemplarze
s tworzone w momencie wystpowania reprezentowanych przez nie wyjtkw i s niszczone w chwili ich przechwycenia i obsuenia w kodzie programu. Obiektem bazowym dla
wszystkich wyjtkw w aplikacjach platformy .NET jest ?!1%: @!.
Jednym z waniejszych elementw w obiekcie : @! jest waciwo &, ktra
reprezentuje acuch z dodatkowymi informacjami lub wyjanieniem danego wyjtku.
Rodzaj informacji zawartych w tym acuchu zaley oczywicie od typu odpowiedniego
wyjtku.
Jeli zdecydujesz si na definiowanie wasnego obiektu wyjtku, upewnij si, e Twj
obiekt dziedziczy po znanym obiekcie wyjtku po najbardziej oglnym obiekcie
bazowym : @! lub jednym z jego potomkw. Dziki temu oglne procedury
obsugi wyjtkw bd mogy odpowiednio przechwytywa Twj wyjtek.

Kiedy obsugujemy w bloku : @! konkretny rodzaj wyjtku, ten sam blok bdzie przechwytywa take wszystkie te wyjtki, ktre zostay zdefiniowane jako obiekty potomne wzgldem wyjtku, ktry wskazalimy w tym bloku. Przykadowo, obiekt ?!1%
#!'1! : @! jest przodkiem dla wielu wyjtkw zwizanych z dziaaniami
matematycznymi, w tym wyjtku dzielenia przez zero (.?T: @!), niezastosowania liczby skoczonej (!!"1+: @!) czy przekroczenia zakresu
(*: @!). Moemy przechwytywa dowolne z tych wyjtkw, ustawiajc
w bloku : @! klas bazow #!'1! : @! (patrz poniszy przykad):



E 
%( 5%



 5 %( 5%


  
 
6

Wszystkie pojawiajce si wyjtki, ktrych nie obsugujesz w swoim programie wprost


(nie wymieniasz ich w bloku : @!), bd przechowywane na stosie a do momentu
ich obsuenia. W aplikacjach typu WinForm i WebForm dla platformy .NET domylny
mechanizm obsugi wyjtkw sam odpowiada za realizacj zada zmierzajcych do prezentowania informacji o wyjtkach przed uytkownikiem. W aplikacjach opartych na
komponentach biblioteki VCL domylny mechanizm obsugi wyjtkw wywietla specjalne okno dialogowe z komunikatem informujcym uytkownika o zaistniaej sytuacji.
W naszym kodzie przechwytujcym i obsugujcym wyjtki musimy niekiedy uzyska
dostp do egzemplarza obiektu wyjtku, aby uzyska wicej informacji na jego temat
take tych udostpnianych przez waciwo &. Istniej dwa sposoby uzyskiwania takiego dostpu. Po pierwsze, metod preferowan jest wykorzystanie opcjonalnego identyfikatora ju w konstrukcji  

. Moemy take uy funkcji
: @!+P ! nie jest to jednak sposb zalecany.
Do czci  

 bloku : @! moemy doda opcjonalny identyfikator,
ktry bdzie reprezentowa odpowiedni egzemplarz aktualnie obsugiwanego wyjtku.

Rozdzia 5.  Jzyk Delphi

151

Zgodnie ze skadni jzyka programowana Delphi taki identyfikator powinien poprzedza


nazw typu wyjtku (oba elementy powinny by oddzielone dwukropkiem) oto przykad:


! 
E 
%8%4%E 
45( %3( 6
6

Identyfikator egzemplarza (w tym przypadku ) otrzymuje referencj do wanie przechwyconego wyjtku. Taki identyfikator jest zawsze tego samego typu co poprzedzany przez
niego wyjtek.
Skadnia generowania wyjtkw jest podobna do skadni tworzenia egzemplarza obiektu.
Aby wygenerowa np. zdefiniowany przez uytkownika wyjtek .!", uylibymy
nastpujcej skadni:

%G 4::3H
 >4- ::5 3>6

 
 

Po wywoaniu wyjtku sterowanie dziaaniem naszego programu jest przekazywane do
kolejnej procedury obsugi wyjtkw i pozostaje tam a do momentu penego obsuenia
i zniszczenia danego egzemplarza wyjtku. Cay ten proces jest kontrolowany przez stos
wywoa, dotyczy zatem caego programu (nie tylko pojedynczej procedury lub biecego moduu). Na listingu 5.7 przedstawiono modu VCL, ktry dobrze ilustruje przepyw sterowania dziaaniem programu w przypadku wystpienia wyjtku. Listing zawiera
gwny modu aplikacji napisanej w jzyku Delphi, ktra skada si z pojedynczej formy
zawierajcej jeden przycisk. Kliknicie tego przycisku powoduje, e metoda ."!!2 N
wywouje procedur
 2, ktra wywouje procedur
 B, ktra z kolei wywouje procedur
 =. Poniewa wyjtek jest generowany w procedurze
 =, moemy przeledzi przepyw sterowania dziaaniem programu za porednictwem kolejnych
blokw !?<? a do momentu, w ktrym wygenerowany wyjtek zostanie ostatecznie obsuony wewntrz metody ."!!2 N.
$ "&/ Gwny modu programu demonstrujcego przepyw sterowania jego dziaaniem
28
?8
D8
J8
K8
@8
L8
S8
M8
2=8
228
2?8
2D8
2J8

( 6

: 

I/( /4 +/;
 /H /c
5 /H
/#
/
$ 6
 
#
2<  #

G8G6

 
G2H 4
8'-  6
6

152

Cz II  Jzyk programowania Delphi for .NET


2K8
2@8
2L8
2S8
2M8
?=8
?28
??8
?D8
?J8
?K8
?@8
?L8
?S8
?M8
D=8
D28
D?8
DD8
DJ8
DK8
D@8
DL8
DS8
DM8
J=8
J28
J?8
JD8
JJ8
JK8
J@8
JL8
JS8
JM8
K=8
K28
K?8
KD8
KJ8
KK8
K@8
KL8
KS8
KM8
@=8
@28
@?8
@D8
@J8
@K8

#
28#
26
 
!B3:
 
%G 4::<  %E 6

 
)
 D6
-



%G 4::3H
 >"  V
 P>6
: 
45( >I    3)
 
)
 D -  ->6
6
6

 
)
 ?6
-


)
 D6
: 
45( >)
 
)
 ? -  ->6
6
6

 
)
 26
-


)
 ?6
: 
45( >)
 
)
 2 -  ->6
6
6

 
#
23G2H 4
8'-  6

%E (<>I -0     
 
3I ^N]N>6
-
45( >    
 
1)
 2V
  
 
1)
 ?
V
  )
 D>6


)
 26
E 
%8%G 4::
45( #
 %E (/Q%3( R6
6
6
3

Kiedy uruchomisz ten program w rodowisku programowania Delphi, bdziesz mia


moliwo jeszcze lepszej obserwacji przepywu sterowania dziaaniem aplikacji, jeli
wyczysz mechanizm obsugi wyjtkw zintegrowanego z tym rodowiskiem programu
uruchomieniowego usu zaznaczenie opcji Tools/Options/Debugger Options/Borland
.NET Debugger/Language Exceptions/Stop on Language Exceptions.

Rozdzia 5.  Jzyk Delphi

153





! 
Kiedy musimy uy specjalnego mechanizmu obsugi ewentualnych wyjtkw dla instrukcji znajdujcej si wewntrz istniejcego bloku !?<: @!, nie powodujc przy
tym przerwania przepywu sterowania dziaaniem programu do domylnej, zewntrznej
procedury obsugi wyjtkw, moemy zastosowa technik nazywan ponownym generowaniem wyjtkw. Przykad uycia tej techniki zademonstrowano na listingu 5.8.
$ "&0 Ponowne generowanie wyjtku
28
?8
D8
J8
K8
@8
L8
S8
M8
2=8
228
2?8
2D8
2J8
2K8
2@8
2L8


 - 1


 

 

 

   -1

  
       - V
E 
%4%E 
-
  -  V 
 
-

6
   1
-
6
6
E 
 1
 -     
 
1- V
%4%E 456
6

Você também pode gostar