SlideShare a Scribd company logo
1 of 43
Download to read offline
IDZ DO
         PRZYK£ADOWY ROZDZIA£

                           SPIS TREŒCI
                                         Visual Basic 2005.
                                         Zapiski programisty
           KATALOG KSI¥¯EK               Autor: Matthew MacDonald
                                         T³umaczenie: Grzegorz Werner
                      KATALOG ONLINE     ISBN: 83-246-0087-6
                                         Tytu³ orygina³u: Visual Basic 2005: A Developers Notebook
       ZAMÓW DRUKOWANY KATALOG           Format: B5, stron: 304
                                         Przyk³ady na ftp: 1986 kB

              TWÓJ KOSZYK
                    DODAJ DO KOSZYKA     Visual Basic 2005 nie jest tak rewolucyjnym produktem, jak Visual Basic .NET.
                                         Opracowuj¹c wersjê 2005, twórcy jêzyka skoncentrowali siê na usuniêciu b³êdów
                                         i usterek oraz zwiêkszeniu komfortu pracy programisty. Narzêdzia i kontrolki,
         CENNIK I INFORMACJE             w które wyposa¿ono zarówno najnowsz¹ wersjê Visual Basica, jak i œrodowisko
                                         programistyczne Visual Studio 2005, pozwalaj¹ znacznie przyspieszyæ pisanie kodu.
                   ZAMÓW INFORMACJE      Jednoczeœnie zosta³ zachowany dostêp do wszystkich mo¿liwoœci platformy .NET.
                     O NOWOŒCIACH        Ksi¹¿ka „Visual Basic 2005. Zapiski programisty” to zbiór notatek spisanych przez
                                         programistów analizuj¹cych tê wersjê jêzyka. Zawiera æwiczenia ilustruj¹ce nowe
                       ZAMÓW CENNIK      funkcje Visual Basica 2005, platformy .NET Framework 2.0 i œrodowiska
                                         programistycznego Visual Studio 2005. Programiœci korzystaj¹cy z wczeœniejszych
                                         wersji tych narzêdzi szybko opanuj¹ nowe funkcje, takie jak definiowanie klas
                 CZYTELNIA               generycznych czy korzystanie z obiektów My. Godne odnotowania jest tak¿e znaczne
                                         przyspieszenie i udoskonalenie technologii ASP.NET.
          FRAGMENTY KSI¥¯EK ONLINE           • Edycja kodu w Visual Studio 2005
                                             • Tworzenie dokumentacji w formacie XML
                                             • Korzystanie z obiektów My
                                             • Definiowanie klas generycznych
                                             • Tworzenie aplikacji dla œrodowiska Windows oraz aplikacji WWW
                                             • Projektowanie formularzy
                                             • Komunikacja z bazami danych
                                             • Wdra¿anie aplikacji za pomoc¹ technologii ClickOnce
                                         Dziêki tej ksi¹¿ce najnowsza wersja Visual Basica ods³ania swoje tajemnice.


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




Seria „Zapiski programisty” .................................................................. 7

Przedmowa .......................................................................................... 13

Rozdział 1. Visual Studio ..................................................................... 19
         Podstawowe informacje o Visual Studio 2005 ..................................... 20
         Kodowanie, debugowanie i kontynuacja
          bez ponownego uruchamiania aplikacji ............................................ 23
         Zaglądanie do wnętrza obiektu podczas debugowania ........................ 26
         Diagnozowanie i poprawianie błędów „w locie” .................................. 29
         Zmiana nazwy wszystkich wystąpień dowolnego elementu programu .... 31
         Filtrowanie IntelliSense i autokorekta ................................................. 35
         Wywoływanie metod podczas projektowania aplikacji ........................ 37
         Wstawianie szablonowego kodu .......................................................... 39
         Tworzenie dokumentacji XML ............................................................ 41

Rozdział 2. Język Visual Basic ............................................................. 47
         Wykonywanie popularnych zadań za pomocą obiektów My ............... 48
         Uzyskiwanie informacji o aplikacji ..................................................... 52
         Używanie ściśle typizowanych zasobów ............................................. 54




                                                                                                          3
Używanie ściśle typizowanych ustawień konfiguracyjnych ................57
            Tworzenie klas generycznych .............................................................60
            Używanie wartości pustych w prostych typach danych .......................65
            Używanie operatorów w połączeniu z własnymi obiektami ................67
            Dzielenie klasy na wiele plików ...........................................................72
            Rozszerzanie przestrzeni nazw My .....................................................73
            Przechodzenie do następnej iteracji pętli .............................................76
            Automatyczne usuwanie obiektów .......................................................79
            Ochrona właściwości przy użyciu różnych poziomów dostępu ............81
            Testowanie kolejnych części wyrażenia warunkowego .......................82

    Rozdział 3. Aplikacje Windows ............................................................ 85
            Używanie pasków narzędzi w stylu pakietu Office ..............................86
            Dodawanie dowolnych kontrolek do paska ToolStrip ...........................91
            Dodawanie ikon do menu ....................................................................92
            Wyświetlanie strony WWW w oknie aplikacji .....................................95
            Weryfikowanie danych podczas ich wpisywania ................................99
            Tworzenie pól tekstowych z funkcją autouzupełniania ......................103
            Odtwarzanie systemowych dźwięków Windows ................................105
            Odtwarzanie prostych dźwięków WAV ..............................................106
            Tworzenie podzielonego okna w stylu Eksploratora Windows ...........108
            Automatyczne rozmieszczanie kontrolek ...........................................111
            Określanie momentu zakończenia aplikacji .......................................113
            Zapobieganie uruchamianiu wielu kopii aplikacji ..............................117
            Komunikacja między formularzami ..................................................118
            Przyspieszanie przerysowywania GDI+ ...........................................120
            Bezpieczna obsługa zadań asynchronicznych ...................................124
            Lepsza siatka danych ........................................................................128
            Formatowanie siatki DataGridView ...................................................132
            Dodawanie obrazów i kontrolek do siatki DataGridView ....................135




4   Spis treści
Rozdział 4. Aplikacje WWW ............................................................... 139
        Tworzenie aplikacji WWW w Visual Studio 2005 ............................. 140
        Administrowanie aplikacją WWW .................................................... 143
        Wiązanie danych bez pisania kodu ................................................... 146
        Wiązanie kontrolek WWW z niestandardową klasą ......................... 151
        Wyświetlanie interaktywnych tabel bez pisania kodu ....................... 156
        Wyświetlanie pojedynczych rekordów .............................................. 159
        Ujednolicanie wyglądu aplikacji przy użyciu stron szablonu ............ 165
        Dodawanie elementów nawigacyjnych do witryny WWW ................ 170
        Łatwe uwierzytelnianie użytkowników ............................................. 174
        Sprawdzanie bieżącej liczby użytkowników witryny ......................... 182
        Uwierzytelnianie oparte na rolach .................................................... 183
        Przechowywanie indywidualnych informacji o użytkownikach ........ 188

Rozdział 5. Pliki, bazy danych i XML .................................................. 195
        Pobieranie informacji o dyskach ....................................................... 196
        Pobieranie informacji o plikach i katalogach ..................................... 199
        Kopiowanie, przenoszenie i usuwanie plików ................................... 201
        Odczytywanie i zapisywanie plików .................................................. 204
        Kompresowanie i dekompresowanie danych .................................... 206
        Gromadzenie danych statystycznych
         o połączeniach ze źródłami danych ................................................ 209
        Łączenie poleceń adaptera danych w celu zwiększenia wydajności .. 212
        Hurtowe kopiowanie wierszy z jednej tabeli do drugiej ..................... 215
        Pisanie kodu niezależnego od używanej bazy danych ....................... 219
        Nowe klasy XPathDocument i XPathNavigator ................................. 224
        Edycja dokumentów XML przy użyciu klasy XPathNavigator .......... 229

Rozdział 6. Usługi platformy .NET ...................................................... 235
        Łatwe rejestrowanie zdarzeń ............................................................ 236
        Sprawdzanie łączności z innym komputerem ................................... 240
        Uzyskiwanie informacji o połączeniu sieciowym .............................. 243



                                                                                        Spis treści    5
Wysyłanie i pobieranie plików przy użyciu FTP ................................246
             Testowanie przynależności grupowej bieżącego użytkownika ...........253
             Szyfrowanie danych dla bieżącego użytkownika ...............................255
             Ujarzmianie konsoli ..........................................................................258
             Mierzenie czasu wykonywania kodu .................................................262
             Wdrażanie aplikacji za pomocą technologii ClickOnce .......................264

    Skorowidz .......................................................................................... 271




6   Spis treści
ROZDZIAŁ 2


                          Język Visual Basic




W tym rozdziale:
   Wykonywanie popularnych zadań za pomocą obiektów My
   Uzyskiwanie informacji o aplikacji
   Używanie ściśle typizowanych zasobów
   Używanie ściśle typizowanych ustawień konfiguracyjnych
   Tworzenie klas generycznych
   Używanie wartości pustych w prostych typach danych
   Używanie operatorów w połączeniu z własnymi obiektami
   Dzielenie klasy na wiele plików
   Rozszerzanie przestrzeni nazw My
   Przechodzenie do następnej iteracji pętli
   Automatyczne usuwanie obiektów

Kiedy pojawiła się pierwsza wersja Visual Basica .NET, lojalni progra-
miści VB byli zaszokowani drastycznymi zmianami w ich ulubionym
języku. Ni stąd, ni zowąd proste czynności, takie jak tworzenie instancji
obiektu i deklarowanie struktury, wymagały nowej składni, a podsta-
wowe typy, na przykład tablice, zostały przekształcone w coś zupełnie
innego. Na szczęście w Visual Basicu 2005 nie ma takich niespodzianek.
Zmiany w najnowszych wersjach języka upraszczają programowanie,

                                                                            47
ale nie sprawiają, że istniejący kod staje się przestarzały. Wiele spośród
                       tych zmian to funkcje przeniesione z języka C# (na przykład przeciąża-
                       nie operatorów), a inne to zupełnie nowe składniki wbudowane w naj-
                       nowszą wersję wspólnego środowiska uruchomieniowego (na przykład
                       klasy generyczne). W tym rozdziale opiszemy najprzydatniejsze zmiany
                       w języku VB.


                       Wykonywanie popularnych zadań
                       za pomocą obiektów My
                       Nowe obiekty My zapewniają łatwy dostęp do popularnych funkcji, które
                       niełatwo jest znaleźć w obszernej bibliotece klas .NET. Zasadniczo obiekty
                       My udostępniają różnorodne elementy, od rejestru Windows do ustawień
                       bieżącego połączenia sieciowego. Co najlepsze, hierarchia obiektów My jest
                       zorganizowana według zastosowań i łatwo się po niej poruszać przy
                       użyciu IntelliSense.

Przedzieranie się      Jak to zrobić?
przez obszerną
bibliotekę klas .NET   Istnieje siedem podstawowych obiektów My. Spośród nich trzy kluczowe
w poszukiwaniu
potrzebnej funkcji
                       obiekty centralizują zestaw funkcji .NET Framework i dostarczają in-
bywa męczące.          formacji o komputerze. Są to:
Dzięki nowym
obiektom My można
                       My.Computer
szybko znaleźć             Ten obiekt zawiera informacje o komputerze, w tym o jego połącze-
najprzydatniejsze          niu sieciowym, stanie myszy i klawiatury, bieżącym katalogu, dru-
funkcje oferowane
przez .NET.                karce, ekranie oraz zegarze. Można też użyć go jako punktu wyjścia
                           do odtwarzania dźwięków, wyszukiwania plików, dostępu do reje-
                           stru albo korzystania ze schowka Windows.
                       My.Application
                           Ten obiekt zawiera informacje o bieżącej aplikacji i jej kontekście,
                           w tym o podzespole i jego wersji, kulturze, a także o argumentach
                           wiersza polecenia użytych podczas uruchamiania aplikacji. Można
                           go również użyć do rejestrowania zdarzeń występujących w aplikacji.




48                     Rozdział 2: Język Visual Basic
My.User
   Ten obiekt zawiera informacje o bieżącym użytkowniku. Można użyć
   go do sprawdzenia konta użytkownika Windows i ustalenia, do jakiej
   grupy należy użytkownik.
Obok tych trzech obiektów istnieją kolejne dwa, które zapewniają dostęp do
instancji domyślnych. Instancje domyślne to obiekty, które .NET tworzy
automatycznie dla pewnych typów klas zdefiniowanych w aplikacji. Są to:
My.Forms
   Ten obiekt zapewnia instancję domyślną każdego formularza Windows
   w aplikacji. Można użyć go do obsługi komunikacji między formu-
   larzami bez śledzenia referencji do formularzy w oddzielnej klasie.
My.WebServices
   Ten obiekt zapewnia instancję domyślną klasy pośredniczącej dla
   każdej usługi WWW. Jeśli na przykład projekt używa dwóch referen-
   cji WWW, poprzez ten obiekt można uzyskać dostęp do gotowej klasy
   pośredniczącej dla każdej z nich.
Kolejne dwa obiekty My zapewniają łatwy dostęp do ustawień konfigura-
cyjnych i zasobów:
My.Settings
   Ten obiekt umożliwia pobranie ustawień z pliku konfiguracyjnego
   XML aplikacji.
My.Resources
   Ten obiekt umożliwia pobieranie zasobów — bloków danych binar-
   nych lub tekstowych, które są kompilowane z podzespołem aplikacji.
   Zasobów zwykle używa się do przechowywania wielojęzycznych łań-
   cuchów, obrazów i plików dźwiękowych.

                               O S T R Z EŻ ENIE
       Warto zaznaczyć, że działanie obiektów My zależy od typu projektu.
       Na przykład w aplikacjach WWW lub aplikacjach konsoli nie można
       korzystać z kolekcji My.Forms.




                           Wykonywanie popularnych zadań za pomocą obiektów My   49
Niektóre spośród klas My są zdefiniowane w przestrzeni nazw Microsoft.
       VisualBasic.MyServices, a inne, na przykład klasy używane w obiek-
     tach My.Settings i My.Resources, są tworzone dynamicznie przez Visual
     Studio 2005 podczas modyfikowania ustawień aplikacji i dodawania za-
     sobów do bieżącego projektu.
     Aby wypróbować obiekt My, można skorzystać z funkcji IntelliSense.
     Wystarczy wpisać słowo My oraz kropkę i obejrzeć dostępne obiekty (ry-
     sunek 2.1). Następnie można wybrać jeden z nich i wpisać kolejną kropkę,
     aby przejść na niższy poziom hierarchii.




     Rysunek 2.1. Przeglądanie obiektów My

     W celu wypróbowania prostego kodu, który wyświetla kilka podstawowych
     informacji z wykorzystaniem obiektu My, utwórzmy nowy projekt typu
     Console Application. Następnie dodajmy poniższy kod do procedury Main():
         Console.WriteLine(My.Computer.Name)
         Console.WriteLine(My.Computer.Clock.LocalTime)
         Console.WriteLine(My.Computer.FileSystem.CurrentDirectory)
         Console.WriteLine(My.User.Name)

     Po uruchomieniu tego kodu w oknie konsoli zostanie wyświetlona nazwa
     komputera, bieżący czas, bieżący katalog oraz nazwa użytkownika:
         SALESSERVER
         2005-07-06 11:18:18
         C:KodNotatnikVB1.07Testbin
         MATTHEW




50   Rozdział 2: Język Visual Basic
O S T R Z EŻ ENIE
       Obiekt My ma również „ciemną stronę”. Rozwiązania, w których go
       zastosowano, trudniej współużytkować z innymi programistami,
       ponieważ nie jest on obsługiwany w językach innych niż VB (na
       przykład C#).



Więcej informacji
Aby dowiedzieć się więcej o obiekcie My i zobaczyć przykłady jego uży-
cia, należy zajrzeć pod hasło indeksu „My Object” w pomocy MSDN.
Można też wykonać inne ćwiczenia, w których wykorzystano obiekt My.
Oto kilka przykładów:
 • używanie obiektu My.Application do pobierania informacji o pro-
   gramie, takich jak bieżąca wersja oraz parametry wiersza polecenia
   podane podczas uruchamiania aplikacji (ćwiczenie „Uzyskiwanie
   informacji o aplikacji” dalej w tym rozdziale);
 • wczytywanie obrazów i innych zasobów z podzespołu aplikacji za
   pomocą obiektu My.Resources (ćwiczenie „Używanie ściśle typizo-
   wanych zasobów” dalej w tym rozdziale);
 • pobieranie ustawień aplikacji i użytkownika za pomocą obiektu
   My.Settings (ćwiczenie „Używanie ściśle typizowanych ustawień
   konfiguracyjnych” dalej w tym rozdziale);
 • używanie obiektu My.Forms do interakcji między oknami aplikacji
   (ćwiczenie „Komunikacja między formularzami” w rozdziale 3.);
 • manipulowanie plikami i połączeniami sieciowymi za pomocą obiektu
   My.Computer (rozdziały 5. i 6.);

 • uwierzytelnianie użytkownika za pomocą obiektu My.User (ćwiczenie
   „Testowanie przynależności grupowej bieżącego użytkownika” w roz-
   dziale 6.).




                          Wykonywanie popularnych zadań za pomocą obiektów My   51
Za pomocą obiektu
My.Application
                        Uzyskiwanie informacji o aplikacji
można pobrać
informacje o bieżącej   Obiekt My.Application udostępnia wiele przydatnych informacji. W celu
wersji aplikacji,       ich pobrania wystarczy odczytać właściwości obiektu.
jej położeniu
oraz parametrach
użytych do jej          Jak to zrobić?
uruchomienia.
                        Informacje zawarte w obiekcie My.Application przydają się w wielu róż-
                        nych sytuacjach. Oto dwa przykłady:
                         • Chcemy ustalić dokładny numer wersji. Bywa to użyteczne, jeśli
                           chcemy wyświetlić dynamiczne okno z informacjami o programie
                           albo sprawdzić usługę WWW i upewnić się, że mamy najnowszą
                           wersję podzespołu.
                         • Chcemy zarejestrować pewne informacje diagnostyczne. Jest to istotne,
                           jeśli problem występuje u klienta i musimy zapisać ogólne informacje
                           o działającej aplikacji.
                        Aby sprawdzić, jak to działa, można wykorzystać kod z listingu 2.1 w apli-
                        kacji konsoli. Pobiera on wszystkie informacje i wyświetla je w oknie
                        konsoli.

                        Listing 2.1. Pobieranie informacji z obiektu My.Application
                              ' Ustalamy parametry, z jakimi została uruchomiona aplikacja
                              Console.Write("Parametry wiersza polecenia: ")
                              For Each Arg As String In My.Application.CommandLineArgs
                                   Console.Write(Arg & " ")
                              Next
                              Console.WriteLine()
                              Console.WriteLine()

                              ' Pobieramy informacje o podzespole, w którym znajduje się ten kod
                              ' Informacje te pochodzą z metadanych (atrybutów w kodzie)
                              Console.WriteLine("Firma: " & My.Application.Info.CompanyName)
                              Console.WriteLine("Opis: " & My.Application.Info.Description)
                              Console.WriteLine("Lokalizacja: " & My.Application.Info.DirectoryPath)
                              Console.WriteLine("Prawa autorskie: " & My.Application.Info.Copyright)
                              Console.WriteLine("Znak towarowy: " & My.Application.Info.Trademark)
                              Console.WriteLine("Nazwa: " & My.Application.Info.AssemblyName)
                              Console.WriteLine("Produkt: " & My.Application.Info.ProductName)
                              Console.WriteLine("Tytuł: " & My.Application.Info.Title)
                              Console.WriteLine("Wersja: " & My.Application.Info.Version.ToString())
                              Console.WriteLine()




52                      Rozdział 2: Język Visual Basic
WS KAZÓWK A
       Visual Studio 2005 zawiera okno Quick Console, które jest uprosz-
       czoną wersją zwykłego okna wiersza poleceń. W niektórych przy-
       padkach okno to działa nieprawidłowo. W razie problemów z uru-
       chamianiem przykładowej aplikacji i wyświetlaniem jej wyników
       należy wyłączyć okno Quick Console. W tym celu należy wybrać
       z menu Tools polecenie Options, upewnić się, że zaznaczone jest pole
       wyboru Show all settings, po czym przejść do pozycji Debugging –>
       General. Następnie należy usunąć zaznaczenie z pola Redirect all
       console output to the Quick Console window.


Przed przetestowaniem powyższego kodu warto skonfigurować środowisko
tak, aby program zwrócił sensowne wyniki. Można na przykład przeka-
zać parametry wiersza polecenia do uruchamianej aplikacji. W tym celu
należy kliknąć dwukrotnie ikonę My Project w oknie Solution Explorer.
Następnie należy przejść na zakładkę Debug i poszukać pola tekstowego
Command line parameters. W polu tym należy wpisać parametry wiersza
polecenia, na przykład /a /b /c.
Aby określić informacje, takie jak autor podzespołu, produkt, wersja itd.,
trzeba dodać specjalne atrybuty do pliku AssemblyInfo.vb, który zwykle
nie jest widoczny w oknie Solution Explorer. Aby go wyświetlić, należy
wybrać z menu Project polecenie Show All Files. Plik AssemblyInfo.vb
jest umieszczony pod węzłem My Project. Oto typowy zestaw znaczni-
ków, które można określić w tym pliku:
   <Assembly:   AssemblyVersion("1.0.0.0")>
   <Assembly:   AssemblyCompany("Prosetech")>                                          Nowością w VB
   <Assembly:   AssemblyDescription("Program testujący obiekt My.Application")>        2005 jest możliwość
   <Assembly:   AssemblyCopyright("(C) Matthew MacDonald")>
                                                                                       dodawania info-
   <Assembly:   AssemblyTrademark("(R) Prosetech")>
                                                                                       rmacji o aplikacji
   <Assembly:   AssemblyTitle("Aplikacja testowa")>
   <Assembly:   AssemblyProduct("Aplikacja testowa")>                                  w specjalnym oknie
                                                                                       dialogowym. Aby
Wszystkie te informacje zostaną osadzone w skompilowanym podze-                        skorzystać z tej
                                                                                       funkcji, należy
spole jako metadane.                                                                   kliknąć dwukrotnie
Teraz można uruchomić testową aplikację. Oto przykładowe wyniki:                       ikonę My Project
                                                                                       w oknie Solution
   Parametry wiersza polecenia: /a /b /c                                               Explorer, przejść na
                                                                                       zakładkę Application
   Firma: Prosetech
                                                                                       i kliknąć przycisk
   Opis: Program testujący obiekt My.Application
   Lokalizacja: C:NotatnikVB2InformacjeOAplikacjibinDebug                         Assembly Information.



                                                  Uzyskiwanie informacji o aplikacji                     53
Prawa autorskie: (C) Matthew MacDonald
                            Znak towarowy: (R) Prosetech
                            Nazwa: InformacjeOAplikacji
                            Produkt: Aplikacja testowa
                            Tytuł: Aplikacja testowa
                            Wersja: 1.0.0.0


                        A co…
                        …z uzyskiwaniem bardziej szczegółowych informacji diagnostycznych?
                        Obiekt My.Computer.Info ma dwie przydatne właściwości, które dostar-
                        czają takich informacji. Właściwość LoadedAssemblies to kolekcja wszyst-
                        kich podzespołów, które są obecnie wczytane (i dostępne dla aplikacji).
                        Można też zbadać ich wersje oraz informacje o wydawcy. Właściwość
                        StackTrace zawiera bieżący obraz stosu i pozwala ustalić, którą część
                        kodu obecnie wykonuje program. Jeśli na przykład metoda Main() wy-
                        wołuje metodę A(), a ta wywołuje metodę B(), na stosie będzie widać te
                        trzy metody — B(), A() i Main() — w odwrotnej kolejności.
                        Oto kod, który wyświetla te informacje:
                            Console.WriteLine("Wczytane podzespoły:")
                            For Each Assm As System.Reflection.Assembly In _
                              My.Application.Info.LoadedAssemblies
                                Console.WriteLine(Assm.GetName().Name)
                            Next
                            Console.WriteLine()

                            Console.WriteLine("Bieżący stos: " & My.Application.Info.StackTrace)
                            Console.WriteLine()



Ściśle typizowane
zasoby umożliwiają
                        Używanie ściśle typizowanych zasobów
osadzanie statycz-      Podzespoły .NET oprócz kodu mogą zawierać zasoby — osadzone dane
nych danych (na
przykład obrazów)       binarne, na przykład obrazy i niezmienne łańcuchy. Choć środowisko
w skompilowanych        .NET obsługuje zasoby już od wersji 1.0, Visual Studio nie oferowało ich
podzespołach
                        zintegrowanej obsługi w czasie projektowania aplikacji. W rezultacie
i zapewniają łatwy
dostęp do tych danych   programiści, którzy chcieli zapisać dane obrazu w swojej aplikacji, zwy-
z poziomu kodu.         kle dodawali je do kontrolek obsługujących obrazy podczas projektowa-
                        nia aplikacji, takich jak PictureBox lub ImageList. Kontrolki te automa-
                        tycznie wstawiały dane obrazu do pliku zasobów aplikacji.



54                      Rozdział 2: Język Visual Basic
W Visual Studio 2005 znacznie łatwiej jest dodawać informacje do plików
zasobu i później je aktualizować. Co najlepsze, można uzyskać dostęp do
tych informacji z dowolnego punktu kodu, i to ze ścisłą kontrolą typów.

Jak to zrobić?
Aby utworzyć ściśle typizowany zasób na użytek tego ćwiczenia, należy
zacząć od utworzenia nowej aplikacji Windows.
W celu dodania zasobu należy kliknąć dwukrotnie węzeł My Project
w oknie Solution Explorer. Pojawi się okno projektu aplikacji, w którym
można skonfigurować wiele różnorodnych ustawień programu. Następ-
nie należy przejść na zakładkę Resources i wybrać żądany typ zasobów
z listy rozwijanej umieszczonej w lewym górnym oknie (Strings, Images,
Audio itd.). Widok łańcuchów przedstawia siatkę danych. Widok obrazów
jest nieco inny — domyślnie pokazuje miniatury dołączonych obrazów.
Aby dodać nowy obraz, należy wybrać z listy kategorię Images, a na-
stępnie kliknąć strzałkę obok przycisku Add Resource i wybrać polecenie
Add Existing File. Należy znaleźć plik obrazu, zaznaczyć go i kliknąć
przycisk OK. Ci, którzy nie mają pod ręką innego obrazu, mogą wyko-
rzystać jeden spośród plików przechowywanych w katalogu Windows,
na przykład winnt256.bmp (który jest dołączany do większości wersji
Windows).
Domyślnie zasób ma tę samą nazwę co plik, ale można ją zmienić po dodaniu
zasobu. W tym przykładzie zmienimy nazwę obrazu na EmbeddedGraphic               Klasa zasobów
(jak pokazano na rysunku 2.2).                                                   jest dodawana do
                                                                                 węzła My Project
Korzystanie z zasobów jest bardzo łatwe. Wszystkie zasoby są kompilo-            i otrzymuje nazwę
                                                                                 Resources.Designer.vb.
wane dynamicznie w ściśle typizowaną klasę zasobów, do której można
                                                                                 Aby ją zobaczyć,
uzyskać dostęp poprzez obiekt My.Resources. Aby wypróbować nowo                  trzeba wybrać
dodany zasób, należy dodać kontrolkę PictureBox do formularza Win-               z menu Project
                                                                                 polecenie Show All
dows (i zachować domyślną nazwę PictureBox1). Następnie należy dodać             Files. Oczywiście, nie
poniższy kod, który wyświetli obraz podczas wczytywania formularza:              należy modyfikować
                                                                                 tego pliku ręcznie.
    Private Sub Form1_Load(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles MyBase.Load

        PictureBox1.Image = My.Resources.EmbeddedGraphic

    End Sub


                                          Używanie ściśle typizowanych zasobów                      55
Rysunek 2.2. Dodawanie obrazu jako ściśle typizowanego zasobu

                      Po uruchomieniu programu obraz zostanie wyświetlony na formularzu.
                      Aby upewnić się, że obraz jest pobierany z podzespołu, można skompi-
                      lować aplikację, a następnie usunąć plik obrazu (kod będzie nadal dzia-
                      łał bez żadnych problemów).

Inną zaletą zasobów   Kiedy dodajemy zasoby w taki sposób, Visual Studio kopiuje je do pod-
jest to, że można     katalogu Resources aplikacji. Katalog ten, wraz z zawartymi w nim za-
wykorzystać te
same obrazy w wielu
                      sobami, można obejrzeć w oknie Solution Explorer. Podczas kompilowania
kontrolkach na        aplikacji wszystkie zasoby są osadzane w podzespole, ale przechowy-
różnych formula-      wanie ich w oddzielnym katalogu ma pewną ważną zaletę — pozwala
rzach bez dodawania
wielu kopii obrazu    zaktualizować zasób przez zamianę pliku i ponowne skompilowanie apli-
do jednego pliku.     kacji. Nie trzeba modyfikować kodu. Jest to niezwykle przydatne, jeśli trzeba
                      jednocześnie zaktualizować wiele obrazów albo innych zasobów.
                      Zasoby można dołączać do różnych kontrolek za pomocą okna Properties.
                      Na przykład po kliknięciu wielokropka (...) obok właściwości Image
                      kontrolki PictureBox pojawi się okno z listą wszystkich obrazów dostęp-
                      nych w zasobach aplikacji.




56                    Rozdział 2: Język Visual Basic
A co…
…z kontrolką ImageList? Większość programistów Windows zna tę
kontrolkę, która grupuje wiele obrazów (zwykle niewielkich map bitowych)
na użytek innych kontrolek, takich jak menu, paski narzędzi, drzewa i li-
sty. Kontrolka ImageList nie używa typizowanych zasobów, lecz wła-
snej metody serializacji. Choć dostęp do zawartych w niej obrazów można
uzyskać zarówno podczas projektowania aplikacji, jak i metodą progra-
mistyczną, nie podlega ona kontroli typów.


Używanie ściśle typizowanych                                                      Tworzenie ustawień
                                                                                  konfiguracyjnych
ustawień konfiguracyjnych                                                         w oknie projektu
                                                                                  aplikacji.
Aplikacje często używają ustawień konfiguracyjnych, na przykład wska-
zujących położenie plików, parametry połączenia z bazą danych i prefe-
rencje użytkownika. Zamiast kodować te ustawienia „na sztywno” (albo
wymyślać własny mechanizm ich przechowywania), w .NET można dodać
je do pliku konfiguracyjnego specyficznego dla aplikacji. Dzięki temu
można je łatwo modyfikować poprzez edycję pliku tekstowego, bez po-
nownego kompilowania aplikacji.
W Visual Studio 2005 jest to jeszcze łatwiejsze, ponieważ ustawienia
konfiguracyjne są kompilowane w oddzielną klasę i podlegają ścisłej
kontroli typów. Oznacza to, że można pobierać ustawienia przy użyciu
właściwości, z wykorzystaniem funkcji IntelliSense, zamiast zdawać się
na wyszukiwanie tekstowe. Co najlepsze, .NET rozszerza ten model
o możliwość używania ustawień specyficznych dla użytkownika w celu
śledzenia preferencji i innych informacji. W niniejszym ćwiczeniu zo-
staną zaprezentowane obie te techniki.

Jak to zrobić?
Każde ustawienie konfiguracyjne jest definiowane przez unikatową na-
zwę. W poprzednich wersjach .NET można było pobrać wartość usta-
wienia konfiguracyjnego poprzez wyszukanie jego nazwy w kolekcji. Je-
śli jednak nazwa była nieprawidłowa, błąd można było wykryć dopiero
po uruchomieniu programu i wystąpieniu wyjątku czasu wykonania.

                         Używanie ściśle typizowanych ustawień konfiguracyjnych                    57
W aplikacji WWW         W Visual Studio 2005 sytuacja wygląda znacznie lepiej. Aby dodać nowe
ustawienia konfigura-   ustawienie konfiguracyjne, należy kliknąć dwukrotnie węzeł My Project
cyjne są umieszczane
w pliku web.config.     w oknie Solution Explorer. Pojawi się okno projektu aplikacji, w którym
W innych aplikacjach    można skonfigurować wiele różnorodnych ustawień programu. Następ-
ustawienia są
                        nie należy przejść na zakładkę Settings, która pokazuje listę niestandar-
umieszczane w pliku
noszącym tę samą        dowych ustawień konfiguracyjnych i umożliwia zdefiniowanie nowych
nazwę co aplikacja      ustawień oraz ich wartości.
i uzupełnioną
rozszerzeniem           Aby dodać do aplikacji nowe ustawienie konfiguracyjne, należy wpisać
.config, na przykład
MojaAplikacja.
                        jego nazwę na dole listy. Następnie należy określić typ danych, zasięg
   exe.config.          i rzeczywistą wartość ustawienia. Aby na przykład dodać ustawienie ze
                        ścieżką do pliku, można użyć nazwy UserDataFilePath, typu String,
                        zasięgu Application (niebawem powiemy więcej na ten temat) oraz warto-
                        ści c:MyFiles. Ustawienie to pokazano na rysunku 2.3.




                        Rysunek 2.3. Definiowanie ściśle typizowanego ustawienia konfiguracyjnego

                        Po dodaniu tego ustawienia Visual Studio .NET wstawi poniższe infor-
                        macje do pliku konfiguracyjnego aplikacji:
                            <configuration>
                              <applicationSettings>
                                <TypizowaneUstawienia.Settings>
                                  <setting name="UserDataFilePath" serializeAs="String">
                                    <value>c:MyFiles</value>
                                  </setting>


58                      Rozdział 2: Język Visual Basic
</TypizowaneUstawienia.Settings>
     </applicationSettings>
   </configuration>

Jednocześnie „za kulisami” Visual Studio skompiluje klasę, która za-
wiera informacje o niestandardowym ustawieniu konfiguracyjnym. Teraz
z dowolnego miejsca w kodzie będzie można uzyskać dostęp do ustawie-
nia według jego nazwy za pośrednictwem obiektu My.Settings. Oto kod,
który pobiera wartość ustawienia o nazwie UserDataFilePath:
   Dim path As String
   path = My.Settings.UserDataFilePath

W .NET 2.0 ustawienia konfiguracyjne nie muszą być łańcuchami.
                                                                                   Klasa ustawień
Można używać innych serializowalnych typów danych, w tym liczb cał-                konfiguracyjnych
kowitych i dziesiętnych, dat i czasów (wystarczy wybrać odpowiedni typ             jest dodawana do
z listy rozwijanej Type). Wartości te są przekształcane w tekst podczas            węzła My Project
                                                                                   i nosi nazwę
zapisu w pliku konfiguracyjnym, ale można je pobrać za pośrednictwem               Settings.Designer.
obiektu My.Settings w odpowiednim formacie, bez analizy składniowej!               Aby ją obejrzeć,
                                                                                   należy wybrać
                                                                                   z menu Project
A co…                                                                              polecenie Show All Files.

…z aktualizowaniem ustawień? W przykładzie UserFileDataPath wy-
korzystano ustawienie o zasięgu aplikacji, które można odczytywać w cza-
sie działania programu, ale nie można go modyfikować. Jeśli konieczna
jest aktualizacja ustawienia o zasięgu aplikacji, trzeba ręcznie zmodyfi-
kować plik konfiguracyjny (albo użyć listy ustawień w Visual Studio).
Alternatywą jest utworzenie ustawień o zasięgu użytkownika. W tym
celu wystarczy wybrać pozycję User z listy rozwijanej Scope na liście
ustawień. Jeśli ustawienie ma zasięg użytkownika, wartość ustawiona
w Visual Studio jest zapisywana jako wartość domyślna w pliku konfi-
guracyjnym, w katalogu aplikacji. Jednakże zmiana tych ustawień po-
woduje utworzenie nowego pliku user.config i zapisanie go w katalogu
specyficznym dla bieżącego użytkownika (o nazwie c:Documents and
Settings[NazwaUżytkownika]Ustawienia lokalneDane aplikacji[Nazwa
  Firmy][UnikatowyKatalog][WersjaAplikacji]).
W razie użycia ustawień specyficznych dla użytkownika trzeba pamię-
tać o wywołaniu metody My.Settings.Save() w celu zapisania zmian.
W przeciwnym razie zmiany będą obowiązywać tylko do momentu za-

                          Używanie ściśle typizowanych ustawień konfiguracyjnych                         59
mknięcia aplikacji. Zwykle metodę My.Settings.Save() wywołuje się pod
                         koniec działania aplikacji.
                         Aby wypróbować ustawienia o zasięgu użytkownika, należy zmienić za-
                         sięg ustawienia UserDataFilePath na User. Następnie należy utworzyć
                         formularz z polem tekstowym (o nazwie txtFilePath) i dwoma przyci-
                         skami: jednym do pobierania ustawienia (cmdRefresh), a drugim do ak-
                         tualizowania go (cmdUpdate). Oto odpowiednie procedury obsługi zdarzeń:
                             Private Sub cmdRefresh_Click(ByVal sender As System.Object, _
                               ByVal e As System.EventArgs) Handles cmdRefresh.Click
                                 txtFilePath.Text = My.Settings.UserDataFilePath
                             End Sub

                             Private Sub cmdUpdate_Click(ByVal sender As System.Object, _
                               ByVal e As System.EventArgs) Handles cmdUpdate.Click
                                 My.Settings.UserDataFilePath = txtFilePath.Text
                             End Sub

                         Aby zmiany obowiązywały podczas następnego uruchomienia aplikacji,
                         konieczne jest utworzenie lub zaktualizowanie pliku user.config podczas
                         zamykania formularza:
                             Private Sub Form1_FormClosed(ByVal sender As Object, _
                               ByVal e As System.Windows.Forms.FormClosedEventArgs) _
                               Handles Me.FormClosed
                                 My.Settings.Save()
                             End Sub

                         To już cały kod, który trzeba dodać do formularza. Teraz można uru-
                         chomić aplikację i sprawdzić, jak działa pobieranie bieżącego ustawienia
                         i zapisywanie nowego. Następnie można poszukać pliku user.config, który
                         zawiera zmienione ustawienia bieżącego użytkownika.


Jak utworzyć klasę
                         Tworzenie klas generycznych
na tyle elastyczną,
                         Programiści często stają przed trudnym wyborem. Z jednej strony, bar-
aby mogła działać
z dowolnym typem         dzo ważne jest tworzenie rozwiązań uniwersalnych, które można wielo-
obiektu, a jednocze-     krotnie wykorzystywać w różnych sytuacjach. Dlaczego na przykład
śnie w każdej sytuacji
móc ograniczać
                         mielibyśmy tworzyć klasę CustomerCollection, która przyjmuje tylko
przyjmowane              obiekty typu Customer, skoro możemy zaprojektować klasę Collection
przez nią obiekty?       zapewniającą dostęp do obiektów dowolnego typu? Z drugiej strony kwe-
Rozwiązaniem są
konstrukcje gene-
                         stie wydajności i typizacji sprawiają, że rozwiązania uniwersalne są
ryczne języka VB.        mniej pożądane. Jeśli na przykład użyjemy generycznej klasy .NET

60                       Rozdział 2: Język Visual Basic
Collection do przechowywania obiektów Customer, to skąd mamy wie-
dzieć, czy przypadkiem nie wstawimy do kolekcji obiektu innego typu, co
później spowoduje trudne do wykrycia problemy?
Visual Basic 2005 i .NET 2.0 zapewniają rozwiązanie nazywane kla-
sami generycznymi. Są to klasy parametryzowane według typu. Innymi
słowy, umożliwiają one zbudowanie szablonu obsługującego dowolny
typ. Podczas tworzenia instancji klasy określamy, jakiego typu chcemy
używać, i od tego momentu jesteśmy „przywiązani” do wybranego typu.

Jak to zrobić?
Przykładem, który pokazuje przydatność konstrukcji generycznych, jest
klasa System.Collections.ArrayList. ArrayList — uniwersalna, au-
tomatycznie skalowana kolekcja. Może ona przechowywać zwykłe obiekty
.NET albo obiekty zdefiniowane przez użytkownika. Aby było to możliwe,
klasa ArrayList traktuje wszystkie elementy jak bazowy typ Object.
Problem polega na tym, że nie sposób narzucić żadnych ograniczeń na
działanie klasy ArrayList. Jeśli, na przykład, chcemy użyć klasy ArrayList
do przechowywania kolekcji obiektów Customer, nie możemy upewnić
się, że jakiś fragment kodu nie wstawi do niej łańcuchów, liczb całko-
witych albo jakichś innych obiektów, co później spowoduje problemy. Z tej
przyczyny programiści często tworzą własne, ściśle typizowane klasy
kolekcji — w rzeczywistości biblioteka .NET jest wypełniona dziesiąt-
kami takich klas.
Konstrukcje generyczne rozwiązują ten problem. Za pomocą słowa klu-
czowego Of można zadeklarować klasę, która działa z dowolnym typem
danych:
   Public Class GenericList(Of ItemType)
       ' (tutaj kod klasy)
   End Class

W tym przypadku tworzymy nową klasę o nazwie GenericList, która
może działać z obiektami dowolnego typu. Kod kliencki musi jednak
określić, jakiego typu będzie używał. W kodzie klasy odwołujemy się do
tego typu za pomocą słowa ItemType. Oczywiście, ItemType nie jest na-



                                                 Tworzenie klas generycznych   61
prawdę typem — to tylko parametr zastępujący typ, który zostanie wy-
     brany podczas tworzenia instancji obiektu GenericList.
     Na listingu 2.2 pokazano kompletny kod prostej klasy listy, która kon-
     troluje zgodność typów.

     Listing 2.2. Kolekcja kontrolująca zgodność typów
         Public Class GenericList(Of ItemType)
             Inherits CollectionBase

              Public Function Add(ByVal value As ItemType) As Integer
                  Return List.Add(value)
              End Function

              Public Sub Remove(ByVal value As ItemType)
                  List.Remove(value)
              End Sub

             Public ReadOnly Property Item(ByVal index As Integer) As ItemType
                 Get
                     ' Odpowiedni element jest pobierany z obiektu List i jawnie
                     ' rzutowany na odpowiedni typ, a następnie zwracany
                     Return CType(List.Item(index), ItemType)
                 End Get
             End Property
         End Class

     Klasa GenericList jest nakładką na zwykłą klasę ArrayList, która jest do-
     stępna za pośrednictwem właściwości List bazowej klasy CollectionBase.
     Klasa GenericList działa jednak inaczej niż ArrayList, ponieważ ofe-
     ruje ściśle typizowane metody Add() i Remove(), w których wykorzysta-
     no zastępczy parametr ItemType.
     Oto przykład użycia klasy GenericList do utworzenia kolekcji ArrayList,
     która obsługuje tylko łańcuchy:
         ' Tworzymy instancję GenericList i wybieramy typ (w tym przypadku String)
         Dim List As New GenericList(Of String)

         ' Dodajemy dwa łańcuchy
         List.Add("niebieski")
         List.Add("zielony")

         ' Następna instrukcja nie zadziała, ponieważ dodaje do kolekcji błędny typ.
         ' Nie można automatycznie przekształcić identyfikatora GUID w łańcuch.
         ' Prawdę mówiąc, wiersz ten nie zostanie nigdy wykonany, ponieważ kompilator
         ' wykryje problem i odmówi zbudowania aplikacji.
         List.Add(Guid.NewGuid())



62   Rozdział 2: Język Visual Basic
Nie ma żadnych ograniczeń, jeśli chodzi o parametryzowanie klasy.
W przykładzie GenericList jest tylko jeden parametr. Można jednak ła-
two utworzyć klasę, która działa z dwoma lub trzema typami obiektów
i pozwala sparametryzować każdy z nich. Aby użyć tej techniki, należy
oddzielić każdy typ przecinkiem (między nawiasami na początku de-
klaracji klasy).
Rozważmy na przykład poniższą klasę GenericHashTable, która po-
zwala zdefiniować typ elementów kolekcji (ItemType), a także typ kluczy
używanych do indeksowania tych elementów (KeyType):
   Public Class GenericHashTable(Of ItemType, KeyType)
       Inherits DictionaryBase
       ' (tutaj kod klasy)
   End Class

Inną ważną cechą konstrukcji generycznych jest możliwość nakładania
ograniczeń na parametry. Ograniczenia zawężają zakres typów obsłu-
giwanych przez klasę generyczną. Przypuśćmy, że chcemy utworzyć
klasę obsługującą wyłącznie typy implementujące określony interfejs.
W tym celu najpierw musimy zadeklarować typ lub typy akceptowane
przez klasę, a następnie użyć słowa kluczowego As, aby określić klasę
bazową, z której typ musi się wywodzić, albo interfejs, który musi im-
plementować.
Oto przykład, który ogranicza elementy przechowywane w kolekcji Generic-
List do typów serializowalnych. Byłoby to użyteczne, gdybyśmy chcieli
dodać do klasy GenericList metodę wymagającą serializacji, na przy-
kład taką, która zapisywałaby wszystkie elementy listy w strumieniu:
   Public Class SerializableList(Of ItemType As ISerializable)
      Inherits CollectionBase
       ' (tutaj kod klasy)
   End Class

A oto kolekcja, która może zawierać obiekt dowolnego typu, pod warun-
kiem że wywodzi się on z klasy System.Windows.Forms.Control. Re-
zultatem jest kolekcja ograniczona do kontrolek, przypominająca tę eks-
ponowaną przez właściwość Forms.Controls okna:
   Public Class SerializableList(Of ItemType As Control)
      Inherits CollectionBase
       ' (tutaj kod klasy)
   End Class


                                                   Tworzenie klas generycznych   63
Czasem klasa generyczna musi mieć możliwość tworzenia sparametry-
                      zowanych obiektów. Na przykład w klasie GenericList konieczne może
                      być tworzenie instancji elementu, który ma być dodany do kolekcji. W ta-
                      kim przypadku trzeba użyć ograniczenia New. Ograniczenie New zezwala
                      tylko na typy, które mają publiczny, bezargumentowy konstruktor i nie są
                      oznaczone jako MustInherit. Gwarantuje to, że kod będzie mógł tworzyć
                      instancje typu. Oto kolekcja, która narzuca ograniczenie New:
                          Public Class GenericList(Of ItemType As New)
                              Inherits CollectionBase
                              ' (tutaj kod klasy)
                          End Class

                      Warto też zauważyć, że można definiować dowolnie wiele ograniczeń.
                      W tym celu należy umieścić ich listę w nawiasie klamrowym, jak w po-
                      niższym przykładzie:
                          Public Class GenericList(Of ItemType As {ISerializable, New})
                              Inherits CollectionBase
                              ' (tutaj kod klasy)
                          End Class

Konstrukcje gene-     Ograniczenia są wymuszone przez kompilator, więc naruszenie ograni-
ryczne są wbudowane
                      czenia podczas korzystania z klasy generycznej uniemożliwi skompilo-
w środowisko CLR.
Oznacza to, że są     wanie aplikacji.
one obsługiwane we
wszystkich językach
.NET, łącznie z C#.
                      A co…
                      …z innymi konstrukcjami generycznymi? Typów sparametryzowanych
                      można używać nie tylko w klasach, ale również w strukturach, interfej-
                      sach, delegacjach, a nawet metodach. Więcej informacji jest dostępnych
                      pod hasłem „generics” w pomocy MSDN. Przykłady użycia zaawansowa-
                      nych konstrukcji generycznych można znaleźć w artykule przeglądowym
                      Microsoftu pod adresem http://www.msdn.net/library/en-us/dnvs05/html/
                      vb2005_generics.asp.
                      Nawiasem mówiąc, twórcy .NET Framework zdawali sobie sprawę z przy-
                      datności kolekcji generycznych, więc utworzyli kilka gotowych kolekcji
                      na użytek programistów. Znajdują się one w przestrzeni nazw System.
                        Collections.Generic. Są to między innymi:

                       • List (prosta kolekcja podobna do przykładowej klasy GenericList);


64                    Rozdział 2: Język Visual Basic
• Dictionary (kolekcja typu „nazwa-wartość”, w której każdy element
   jest indeksowany przy użyciu klucza);
 • LinkedList (połączona lista, w której każdy element wskazuje następny);
 • Queue (kolekcja typu „pierwszy na wejściu, pierwszy na wyjściu”);
 • Stack (kolekcja typu „ostatni na wejściu, pierwszy na wyjściu”);
 • SortedList (kolekcja typu „nazwa-wartość”, która stale pozostaje
   posortowana).
Większość spośród tych kolekcji powiela jedną z klas w przestrzeni nazw
System.Collections. Stare kolekcje pozostawiono w celu zachowania
zgodności.


Używanie wartości pustych                                                         Czasem konieczne
                                                                                  jest reprezentowanie
w prostych typach danych                                                          danych, które mogą
                                                                                  być nieobecne.
                                                                                  Umożliwiają to nowe
Dzięki obsłudze konstrukcji generycznych .NET Framework może za-                  typy danych VB .NET.
oferować kilka nowych funkcji. Jedną z nich — generyczne, ściśle typi-
zowane kolekcje — opisano w poprzednim ćwiczeniu, „Tworzenie klas
generycznych”. Konstrukcje generyczne rozwiązują również inne często
spotykane problemy, w tym obsługę wartości pustych w prostych typach
danych.

Jak to zrobić?
Wartość pusta (w Visual Basicu identyfikowana przez słowo kluczowe
Nothing) jest specjalnym znacznikiem, który wskazuje, że dane są nie-
obecne. Większość programistów zna puste referencje do obiektów, które
wskazują, że obiekt zdefiniowano, ale jeszcze go nie utworzono. Na przy-
kład w poniższym kodzie obiekt FileStream zawiera pustą referencję, po-
nieważ nie został jeszcze utworzony za pomocą słowa kluczowego New:
   Dim fs As FileStream
   If fs Is Nothing
       ' Ten warunek jest zawsze spełniony, ponieważ
       ' nie utworzono jeszcze obiektu FileStream
       Console.WriteLine("Obiekt zawiera pustą referencję")
   End If



                             Używanie wartości pustych w prostych typach danych                    65
Podstawowe typy danych, takie jak liczby całkowite i łańcuchy, nie mogą
     zawierać wartości pustych. Zmienne liczbowe są automatycznie inicjali-
     zowane wartością 0, zmienne logiczne — wartością False, zmienne
     łańcuchowe — łańcuchem pustym (""). W rzeczywistości nawet jawne
     ustawienie zmiennej typu prostego na Nothing spowoduje automatycz-
     ne przekształcenie wartości pustej (w 0, False lub ""), jak pokazuje
     poniższy kod:
         Dim j As Integer = Nothing
         If j = 0 Then
             ' Ten warunek jest zawsze spełniony, ponieważ w przypadku liczb
                całkowitych
             ' zachodzi automatyczna konwersja między wartością Nothing a 0
             Console.WriteLine("Zmienna całkowita nie może zawierać wartości
         pustej, j = " & j)
         End If

     Czasem powoduje to problemy, ponieważ nie da się odróżnić wartości
     zerowej od wartości, której nigdy nie podano. Wyobraźmy sobie, że pi-
     szemy kod, który pobiera z pliku tekstowego liczbę zamówień złożonych
     przez klienta. Później badamy tę wartość. Problem występuje wtedy, gdy
     jest ona równa zeru. Nie możemy stwierdzić, czy dane są prawidłowe
     (użytkownik nie złożył żadnych zamówień), czy może brakuje nam ja-
     kichś informacji (nie udało się pobrać wartości albo bieżący użytkownik
     nie jest zarejestrowanym klientem).
     Dzięki obsłudze konstrukcji generycznych .NET 2.0 oferuje rozwiązanie
     — klasę System.Nullable, która może „owijać” dowolny typ danych.
     Podczas tworzenia instancji klasy Nullable określamy typ danych. Jeśli
     nie ustawimy wartości, instancja ta będzie zawierać pustą referencję.
     Możemy sprawdzić, czy tak jest w istocie, wywołując metodę Nullable.
       HasType(), i pobrać bazowy obiekt za pośrednictwem właściwości
     Nullable.Value.

     Oto przykładowy kod tworzący zmienną całkowitą, która może zawierać
     wartość pustą:
         Dim i As Nullable(Of Integer)
         If Not i.HasValue Then
             ' Warunek jest spełniony, ponieważ zmiennej nie przypisano wartości
             Console.WriteLine("Zmienna i zawiera wartość pustą")
         End If




66   Rozdział 2: Język Visual Basic
' Przypisujemy wartość. Zauważmy, że trzeba ją przypisać bezpośrednio
   ' zmiennej i,
   ' a nie i.Value. Właściwość i.Value jest przeznaczona tylko do odczytu i zawsze
   ' odzwierciedla bieżący obiekt, jeśli nie jest to Nothing.
   i = 100
   If i.HasValue Then
       ' Warunek jest spełniony, ponieważ obecnie zmienna zawiera wartość (100)
       Console.WriteLine("Zmienna całkowita i = " & i.Value)
   End If


A co…
…z używaniem klasy Nullable w połączeniu z typami referencyjnymi?
Choć nie jest to konieczne (ponieważ typy referencyjne mogą zawierać
pustą referencję), to ma pewne zalety. Możemy używać nieco czytelniej-
szej metody HasValue() zamiast testować wartość Nothing. Co najlep-
sze, możemy łatwo dokonać tej zmiany, ponieważ klasa Nullable po-
zwala na niejawną konwersję między Nullable a typem bazowym.

Więcej informacji
Aby dowiedzieć się więcej na temat klasy Nullable i jej implementacji,
należy zajrzeć pod hasło „Nullable class” w pomocy MSDN.


Używanie operatorów                                                                  Kto ma dość posłu-
                                                                                     giwania się toporną

w połączeniu z własnymi obiektami                                                    składnią w rodzaju
                                                                                     ObjA.Subtract(ObjB)
                                                                                     w celu wykonania
Każdy programista VB dobrze zna operatory arytmetyczne służące do                    prostych operacji na
dodawania (+), odejmowania (-), dzielenia (/) i mnożenia (*). Zwykle                 własnych obiektach?
                                                                                     Dzięki przeciążaniu
operatory te są zarezerwowane dla liczbowych typów .NET i nie można                  operatorów można
używać ich w połączeniu z innymi obiektami. Jednakże w VB .NET 2.0                   manipulować takimi
można budować obiekty, które obsługują wszystkie te operatory (a także               obiektami równie
                                                                                     łatwo jak zwykłymi
operatory używane do operacji logicznych i niejawnej konwersji typu).                liczbami.
Technika ta nie ma sensu w przypadku obiektów biznesowych, ale jest
niezwykle przydatna do modelowania struktur matematycznych, takich
jak wektory, macierze, liczby zespolone albo — jak w poniższym przy-
kładzie — ułamki.




                           Używanie operatorów w połączeniu z własnymi obiektami                      67
Jak to zrobić?
     Aby przeciążyć operator w Visual Basicu 2005, trzeba utworzyć specjal-
     ną metodę operatorową w klasie (lub strukturze). Metodę tę deklaruje się
     przy użyciu słów kluczowych Public Shared Operator, po których na-
     stępuje symbol operatora (na przykład +).

                                       WS KAZÓWK A
              Przeciążanie operatora to po prostu definiowanie, co robi operator,
              kiedy używamy go w połączeniu z konkretnym typem obiektu. In-
              nymi słowy, kiedy przeciążamy operator + klasy Fraction, infor-
              mujemy .NET, co należy zrobić, gdy kod dodaje do siebie dwa
              obiekty Fraction.


     Oto przykładowa metoda operatorowa, która dodaje obsługę operatora
     dodawania (+):
         Public Shared Operator(ObjA As MyClass, objB As MyClass) As MyClass
             ' (tutaj kody klasy)
         End Operator

     Każda metoda operatorowa przyjmuje dwa parametry, które reprezen-
     tują wartości po obu stronach operatora. W zależności od operatora i klasy
     kolejność może mieć znaczenie (jak w przypadku dzielenia).
     Kiedy zdefiniujemy operator, kompilator VB będzie wywoływał nasz kod
     podczas wykonywania każdej instrukcji, która używa operatora na obiek-
     cie danej klasy. Na przykład kompilator przekształci kod:
         ObjC = ObjA + ObjB

     do następującej postaci:
         ObjC = MyClass.Operator+(ObjA, ObjB)

     Na listingu 2.3 pokazano, jak przeciążyć operatory arytmetyczne Visual
     Basica na użytek klasy Fraction. Każdy obiekt Fraction składa się
     z dwóch części: licznika i mianownika (tzw. „góry” i „dołu” ułamka). Kod
     klasy Fraction przeciąża operatory +, -, * oraz /, umożliwiając wyko-
     nywanie obliczeń ułamkowych bez przekształcania liczb w wartości
     dziesiętne, a zatem bez utraty precyzji.



68   Rozdział 2: Język Visual Basic
Listing 2.3. Przeciążanie operatorów arytmetycznych w klasie Fraction
    Public Structure Fraction

         ' Dwie części ułamka
         Public Denominator As Integer
         Public Numerator As Integer

         Public Sub New(ByVal numerator As Integer, ByVal denominator As Integer)
             Me.Numerator = numerator
             Me.Denominator = denominator
         End Sub

         Public Shared Operator +(ByVal x As Fraction, ByVal y As Fraction) _
           As Fraction
             Return Normalize(x.Numerator * y.Denominator + _
               y.Numerator * x.Denominator, x.Denominator * y.Denominator)
         End Operator

         Public Shared Operator -(ByVal x As Fraction, ByVal y As Fraction) _
           As Fraction
             Return Normalize(x.Numerator * y.Denominator - _
               y.Numerator * x.Denominator, x.Denominator * y.Denominator)
         End Operator

         Public Shared Operator *(ByVal x As Fraction, ByVal y As Fraction) _
           As Fraction
             Return Normalize(x.Numerator * y.Numerator, _
               x.Denominator * y.Denominator)
         End Operator

         Public Shared Operator /(ByVal x As Fraction, ByVal y As Fraction) _
           As Fraction
             Return Normalize(x.Numerator * y.Denominator, _
               x.Denominator * y.Numerator)
         End Operator

         ' Redukcja ułamka
         Private Shared Function Normalize(ByVal numerator As Integer, _
           ByVal denominator As Integer) As Fraction
             If (numerator <> 0) And (denominator <> 0) Then
                 ' Poprawianie znaków
                 If denominator < 0 Then
                     denominator *= -1
                     numerator *= -1
                 End If

                 Dim divisor As Integer = GCD(numerator, denominator)
                 numerator = divisor
                 denominator = divisor
             End If

             Return New Fraction(numerator, denominator)
         End Function



                               Używanie operatorów w połączeniu z własnymi obiektami   69
' Zwracanie największego wspólnego dzielnika przy użyciu algorytmu
              ' Euklidesa
              Private Shared Function GCD(ByVal x As Integer, ByVal y As Integer) _
                As Integer
                  Dim temp As Integer

                   x = Math.Abs(x)
                   y = Math.Abs(y)
                   Do While (y <> 0)
                        temp = x Mod y
                        x = y
                        y = temp
                   Loop

                  Return x
              End Function

              ' Przekształcanie ułamka w postać dziesiętną
              Public Function GetDouble() As Double
                  Return CType(Me.Numerator, Double) / _
                    CType(Me.Denominator, Double)
              End Function

              ' Pobieranie łańcucha reprezentującego ułamek
              Public Overrides Function ToString() As String
                  Return Me.Numerator.ToString & "/" & Me.Denominator.ToString
              End Function

          End Structure

     Aplikacja konsoli pokazana na listingu 2.4 przeprowadza szybki test
     klasy Fraction. Dzięki przeciążaniu operatorów liczba pozostaje w postaci
     ułamkowej i nie dochodzi do utraty precyzji.

     Listing 2.4. Test klasy Fraction
          Module FractionTest

              Sub Main()
                  Dim f1 As New Fraction(2, 3)
                  Dim f2 As New Fraction(1, 4)

                   Console.WriteLine("f1 = " & f1.ToString())
                   Console.WriteLine("f2 = " & f2.ToString())

                   Dim f3 As Fraction
                   f3 = f1 + f2     ' f3 obecnie wynosi 11/12
                   Console.WriteLine("f1 + f2 = " & f3.ToString())

                   f3 = f1 / f2     ' f3 obecnie wynosi 8/3
                   Console.WriteLine("f1 / f2 = " & f3.ToString())



70   Rozdział 2: Język Visual Basic
f3 = f1 - f2     ' f3 obecnie wynosi 5/12
               Console.WriteLine("f1 - f2 = " & f3.ToString())

            f3 = f1 * f2     ' f3 obecnie wynosi 1/6
            Console.WriteLine("f1 * f2 = " & f3.ToString())
            Console.ReadLine()
        End Sub

   End Module

Po uruchomieniu tej aplikacji pojawią się następujące wyniki:
   f1   =   2/3
   f2   =   1/4
   f1   +   f2 =   11/12
   f1   /   f2 =   8/3
   f1   -   f2 =   5/12
   f1   *   f2 =   1/6

Parametry i wartość zwrotna metody operatorowej zwykle są tego sa-
mego typu. Można jednak utworzyć kilka wersji metody operatorowej,
aby używać obiektów w wyrażeniach z różnymi typami.

A co…
…z przeciążaniem operatorów w innych typach danych? Istnieją klasy,
które są naturalnymi kandydatami do przeciążania operatorów. Oto kilka
przykładów:
 • klasy matematyczne, które modelują wektory, macierze, liczby ze-
   spolone lub tensory;
 • klasy finansowe, które zaokrąglają obliczenia do najbliższego grosza
   i obsługują różne typy walut;
 • klasy miar, które używają jednostek nieregularnych, na przykład
   cali i stóp.

Więcej informacji
Aby dowiedzieć się więcej o składni przeciążania operatorów oraz o wszyst-
kich operatorach, które można przeciążać, należy zajrzeć pod hasło in-
deksu „Operator procedures” w pomocy MSDN.




                             Używanie operatorów w połączeniu z własnymi obiektami   71
Niektóre klasy są tak
duże, że przecho-
                           Dzielenie klasy na wiele plików
wywanie ich definicji
                           Jeśli otworzymy klasę .NET 2.0 Windows Forms, zauważymy, że nie ma
w jednym pliku jest
niewygodne. Za             w niej automatycznie wygenerowanego kodu! Aby zrozumieć, gdzie po-
pomocą nowego              dział się ten kod, trzeba zapoznać się z funkcją klas częściowych, która
słowa kluczowego
Partial można
                           umożliwia dzielenie klasy na kilka części.
podzielić klasę na kilka
oddzielnych plików.        Jak to zrobić?
                           Za pomocą słowa kluczowego Partial można podzielić klasę na dowol-
                           ną liczbę części. Wystarczy zdefiniować tę samą klasę w więcej niż jed-
                           nym miejscu. Oto przykład, w którym klasę SampleClass zdefiniowano
                           w dwóch częściach:
                               Partial Public Class SampleClass
                                   Public Sub MethodA()
                                       Console.WriteLine("Wywołano metodę A")
                                   End Sub
                               End Class

                               Partial Public Class SampleClass
                                   Public Sub MethodB()
                                       Console.WriteLine("Wywołano metodę B")
                                   End Sub
                               End Class

                           W tym przykładzie deklaracje znajdują się w tym samym pliku, jedna
                           za drugą. Nic jednak nie stoi na przeszkodzie, aby umieścić dwie części
                           klasy SampleClass w różnych plikach kodu źródłowego należących do
                           tego samego projektu (jedyne ograniczenie polega na tym, że nie można
                           zdefiniować dwóch części klasy w oddzielnych podzespołach albo róż-
                           nych przestrzeniach nazw).
                           Podczas kompilowania aplikacji zawierającej powyższy kod Visual Studio
                           wyszuka każdą część SampleClass i połączy ją w kompletną klasę z dwoma
                           metodami, MethodA() i MethodB(). Można używać obu tych metod:
                               Dim Obj As New SampleClass()
                               Obj.MethodA()
                               Obj.MethodB()

                           Klasy częściowe nie pomagają w rozwiązywaniu problemów programi-
                           stycznych, ale przydają się do dzielenia bardzo dużych, nieporęcznych
                           klas. Oczywiście, sama obecność dużych klas w aplikacji może świadczyć


72                         Rozdział 2: Język Visual Basic
o tym, że programista źle rozłożył problem na czynniki, a w takim przy-
padku lepiej jest podzielić kod na odrębne, a nie częściowe klasy. Jednym
z kluczowych zastosowań klas częściowych w .NET jest ukrywanie kodu
generowanego automatycznie przez Visual Studio, który w starszych
wersjach był widoczny, co przeszkadzało niektórym programistom VB.
Na przykład podczas budowania formularza .NET w Visual Basicu 2005
kod obsługi zdarzeń jest umieszczany w pliku kodu źródłowego formu-
larza, ale kod, który tworzy poszczególne kontrolki i łączy je z procedu-
rami obsługi zdarzeń, jest niewidoczny. Aby go zobaczyć, trzeba wybrać
z menu Project polecenie Show All Files. Plik z brakującą częścią klasy
pojawi się wówczas w oknie Solution Explorer. Jeśli formularz nosi na-
zwę Form1, to składa się na niego plik Form1.vb, który zawiera kod pisany
przez programistę, oraz plik Form1.Designer.vb, który zawiera auto-
matycznie wygenerowaną część.

A co…
…z używaniem słowa kluczowego Partial w połączeniu ze struktu-
rami? To działa, ale nie można tworzyć częściowych interfejsów, wyli-
czeń ani żadnych innych konstrukcji programistycznych .NET.

Więcej informacji
Więcej informacji o klasach częściowych można znaleźć pod hasłem in-
deksu „Partial keyword” w pomocy MSDN.


Rozszerzanie przestrzeni nazw My                                               Niektórzy tak często
                                                                               używają obiektów
Obiekty My nie są zdefiniowane w jednym miejscu. Niektóre z nich po-           My, że chcieliby
                                                                               dostosować je do
chodzą od klas zdefiniowanych w przestrzeni nazw Microsoft.Visual-             własnych potrzeb.
Basic.MyServices, a inne są generowane automatycznie w miarę do-               VB 2005 umożliwia
                                                                               dołączenie własnych
dawania formularzy, usług WWW, ustawień konfiguracyjnych i osa-                klas do przestrzeni
dzonych zasobów do projektu aplikacji. Programista może jednak roz-            nazw My.
szerzyć przestrzeń nazw My o własne składniki (na przykład przydatne
obliczenia oraz zadania specyficzne dla aplikacji).



                                            Rozszerzanie przestrzeni nazw My                     73
Jak to zrobić?
                       Aby dołączyć nową klasę do hierarchii obiektów My, wystarczy użyć bloku
                       Namespace z nazwą My. Na przykład poniższy kod definiuje nową klasę
                       BusinessFunctions, która zawiera specyficzne dla firmy funkcje prze-
                       znaczone do generowania identyfikatorów (poprzez połączenie nazwy
                       klienta z identyfikatorem GUID):
                           Namespace My

                                Public Class BusinessFunctions
                                    Public Shared Function GenerateNewCustomerID( _
                                      ByVal name As String) As String
                                        Return name & "_" & Guid.NewGuid.ToString()
                                    End Function
                                End Class

                           End Namespace

                       Po utworzeniu obiektu BusinessFunctions można używać go w aplikacji
                       tak samo jak dowolnego innego obiektu My. Na przykład poniższa in-
                       strukcja wyświetla nowy identyfikator klienta:
                           Console.WriteLine(My.BusinessFunctions.GenerateNewCustomerID("matthew"))

                       Zwróćmy uwagę, że nowe klasy My muszą używać współdzielonych metod
                       i właściwości, ponieważ obiekty My nie są konkretyzowane automatycz-
                       nie. Gdybyśmy użyli zwykłych składowych instancyjnych, musielibyśmy
                       sami tworzyć obiekt My i nie moglibyśmy manipulować nim przy użyciu
                       tej samej składni. Innym rozwiązaniem jest utworzenie modułu w prze-
                       strzeni nazw My, ponieważ wszystkie metody i właściwości w module są
                       współdzielone.
Składowe współdzie-
                       Można również rozszerzać niektóre spośród istniejących obiektów
lone to składowe,
które są zawsze        My dzięki klasom częściowym. W ten sposób można na przykład do-
dostępne za po-        dać nowe informacje do obiektu My.Computer albo nowe procedury do
średnictwem nazwy
klasy, nawet jeśli
                       obiektu My.Application. Wymaga to nieco innego podejścia. Właści-
obiekt nie został      wość My.Computer eksponuje instancję obiektu MyComputer. Właściwość
utworzony. W razie     My.Application eksponuje instancję obiektu MyApplication. Aby więc
użycia zmiennej
współdzielonej         rozszerzyć którąś z tych klas, trzeba utworzyć klasę częściową o odpo-
istnieje tylko jedna   wiedniej nazwie i dodać do niej odpowiednie składowe. Należy również
kopia tej zmiennej,
                       zadeklarować tę klasę przy użyciu słowa kluczowego Friend, aby dopa-
globalna dla całej
aplikacji.             sować ją do istniejącej klasy.

74                     Rozdział 2: Język Visual Basic
Oto przykład rozszerzania obiektu My.Application o metodę, która
sprawdza, czy dostępna jest zaktualizowana wersja programu:
   Namespace My

       Partial Friend Class MyApplication
           Public Function IsNewVersionAvailable() As Boolean
               ' Zwykle numer najnowszej wersji aplikacji byłby odczytywany
               ' z usługi WWW albo jakiegoś innego zasobu.
               ' W tym przykładzie jest zakodowany "na sztywno"
               Dim LatestVersion As New Version(1, 2, 1, 1)
               Return Application.Info.Version.CompareTo(LatestVersion)

           End Function
       End Class

Teraz możemy wykorzystać tę metodę:
   If My.Application.IsNewVersionAvailable()
       Console.WriteLine("Dostępna jest nowsza wersja")
   Else
       Console.WriteLine("To jest najnowsza wersja")
   End If


A co…
…z używaniem rozszerzeń My w wielu aplikacjach? Klasy My możemy
traktować dokładnie tak samo, jak inne przydatne klasy, które chcemy
ponownie wykorzystać w innej aplikacji. Innymi słowy, możemy utwo-
rzyć projekt biblioteki klas, dodać do niego kilka rozszerzeń My i skom-
pilować go do postaci biblioteki DLL. Następnie możemy odwoływać się
do tej biblioteki DLL w innych aplikacjach.
Oczywiście, pomimo tego, co mogliby twierdzić entuzjaści Microsoftu,
taki sposób rozszerzania przestrzeni nazw My ma dwa potencjalnie nie-
bezpieczne aspekty:
 • Trudniejsze staje się wykorzystanie komponentu w innych językach.
   Na przykład język C# nie obsługuje przestrzeni nazw My. Choć
   można używać niestandardowego obiektu My w aplikacji C#, jest to
   dużo mniej wygodne.
 • Używanie przestrzeni nazw My oznacza rezygnację z jednej spośród
   największych zalet przestrzeni nazw — unikania konfliktów na-
   zewniczych. Rozważmy na przykład dwie firmy, które tworzą kom-
   ponenty przeznaczone do rejestrowania zdarzeń. Gdyby firmy uży-

                                               Rozszerzanie przestrzeni nazw My   75
wały zalecanego standardu nazewniczego przestrzeni nazw .NET
                                (NazwaFirmy.NazwaAplikacji.NazwaKlasy), komponenty najprawdo-
                                podobniej nie miałyby takich samych w pełni kwalifikowanych nazw;
                                jeden mógłby nazywać się Acme.SuperLogger.Logger, a drugi —
                                ComponentTech.LogMagic.Logger. Gdyby jednak oba komponenty roz-
                                szerzały obiekt My, mogłyby używać takiej samej nazwy (na przy-
                                kład My.Application.Logger). W rezultacie nie można byłoby wy-
                                korzystać ich obu w tej samej aplikacji.


Nowe słowo kluczowe         Przechodzenie do następnej iteracji pętli
Continue Visual Basica
umożliwia szybkie           Visual Basic oferuje kilka instrukcji kontroli przepływu, które pozwalają
wyjście ze skom-
plikowanego bloku
                            sterować kolejnością wykonywania kodu. Można na przykład użyć słowa
kodu i przejście do         kluczowego Return, aby wyjść z funkcji, albo słowa Exit, aby zakończyć
następnej iteracji pętli.   pętlę. Jednakże przed wersją VB 2005 nie było sposobu przejścia do na-
                            stępnej iteracji pętli.

                            Jak to zrobić?
                            Instrukcja Continue to jeden z tych mechanizmów językowych, które po-
                            czątkowo wydają się mało istotne, ale z czasem okazują się bardzo przy-
                            datne. Instrukcja Continue ma trzy wersje: Continue For, Continue Do
                            i Continue While, których używa się z różnymi typami pętli (For ... Next,
                            Do ... Loop oraz While ... End While).

                            Aby zrozumieć, jak działa instrukcja Continue, przeanalizujmy poniższy kod:
                                For i = 1 To 1000
                                    If i Mod 5 = 0 Then
                                         ' (kod zadania A)
                                         Continue For
                                    End If
                                    ' (kod zadania B)
                                Next

                            Pętla ta wykonuje się 1000 razy, stopniowo zwiększając wartość liczni-
                            ka i. Kiedy licznik i jest podzielny przez 5, wykonywany jest kod zada-
                            nia A. Następnie instrukcja Continue For powoduje zwiększenie licznika
                            i wznowienie wykonywania od początku pętli, z pominięciem kodu za-
                            dania B.


76                          Rozdział 2: Język Visual Basic
W tym przykładzie instrukcja Continue nie jest właściwie potrzebna,
ponieważ można łatwo przepisać kod w następujący sposób:
    For i = 1 To 1000
        If i Mod 5 = 0 Then
             ' (kod zadania A)
        Else
             ' (kod zadania B)
        End If
    Next

Jest to jednak znacznie trudniejsze, gdy trzeba wykonać kilka różnych
testów. Aby przekonać się o zaletach instrukcji Continue, należy rozwa-
żyć bardziej skomplikowany (i realistyczny) przykład.
Na listingu 2.5 pokazano pętlę, która przetwarza tablicę słów. Program
analizuje każde słowo i ustala, czy jest ono puste, czy też składa się
z liter lub cyfr. Jeśli spełniony jest jeden z tych warunków (na przykład
słowo składa się z liter), trzeba przejść do następnego słowa bez wyko-
nywania następnego testu. Aby osiągnąć to bez użycia instrukcji Continue,
trzeba zastosować zagnieżdżone pętle, co zmniejsza czytelność kodu.

Listing 2.5. Analizowanie łańcucha bez użycia instrukcji Continue
    ' Definiujemy zdanie
    Dim Sentence As String = "Końcowy wynik obliczeń to 433."

    ' Przekształcamy zdanie w tablicę słów
    Dim Delimiters() As Char = {" ", ".", ","}
    Dim Words() As String = Sentence.Split(Delimiters)

    ' Badamy każde słowo
    For Each Word As String In Words
        ' Sprawdzamy, czy słowo jest puste
        If Word <> "" Then
            Console.Write("'" + Word + "'" & vbTab & "= ")

              ' Sprawdzamy, czy słowo składa się z liter
              Dim AllLetters As Boolean = True
              For Each Character As Char In Word
                   If Not Char.IsLetter(Character) Then
                       AllLetters = False
                   End If
              Next
              If AllLetters Then
                   Console.WriteLine("słowo")
              Else
                   ' Jeśli słowo nie składa się z liter,
                   ' sprawdzamy, czy składa się z cyfr



                                                Przechodzenie do następnej iteracji pętli   77
Dim AllNumbers As Boolean = True
                     For Each Character As Char In Word
                         If Not Char.IsDigit(Character) Then
                              AllNumbers = False
                         End If
                     Next
                     If AllNumbers Then
                         Console.WriteLine("liczba")
                     Else
                          ' Jeśli słowo nie składa się z samych liter albo cyfr,
                          ' zakładamy, że zawiera ich kombinację (albo inne znaki)
                         Console.WriteLine("mieszane")
                     End If
                 End If
             End If
         Next

     Teraz rozważmy wersję z listingu 2.6, w której użyto instrukcji Continue,
     aby działanie programu było bardziej zrozumiałe.

     Listing 2.6. Analizowanie łańcucha przy użyciu instrukcji Continue
           ' Definiujemy zdanie
           Dim Sentence As String = "Końcowy wynik obliczeń to 433."

           ' Przekształcamy zdanie w tablicę słów
           Dim Delimiters() As Char = {" ", ".", ","}
           Dim Words() As String = Sentence.Split(Delimiters)

           ' Badamy każde słowo
           For Each Word As String In Words
               ' Sprawdzamy, czy słowo jest puste
               If Word = "" Then Continue For
               Console.Write("'" + Word + "'" & vbTab & "= ")

               ' Sprawdzamy, czy słowo składa się z liter
               Dim AllLetters As Boolean = True
               For Each Character As Char In Word
                    If Not Char.IsLetter(Character) Then
                        AllLetters = False
                    End If
               Next
               If AllLetters Then
                    Console.WriteLine("słowo")
                    Continue For
               End If

               ' Jeśli słowo nie składa się z liter,
               ' sprawdzamy, czy składa się z cyfr
               Dim AllNumbers As Boolean = True
               For Each Character As Char In Word
                   If Not Char.IsDigit(Character) Then
                       AllNumbers = False
                   End If


78   Rozdział 2: Język Visual Basic
Next
           If AllNumbers Then
                Console.WriteLine("liczba")
                Continue For
           End If

           ' Jeśli słowo nie składa się z samych liter albo cyfr,
           ' zakładamy, że zawiera ich kombinację (albo inne znaki)
           Console.WriteLine("mieszane")
    Next


A co…
…z użyciem instrukcji Continue w zagnieżdżonej pętli? Jest to możliwe.
Jeśli zagnieździmy pętlę For w pętli Do, będziemy mogli użyć instrukcji
Continue For, aby przejść do następnej iteracji wewnętrznej pętli, albo
instrukcji Continue Do, aby przejść do następnej iteracji zewnętrznej
pętli. Technika ta działa także w odwrotnej sytuacji (pętla Do wewnątrz
pętli For), ale nie w przypadku dwóch zagnieżdżonych pętli tego samego
typu. W takiej sytuacji nie da się jednoznacznie odwołać do zewnętrznej
pętli, więc instrukcja Continue zawsze dotyczy pętli wewnętrznej.

Więcej informacji
Szczegółowe informacje o instrukcji Continue można znaleźć pod ha-
słem indeksu „continue statement” w pomocy MSDN.


Automatyczne usuwanie obiektów                                                     Jak uniknąć
                                                                                   pozostawiania
W środowisku .NET trzeba zwracać szczególną uwagę na to, aby obiekty               w pamięci obiektów,
                                                                                   które zajmują zasoby
używające niezarządzanych zasobów (na przykład uchwytów plików,                    aż do momentu,
połączeń z bazami danych i kontekstów graficznych) zwalniały je na-                w którym wyszuka
tychmiast, kiedy będzie to możliwe. Obiekty tego typu powinny imple-               je „odśmiecacz”?
                                                                                   Dzięki instrukcji
mentować interfejs IDisposable i udostępniać metodę Dispose(), którą               Using można upewnić
można wywołać w celu natychmiastowego zwolnienia zasobów.                          się, że obiekty
                                                                                   zostaną usunięte
Jedyny problem z tą techniką polega na tym, że trzeba pamiętać o wy-               we właściwym
wołaniu metody Dispose() (albo innej metody wywołującej Dispose(),                 momencie.

na przykład Close()). VB 2005 oferuje nowe zabezpieczenie, które gwa-
rantuje wywołanie metody Dispose() — instrukcję Using.


                                                  Automatyczne usuwanie obiektów                    79
Jak to zrobić?
     Instrukcji Using używa się w strukturze bloku. W pierwszym wierszu
     bloku Using należy określić usuwalny obiekt. Często w tym samym
     momencie tworzy się obiekt za pomocą słowa kluczowego New. Następ-
     nie w bloku Using należy napisać kod, który używa usuwalnego obiektu.
     Oto krótki fragment kodu, który tworzy nowy plik i zapisuje w nim dane:
         Using NewFile As New System.IO.StreamWriter("c:MojPlik.txt")
             NewFile.WriteLine("To jest wiersz 1")
             NewFile.WriteLine("To jest wiersz 2")
         End Using

         ' Plik jest zamykany automatycznie
         ' Obiekt NewFile w tym miejscu jest już niedostępny

     W tym przykładzie natychmiast po opuszczeniu bloku Using wywoły-
     wana jest metoda Dispose() obiektu NewFile, co powoduje zwolnienie
     uchwytu pliku.

     A co…
     …z błędami występującymi w bloku Using? Na szczęście .NET zwalnia
     zasób bez względu na sposób wyjścia z bloku Using, nawet w przypadku
     nieobsłużonego wyjątku.
     Instrukcji Using można używać w połączeniu ze wszystkimi usuwalnymi
     obiektami, na przykład:
      • plikami (w tym FileStream, StreamReader i StreamWriter);
      • połączeniami z bazą danych (w tym SqlConnection, OracleConnection
        i OleDbConnection);
      • połączeniami sieciowymi (w tym TcpClient, UdpClient, NetworkStream,
        FtpWebResponse, HttpWebResponse);

      • grafiką (w tym Image, Bitmap, Metafile, Graphics).

     Więcej informacji
     Szczegółowe informacje o instrukcji Using można znaleźć pod hasłem
     indeksu „Using block” w pomocy MSDN.



80   Rozdział 2: Język Visual Basic
W przeszłości nie
Ochrona właściwości                                                               dało się utworzyć
                                                                                  właściwości,
przy użyciu różnych poziomów dostępu                                              która mogła być
                                                                                  odczytywana
Większość właściwości zawiera procedurę Get (która umożliwia pobie-               przez każdego,
ranie wartości właściwości) oraz procedurę Set (która umożliwia okre-             ale aktualizowana
                                                                                  tylko przez aplikację.
ślenie nowej wartości właściwości). W poprzednich wersjach Visual Ba-             VB 2005 wreszcie
sica poziom dostępu do obu procedur musiał być jednakowy. W VB 2005               poluzowuje reguły
można zabezpieczyć właściwość, przypisując procedurze Set niższy po-              i oferuje większą
                                                                                  elastyczność.
ziom dostępu niż procedurze Get.

Jak to zrobić?
VB rozróżnia trzy poziomy dostępu. W kolejności od najmniej do najbar-
dziej ograniczonego są to:
 • Public (element dostępny dla wszystkich klas we wszystkich podze-
   społach);
 • Friend (element dostępny dla wszystkich klas w bieżącym podzespole);
 • Private (element dostępny tylko dla kodu w tej samej klasie).
Wyobraźmy sobie, że tworzymy komponent DLL, który będzie używany
przez inną aplikację. Zawiera on właściwość Status, która będzie od-
czytywana przez aplikację kliencką, więc deklarujemy ją jako publiczną:
   Public Class ComponentClass

       Private _Status As Integer
       Public Property Status() As Integer
           Get
                Return _Status
           End Get
           Set(ByVal value As Integer)
                _Status = value
           End Set
       End Property

   End Class

Problem w tym, że poziom dostępu przypisany właściwości Status po-
zwala klientowi na jej zmianę, co nie ma sensu. Właściwość Status
mogłaby być przeznaczona tylko do odczytu (w tym celu należałoby po-
minąć procedurę Set), ale wtedy nie mogłyby jej zmieniać inne klasy,
które stanowią część aplikacji i znajdują się w tym samym podzespole.

                       Ochrona właściwości przy użyciu różnych poziomów dostępu                       81
Rozwiązaniem jest przypisanie procedurze Set poziomu dostępu Friend.
                         Oto, jak powinien wyglądać kod (jedyną zmianę wyróżniono pogrubioną
                         czcionką):
                             Public Property Status() As Integer
                                 Get
                                      Return _Status
                                 End Get
                                 Friend Set(ByVal value As Integer)
                                      _Status = value
                                 End Set
                             End Property


                         A co…
                         …z właściwościami przeznaczonymi tylko do odczytu lub tylko do zapisu?
                         Różne poziomy dostępu nie pomogą, jeśli potrzebna jest właściwość
                         przeznaczona tylko do odczytu (na przykład wartość obliczana) albo tyl-
                         ko do zapisu (na przykład hasło, które po ustawieniu nie powinno pozo-
                         stawać dostępne). W celu utworzenia właściwości przeznaczonej tylko
                         do odczytu należy dodać słowo kluczowe ReadOnly do deklaracji właści-
                         wości (tuż po słowie kluczowym określającym poziom dostępu) i usunąć
                         procedurę Set. W celu utworzenia właściwości przeznaczonej tylko do
                         zapisu należy usunąć procedurę Get i dodać słowo kluczowe WriteOnly.
                         Te słowa kluczowe nie są niczym nowym — były dostępne już w Visual
                         Basicu .NET 1.0.


Nowe operatory
logiczne umożliwiają
                         Testowanie kolejnych części
łączenie wielu warun-
ków i pisanie bardziej
                         wyrażenia warunkowego
zwartego kodu.           W poprzednich wersjach Visual Basica istniały dwa operatory logiczne:
                         And i Or. W Visual Basicu 2005 wprowadzono dwa dodatkowe operatory:
                         AndAlso oraz OrElse. Działają one tak samo jak And i Or, ale pozwalają
                         oszacować tylko jedną część długiego wyrażenia warunkowego.

                         Jak to zrobić?
                         W wielu programach trzeba oszacować kilka warunków z rzędu. Często
                         najpierw sprawdzamy, czy obiekt nie jest pusty, a następnie badamy
                         jedną z jego właściwości.

82                       Rozdział 2: Język Visual Basic
W tym celu musimy używać zagnieżdżonych bloków If, jak w poniż-
szym przykładzie:
   If Not MyObject Is Nothing Then
       If MyObject.Value > 10 Then
           ' (robimy coś)
       End If
   End If

Byłoby miło połączyć te dwa warunki w jednym wierszu:
   If Not MyObject Is Nothing And MyObject.Value > 10 Then
       ' (robimy coś)
   End If

Niestety, to nie zadziała, ponieważ VB zawsze testuje oba warunki. In-
nymi słowy, nawet jeśli MyObject jest równy Nothing, VB sprawdzi
drugi warunek i spróbuje pobrać właściwość MyObject.Value, co spo-
woduje wyjątek NullReferenceException.
W Visual Basicu 2005 rozwiązano ten problem dzięki słowom kluczo-
wym AndAlso i OrElse. Kiedy używamy tych operatorów, Visual Basic
nie testuje drugiego warunku, jeśli pierwszy nie jest spełniony. Oto po-
prawiony kod:
   If Not MyObject Is Nothing AndAlso MyObject.Value > 10 Then
       ' (robimy coś)
   End If


A co…
…z innymi ulepszeniami języka? W tym rozdziale przedstawiono naj-
ważniejsze innowacje w języku VB. Warto jednak wspomnieć o kilku
innych nowościach, które nie zostały tu opisane:
 • Słowo kluczowe IsNot pozwala uprościć niezgrabną składnię. Dzięki
   niemu można zastąpić konstrukcję If Not x Is Nothing równo-
   ważną instrukcją If x IsNot Nothing.
 • Za pomocą funkcji TryCast() można nieco przyspieszyć rzutowanie
   typów. Działa ona tak jak funkcje CType() lub DirectCast(), z jednym
   wyjątkiem — jeśli obiektu nie można przekształcić w żądany typ,
   zwracana jest pusta referencja. Zamiast więc sprawdzać typ obiektu,
   a potem go rzutować, można od razu użyć funkcji TryCast(), a na-
   stępnie sprawdzić, czy zwróciła ona rzeczywistą referencję do obiektu.


                             Testowanie kolejnych części wyrażenia warunkowego   83
• Zmienne całkowite bez znaku umożliwiają przechowywanie wartości,
        które nie mogą być ujemne. Ograniczenie to oszczędza pamięć, po-
        zwalając na przechowywanie większych liczb. Liczby bez znaku zaw-
        sze były obsługiwane przez .NET Framework, ale obecnie VB 2005
        zawiera odpowiednie słowa kluczowe (UInteger, ULong i UShort).




84   Rozdział 2: Język Visual Basic

More Related Content

What's hot

J2EE. Vademecum profesjonalisty. Wydanie II
J2EE. Vademecum profesjonalisty. Wydanie IIJ2EE. Vademecum profesjonalisty. Wydanie II
J2EE. Vademecum profesjonalisty. Wydanie IIWydawnictwo Helion
 
Microsoft SQL Server 2005. Podręcznik programisty
Microsoft SQL Server 2005. Podręcznik programistyMicrosoft SQL Server 2005. Podręcznik programisty
Microsoft SQL Server 2005. Podręcznik programistyWydawnictwo Helion
 
.NET Framework 2.0. Zaawansowane programowanie
.NET Framework 2.0. Zaawansowane programowanie.NET Framework 2.0. Zaawansowane programowanie
.NET Framework 2.0. Zaawansowane programowanieWydawnictwo Helion
 
100 sposobów na Visual Studio
100 sposobów na Visual Studio100 sposobów na Visual Studio
100 sposobów na Visual StudioWydawnictwo Helion
 
Delphi 2005. 303 gotowe rozwiązania
Delphi 2005. 303 gotowe rozwiązaniaDelphi 2005. 303 gotowe rozwiązania
Delphi 2005. 303 gotowe rozwiązaniaWydawnictwo Helion
 
ASP.NET 2.0. Projektowanie aplikacji internetowych
ASP.NET 2.0. Projektowanie aplikacji internetowychASP.NET 2.0. Projektowanie aplikacji internetowych
ASP.NET 2.0. Projektowanie aplikacji internetowychWydawnictwo Helion
 
Visual C# 2008. Projektowanie aplikacji. Pierwsze starcie
Visual C# 2008. Projektowanie aplikacji. Pierwsze starcieVisual C# 2008. Projektowanie aplikacji. Pierwsze starcie
Visual C# 2008. Projektowanie aplikacji. Pierwsze starcieWydawnictwo Helion
 
Macromedia Flash MX 2004. Sztuka projektowania
Macromedia Flash MX 2004. Sztuka projektowaniaMacromedia Flash MX 2004. Sztuka projektowania
Macromedia Flash MX 2004. Sztuka projektowaniaWydawnictwo Helion
 
Excel. Programowanie dla profesjonalistów
Excel. Programowanie dla profesjonalistówExcel. Programowanie dla profesjonalistów
Excel. Programowanie dla profesjonalistówWydawnictwo Helion
 
Macromedia Flash 8. Oficjalny podręcznik
Macromedia Flash 8. Oficjalny podręcznikMacromedia Flash 8. Oficjalny podręcznik
Macromedia Flash 8. Oficjalny podręcznikWydawnictwo Helion
 
Spring Framework. Profesjonalne tworzenie oprogramowania w Javie
Spring Framework. Profesjonalne tworzenie oprogramowania w JavieSpring Framework. Profesjonalne tworzenie oprogramowania w Javie
Spring Framework. Profesjonalne tworzenie oprogramowania w JavieWydawnictwo Helion
 
Microsoft Visual Basic .NET 2003. Księga eksperta
Microsoft Visual Basic .NET 2003. Księga ekspertaMicrosoft Visual Basic .NET 2003. Księga eksperta
Microsoft Visual Basic .NET 2003. Księga ekspertaWydawnictwo Helion
 
Programowanie obiektowe w Visual Basic .NET dla każdego
Programowanie obiektowe w Visual Basic .NET dla każdegoProgramowanie obiektowe w Visual Basic .NET dla każdego
Programowanie obiektowe w Visual Basic .NET dla każdegoWydawnictwo Helion
 
Visual Basic .NET. Encyklopedia
Visual Basic .NET. EncyklopediaVisual Basic .NET. Encyklopedia
Visual Basic .NET. EncyklopediaWydawnictwo Helion
 
Tworzenie stron WWW we Flashu 8. Projekty
Tworzenie stron WWW we Flashu 8. ProjektyTworzenie stron WWW we Flashu 8. Projekty
Tworzenie stron WWW we Flashu 8. ProjektyWydawnictwo Helion
 

What's hot (20)

Visual Basic 2005. Od podstaw
Visual Basic 2005. Od podstawVisual Basic 2005. Od podstaw
Visual Basic 2005. Od podstaw
 
J2EE. Vademecum profesjonalisty. Wydanie II
J2EE. Vademecum profesjonalisty. Wydanie IIJ2EE. Vademecum profesjonalisty. Wydanie II
J2EE. Vademecum profesjonalisty. Wydanie II
 
Microsoft SQL Server 2005. Podręcznik programisty
Microsoft SQL Server 2005. Podręcznik programistyMicrosoft SQL Server 2005. Podręcznik programisty
Microsoft SQL Server 2005. Podręcznik programisty
 
.NET Framework 2.0. Zaawansowane programowanie
.NET Framework 2.0. Zaawansowane programowanie.NET Framework 2.0. Zaawansowane programowanie
.NET Framework 2.0. Zaawansowane programowanie
 
100 sposobów na Visual Studio
100 sposobów na Visual Studio100 sposobów na Visual Studio
100 sposobów na Visual Studio
 
ABC Delphi 2006
ABC Delphi 2006ABC Delphi 2006
ABC Delphi 2006
 
Delphi 2005. 303 gotowe rozwiązania
Delphi 2005. 303 gotowe rozwiązaniaDelphi 2005. 303 gotowe rozwiązania
Delphi 2005. 303 gotowe rozwiązania
 
ASP.NET 2.0. Projektowanie aplikacji internetowych
ASP.NET 2.0. Projektowanie aplikacji internetowychASP.NET 2.0. Projektowanie aplikacji internetowych
ASP.NET 2.0. Projektowanie aplikacji internetowych
 
Visual C# 2008. Projektowanie aplikacji. Pierwsze starcie
Visual C# 2008. Projektowanie aplikacji. Pierwsze starcieVisual C# 2008. Projektowanie aplikacji. Pierwsze starcie
Visual C# 2008. Projektowanie aplikacji. Pierwsze starcie
 
Macromedia Flash MX 2004. Sztuka projektowania
Macromedia Flash MX 2004. Sztuka projektowaniaMacromedia Flash MX 2004. Sztuka projektowania
Macromedia Flash MX 2004. Sztuka projektowania
 
Excel. Programowanie dla profesjonalistów
Excel. Programowanie dla profesjonalistówExcel. Programowanie dla profesjonalistów
Excel. Programowanie dla profesjonalistów
 
Macromedia Flash 8. Oficjalny podręcznik
Macromedia Flash 8. Oficjalny podręcznikMacromedia Flash 8. Oficjalny podręcznik
Macromedia Flash 8. Oficjalny podręcznik
 
Director MX. Szybki start
Director MX. Szybki startDirector MX. Szybki start
Director MX. Szybki start
 
Spring Framework. Profesjonalne tworzenie oprogramowania w Javie
Spring Framework. Profesjonalne tworzenie oprogramowania w JavieSpring Framework. Profesjonalne tworzenie oprogramowania w Javie
Spring Framework. Profesjonalne tworzenie oprogramowania w Javie
 
Microsoft Visual Basic .NET 2003. Księga eksperta
Microsoft Visual Basic .NET 2003. Księga ekspertaMicrosoft Visual Basic .NET 2003. Księga eksperta
Microsoft Visual Basic .NET 2003. Księga eksperta
 
JavaServer Faces. Wydanie II
JavaServer Faces. Wydanie IIJavaServer Faces. Wydanie II
JavaServer Faces. Wydanie II
 
Programowanie obiektowe w Visual Basic .NET dla każdego
Programowanie obiektowe w Visual Basic .NET dla każdegoProgramowanie obiektowe w Visual Basic .NET dla każdego
Programowanie obiektowe w Visual Basic .NET dla każdego
 
Visual Basic .NET. Encyklopedia
Visual Basic .NET. EncyklopediaVisual Basic .NET. Encyklopedia
Visual Basic .NET. Encyklopedia
 
Tworzenie stron WWW we Flashu 8. Projekty
Tworzenie stron WWW we Flashu 8. ProjektyTworzenie stron WWW we Flashu 8. Projekty
Tworzenie stron WWW we Flashu 8. Projekty
 
C++Builder 6 i bazy danych
C++Builder 6 i bazy danychC++Builder 6 i bazy danych
C++Builder 6 i bazy danych
 

Viewers also liked

Nowoczesna Firma
Nowoczesna FirmaNowoczesna Firma
Nowoczesna FirmaAdam
 
Dzielenie się wiedzą – jako przykład (nie
Dzielenie się wiedzą – jako przykład (nieDzielenie się wiedzą – jako przykład (nie
Dzielenie się wiedzą – jako przykład (nieKatarzyna Materska
 
Udręczeni przez demony. Opowieści o szatańskim zniewoleniu - ebook
Udręczeni przez demony. Opowieści o szatańskim zniewoleniu - ebookUdręczeni przez demony. Opowieści o szatańskim zniewoleniu - ebook
Udręczeni przez demony. Opowieści o szatańskim zniewoleniu - ebooke-booksweb.pl
 
Procesy mogą nam pomóc prowadzić projekty!
Procesy mogą nam pomóc prowadzić projekty!Procesy mogą nam pomóc prowadzić projekty!
Procesy mogą nam pomóc prowadzić projekty!Marek Smura
 
Krzysztof Indyk: Jak przetwarzać duże ilości danych? Wprowadzenie do Hadoopa.
Krzysztof Indyk: Jak przetwarzać duże ilości danych? Wprowadzenie do Hadoopa.Krzysztof Indyk: Jak przetwarzać duże ilości danych? Wprowadzenie do Hadoopa.
Krzysztof Indyk: Jak przetwarzać duże ilości danych? Wprowadzenie do Hadoopa.GameDesire Academy
 
Czytanie kodu. Punkt widzenia twórców oprogramowania open source
Czytanie kodu. Punkt widzenia twórców oprogramowania open sourceCzytanie kodu. Punkt widzenia twórców oprogramowania open source
Czytanie kodu. Punkt widzenia twórców oprogramowania open sourceWydawnictwo Helion
 
Knowledge Management 2.0 - Zarządzanie wiedzą 2.0
Knowledge Management 2.0 - Zarządzanie wiedzą 2.0Knowledge Management 2.0 - Zarządzanie wiedzą 2.0
Knowledge Management 2.0 - Zarządzanie wiedzą 2.0Digital-Knowledge
 
nik-p-12-096-teleinformatyka-policji
nik-p-12-096-teleinformatyka-policjinik-p-12-096-teleinformatyka-policji
nik-p-12-096-teleinformatyka-policjiAdam Zakrzewski
 
Scalone dokumenty (32)
Scalone dokumenty (32)Scalone dokumenty (32)
Scalone dokumenty (32)gemix gemix
 
Współdzielenie kodu aplikacji Windows Phone i Windows 8
Współdzielenie kodu aplikacji Windows Phone i Windows 8Współdzielenie kodu aplikacji Windows Phone i Windows 8
Współdzielenie kodu aplikacji Windows Phone i Windows 8Bartlomiej Zass
 
Marketing w wyszukiwarkach 2015 - raport Interaktywnie.com
Marketing w wyszukiwarkach  2015 - raport Interaktywnie.comMarketing w wyszukiwarkach  2015 - raport Interaktywnie.com
Marketing w wyszukiwarkach 2015 - raport Interaktywnie.comAnna Piekart
 
Średnie Kroczące i Oscylatory
Średnie Kroczące i OscylatoryŚrednie Kroczące i Oscylatory
Średnie Kroczące i OscylatoryStrefa Forex
 
Informatyka w zarządzaniu
Informatyka w zarządzaniuInformatyka w zarządzaniu
Informatyka w zarządzaniuAgnieszki
 
Oscylatory i ich praktyczne zastosowanie
Oscylatory i ich praktyczne zastosowanie Oscylatory i ich praktyczne zastosowanie
Oscylatory i ich praktyczne zastosowanie X-Trade Brokers
 

Viewers also liked (20)

Nowoczesna Firma
Nowoczesna FirmaNowoczesna Firma
Nowoczesna Firma
 
Dzielenie się wiedzą – jako przykład (nie
Dzielenie się wiedzą – jako przykład (nieDzielenie się wiedzą – jako przykład (nie
Dzielenie się wiedzą – jako przykład (nie
 
Kryzys jugosłowiański
Kryzys jugosłowiańskiKryzys jugosłowiański
Kryzys jugosłowiański
 
Łącze Satelitarne
Łącze SatelitarneŁącze Satelitarne
Łącze Satelitarne
 
Udręczeni przez demony. Opowieści o szatańskim zniewoleniu - ebook
Udręczeni przez demony. Opowieści o szatańskim zniewoleniu - ebookUdręczeni przez demony. Opowieści o szatańskim zniewoleniu - ebook
Udręczeni przez demony. Opowieści o szatańskim zniewoleniu - ebook
 
16
1616
16
 
Wentylacja pomieszczeń - wpływ na jakość powietrza
Wentylacja pomieszczeń - wpływ na jakość powietrzaWentylacja pomieszczeń - wpływ na jakość powietrza
Wentylacja pomieszczeń - wpływ na jakość powietrza
 
Procesy mogą nam pomóc prowadzić projekty!
Procesy mogą nam pomóc prowadzić projekty!Procesy mogą nam pomóc prowadzić projekty!
Procesy mogą nam pomóc prowadzić projekty!
 
Krzysztof Indyk: Jak przetwarzać duże ilości danych? Wprowadzenie do Hadoopa.
Krzysztof Indyk: Jak przetwarzać duże ilości danych? Wprowadzenie do Hadoopa.Krzysztof Indyk: Jak przetwarzać duże ilości danych? Wprowadzenie do Hadoopa.
Krzysztof Indyk: Jak przetwarzać duże ilości danych? Wprowadzenie do Hadoopa.
 
Czytanie kodu. Punkt widzenia twórców oprogramowania open source
Czytanie kodu. Punkt widzenia twórców oprogramowania open sourceCzytanie kodu. Punkt widzenia twórców oprogramowania open source
Czytanie kodu. Punkt widzenia twórców oprogramowania open source
 
Knowledge Management 2.0 - Zarządzanie wiedzą 2.0
Knowledge Management 2.0 - Zarządzanie wiedzą 2.0Knowledge Management 2.0 - Zarządzanie wiedzą 2.0
Knowledge Management 2.0 - Zarządzanie wiedzą 2.0
 
nik-p-12-096-teleinformatyka-policji
nik-p-12-096-teleinformatyka-policjinik-p-12-096-teleinformatyka-policji
nik-p-12-096-teleinformatyka-policji
 
Scalone dokumenty (32)
Scalone dokumenty (32)Scalone dokumenty (32)
Scalone dokumenty (32)
 
Współdzielenie kodu aplikacji Windows Phone i Windows 8
Współdzielenie kodu aplikacji Windows Phone i Windows 8Współdzielenie kodu aplikacji Windows Phone i Windows 8
Współdzielenie kodu aplikacji Windows Phone i Windows 8
 
Marketing w wyszukiwarkach 2015 - raport Interaktywnie.com
Marketing w wyszukiwarkach  2015 - raport Interaktywnie.comMarketing w wyszukiwarkach  2015 - raport Interaktywnie.com
Marketing w wyszukiwarkach 2015 - raport Interaktywnie.com
 
Średnie Kroczące i Oscylatory
Średnie Kroczące i OscylatoryŚrednie Kroczące i Oscylatory
Średnie Kroczące i Oscylatory
 
И.А. Вальдман "Ключевые аспекты качества образования".
И.А. Вальдман "Ключевые аспекты качества образования".И.А. Вальдман "Ключевые аспекты качества образования".
И.А. Вальдман "Ключевые аспекты качества образования".
 
Informatyka w zarządzaniu
Informatyka w zarządzaniuInformatyka w zarządzaniu
Informatyka w zarządzaniu
 
1.ins znrow14
1.ins znrow141.ins znrow14
1.ins znrow14
 
Oscylatory i ich praktyczne zastosowanie
Oscylatory i ich praktyczne zastosowanie Oscylatory i ich praktyczne zastosowanie
Oscylatory i ich praktyczne zastosowanie
 

Similar to Visual Basic 2005. Zapiski programisty

Visual C# 2005. Zapiski programisty
Visual C# 2005. Zapiski programistyVisual C# 2005. Zapiski programisty
Visual C# 2005. Zapiski programistyWydawnictwo Helion
 
Aplikacje w Visual C++ 2005. Przykłady
Aplikacje w Visual C++ 2005. PrzykładyAplikacje w Visual C++ 2005. Przykłady
Aplikacje w Visual C++ 2005. PrzykładyWydawnictwo Helion
 
Visual C# 2005 Express Edition. Od podstaw
Visual C# 2005 Express Edition. Od podstawVisual C# 2005 Express Edition. Od podstaw
Visual C# 2005 Express Edition. Od podstawWydawnictwo Helion
 
Visual Studio 2005. Programowanie z Windows API w języku C++
Visual Studio 2005. Programowanie z Windows API w języku C++Visual Studio 2005. Programowanie z Windows API w języku C++
Visual Studio 2005. Programowanie z Windows API w języku C++Wydawnictwo Helion
 
Asembler. Podręcznik programisty
Asembler. Podręcznik programistyAsembler. Podręcznik programisty
Asembler. Podręcznik programistyWydawnictwo Helion
 
MS Office 2000 i 2002/XP. Tworzenie własnych aplikacji w VBA
MS Office 2000 i 2002/XP. Tworzenie własnych aplikacji w VBAMS Office 2000 i 2002/XP. Tworzenie własnych aplikacji w VBA
MS Office 2000 i 2002/XP. Tworzenie własnych aplikacji w VBAWydawnictwo Helion
 
.Net. Najpilniej strzeżone tajemnice
.Net. Najpilniej strzeżone tajemnice.Net. Najpilniej strzeżone tajemnice
.Net. Najpilniej strzeżone tajemniceWydawnictwo Helion
 
Aplikacje w Delphi. Przykłady. Wydanie II
Aplikacje w Delphi. Przykłady. Wydanie IIAplikacje w Delphi. Przykłady. Wydanie II
Aplikacje w Delphi. Przykłady. Wydanie IIWydawnictwo Helion
 
PHP. 101 praktycznych skryptów. Wydanie II
PHP. 101 praktycznych skryptów. Wydanie IIPHP. 101 praktycznych skryptów. Wydanie II
PHP. 101 praktycznych skryptów. Wydanie IIWydawnictwo Helion
 
MySQL. Budowanie interfejsów użytkownika. Vademecum profesjonalisty
MySQL. Budowanie interfejsów użytkownika. Vademecum profesjonalistyMySQL. Budowanie interfejsów użytkownika. Vademecum profesjonalisty
MySQL. Budowanie interfejsów użytkownika. Vademecum profesjonalistyWydawnictwo Helion
 
PHP5. Zaawansowane programowanie
PHP5. Zaawansowane programowaniePHP5. Zaawansowane programowanie
PHP5. Zaawansowane programowanieWydawnictwo Helion
 
Wstęp do programowania w języku C#
Wstęp do programowania w języku C#Wstęp do programowania w języku C#
Wstęp do programowania w języku C#Wydawnictwo Helion
 
Po prostu PHP. Techniki zaawansowane
Po prostu PHP. Techniki zaawansowanePo prostu PHP. Techniki zaawansowane
Po prostu PHP. Techniki zaawansowaneWydawnictwo Helion
 

Similar to Visual Basic 2005. Zapiski programisty (18)

Visual C# 2005. Zapiski programisty
Visual C# 2005. Zapiski programistyVisual C# 2005. Zapiski programisty
Visual C# 2005. Zapiski programisty
 
Aplikacje w Visual C++ 2005. Przykłady
Aplikacje w Visual C++ 2005. PrzykładyAplikacje w Visual C++ 2005. Przykłady
Aplikacje w Visual C++ 2005. Przykłady
 
Visual C# 2005 Express Edition. Od podstaw
Visual C# 2005 Express Edition. Od podstawVisual C# 2005 Express Edition. Od podstaw
Visual C# 2005 Express Edition. Od podstaw
 
Visual Studio 2005. Programowanie z Windows API w języku C++
Visual Studio 2005. Programowanie z Windows API w języku C++Visual Studio 2005. Programowanie z Windows API w języku C++
Visual Studio 2005. Programowanie z Windows API w języku C++
 
Asembler. Podręcznik programisty
Asembler. Podręcznik programistyAsembler. Podręcznik programisty
Asembler. Podręcznik programisty
 
Visual Basic .NET. Ćwiczenia
Visual Basic .NET. ĆwiczeniaVisual Basic .NET. Ćwiczenia
Visual Basic .NET. Ćwiczenia
 
Spring. Zapiski programisty
Spring. Zapiski programistySpring. Zapiski programisty
Spring. Zapiski programisty
 
MS Office 2000 i 2002/XP. Tworzenie własnych aplikacji w VBA
MS Office 2000 i 2002/XP. Tworzenie własnych aplikacji w VBAMS Office 2000 i 2002/XP. Tworzenie własnych aplikacji w VBA
MS Office 2000 i 2002/XP. Tworzenie własnych aplikacji w VBA
 
.Net. Najpilniej strzeżone tajemnice
.Net. Najpilniej strzeżone tajemnice.Net. Najpilniej strzeżone tajemnice
.Net. Najpilniej strzeżone tajemnice
 
Aplikacje w Delphi. Przykłady. Wydanie II
Aplikacje w Delphi. Przykłady. Wydanie IIAplikacje w Delphi. Przykłady. Wydanie II
Aplikacje w Delphi. Przykłady. Wydanie II
 
ASP.NET 2.0. Księga eksperta
ASP.NET 2.0. Księga ekspertaASP.NET 2.0. Księga eksperta
ASP.NET 2.0. Księga eksperta
 
PHP. 101 praktycznych skryptów. Wydanie II
PHP. 101 praktycznych skryptów. Wydanie IIPHP. 101 praktycznych skryptów. Wydanie II
PHP. 101 praktycznych skryptów. Wydanie II
 
Contribute 2. Szybki start
Contribute 2. Szybki startContribute 2. Szybki start
Contribute 2. Szybki start
 
MySQL. Budowanie interfejsów użytkownika. Vademecum profesjonalisty
MySQL. Budowanie interfejsów użytkownika. Vademecum profesjonalistyMySQL. Budowanie interfejsów użytkownika. Vademecum profesjonalisty
MySQL. Budowanie interfejsów użytkownika. Vademecum profesjonalisty
 
C# i ASP.NET. Szybki start
C# i ASP.NET. Szybki startC# i ASP.NET. Szybki start
C# i ASP.NET. Szybki start
 
PHP5. Zaawansowane programowanie
PHP5. Zaawansowane programowaniePHP5. Zaawansowane programowanie
PHP5. Zaawansowane programowanie
 
Wstęp do programowania w języku C#
Wstęp do programowania w języku C#Wstęp do programowania w języku C#
Wstęp do programowania w języku C#
 
Po prostu PHP. Techniki zaawansowane
Po prostu PHP. Techniki zaawansowanePo prostu PHP. Techniki zaawansowane
Po prostu PHP. Techniki zaawansowane
 

More from Wydawnictwo Helion

Tworzenie filmów w Windows XP. Projekty
Tworzenie filmów w Windows XP. ProjektyTworzenie filmów w Windows XP. Projekty
Tworzenie filmów w Windows XP. ProjektyWydawnictwo Helion
 
Blog, więcej niż internetowy pamiętnik
Blog, więcej niż internetowy pamiętnikBlog, więcej niż internetowy pamiętnik
Blog, więcej niż internetowy pamiętnikWydawnictwo Helion
 
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktycznePozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczneWydawnictwo Helion
 
E-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesie
E-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesieE-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesie
E-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesieWydawnictwo Helion
 
Microsoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Microsoft Visual C++ 2008. Tworzenie aplikacji dla WindowsMicrosoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Microsoft Visual C++ 2008. Tworzenie aplikacji dla WindowsWydawnictwo Helion
 
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie IICo potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie IIWydawnictwo Helion
 
Makrofotografia. Magia szczegółu
Makrofotografia. Magia szczegółuMakrofotografia. Magia szczegółu
Makrofotografia. Magia szczegółuWydawnictwo Helion
 
Java. Efektywne programowanie. Wydanie II
Java. Efektywne programowanie. Wydanie IIJava. Efektywne programowanie. Wydanie II
Java. Efektywne programowanie. Wydanie IIWydawnictwo Helion
 
Ajax, JavaScript i PHP. Intensywny trening
Ajax, JavaScript i PHP. Intensywny treningAjax, JavaScript i PHP. Intensywny trening
Ajax, JavaScript i PHP. Intensywny treningWydawnictwo Helion
 
PowerPoint 2007 PL. Seria praktyk
PowerPoint 2007 PL. Seria praktykPowerPoint 2007 PL. Seria praktyk
PowerPoint 2007 PL. Seria praktykWydawnictwo Helion
 
Serwisy społecznościowe. Budowa, administracja i moderacja
Serwisy społecznościowe. Budowa, administracja i moderacjaSerwisy społecznościowe. Budowa, administracja i moderacja
Serwisy społecznościowe. Budowa, administracja i moderacjaWydawnictwo Helion
 

More from Wydawnictwo Helion (20)

Tworzenie filmów w Windows XP. Projekty
Tworzenie filmów w Windows XP. ProjektyTworzenie filmów w Windows XP. Projekty
Tworzenie filmów w Windows XP. Projekty
 
Blog, więcej niż internetowy pamiętnik
Blog, więcej niż internetowy pamiętnikBlog, więcej niż internetowy pamiętnik
Blog, więcej niż internetowy pamiętnik
 
Access w biurze i nie tylko
Access w biurze i nie tylkoAccess w biurze i nie tylko
Access w biurze i nie tylko
 
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktycznePozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
 
E-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesie
E-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesieE-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesie
E-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesie
 
Microsoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Microsoft Visual C++ 2008. Tworzenie aplikacji dla WindowsMicrosoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Microsoft Visual C++ 2008. Tworzenie aplikacji dla Windows
 
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie IICo potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
 
Makrofotografia. Magia szczegółu
Makrofotografia. Magia szczegółuMakrofotografia. Magia szczegółu
Makrofotografia. Magia szczegółu
 
Windows PowerShell. Podstawy
Windows PowerShell. PodstawyWindows PowerShell. Podstawy
Windows PowerShell. Podstawy
 
Java. Efektywne programowanie. Wydanie II
Java. Efektywne programowanie. Wydanie IIJava. Efektywne programowanie. Wydanie II
Java. Efektywne programowanie. Wydanie II
 
JavaScript. Pierwsze starcie
JavaScript. Pierwsze starcieJavaScript. Pierwsze starcie
JavaScript. Pierwsze starcie
 
Ajax, JavaScript i PHP. Intensywny trening
Ajax, JavaScript i PHP. Intensywny treningAjax, JavaScript i PHP. Intensywny trening
Ajax, JavaScript i PHP. Intensywny trening
 
PowerPoint 2007 PL. Seria praktyk
PowerPoint 2007 PL. Seria praktykPowerPoint 2007 PL. Seria praktyk
PowerPoint 2007 PL. Seria praktyk
 
Excel 2007 PL. Seria praktyk
Excel 2007 PL. Seria praktykExcel 2007 PL. Seria praktyk
Excel 2007 PL. Seria praktyk
 
Access 2007 PL. Seria praktyk
Access 2007 PL. Seria praktykAccess 2007 PL. Seria praktyk
Access 2007 PL. Seria praktyk
 
Word 2007 PL. Seria praktyk
Word 2007 PL. Seria praktykWord 2007 PL. Seria praktyk
Word 2007 PL. Seria praktyk
 
Serwisy społecznościowe. Budowa, administracja i moderacja
Serwisy społecznościowe. Budowa, administracja i moderacjaSerwisy społecznościowe. Budowa, administracja i moderacja
Serwisy społecznościowe. Budowa, administracja i moderacja
 
AutoCAD 2008 i 2008 PL
AutoCAD 2008 i 2008 PLAutoCAD 2008 i 2008 PL
AutoCAD 2008 i 2008 PL
 
Bazy danych. Pierwsze starcie
Bazy danych. Pierwsze starcieBazy danych. Pierwsze starcie
Bazy danych. Pierwsze starcie
 
Inventor. Pierwsze kroki
Inventor. Pierwsze krokiInventor. Pierwsze kroki
Inventor. Pierwsze kroki
 

Visual Basic 2005. Zapiski programisty

  • 1. IDZ DO PRZYK£ADOWY ROZDZIA£ SPIS TREŒCI Visual Basic 2005. Zapiski programisty KATALOG KSI¥¯EK Autor: Matthew MacDonald T³umaczenie: Grzegorz Werner KATALOG ONLINE ISBN: 83-246-0087-6 Tytu³ orygina³u: Visual Basic 2005: A Developers Notebook ZAMÓW DRUKOWANY KATALOG Format: B5, stron: 304 Przyk³ady na ftp: 1986 kB TWÓJ KOSZYK DODAJ DO KOSZYKA Visual Basic 2005 nie jest tak rewolucyjnym produktem, jak Visual Basic .NET. Opracowuj¹c wersjê 2005, twórcy jêzyka skoncentrowali siê na usuniêciu b³êdów i usterek oraz zwiêkszeniu komfortu pracy programisty. Narzêdzia i kontrolki, CENNIK I INFORMACJE w które wyposa¿ono zarówno najnowsz¹ wersjê Visual Basica, jak i œrodowisko programistyczne Visual Studio 2005, pozwalaj¹ znacznie przyspieszyæ pisanie kodu. ZAMÓW INFORMACJE Jednoczeœnie zosta³ zachowany dostêp do wszystkich mo¿liwoœci platformy .NET. O NOWOŒCIACH Ksi¹¿ka „Visual Basic 2005. Zapiski programisty” to zbiór notatek spisanych przez programistów analizuj¹cych tê wersjê jêzyka. Zawiera æwiczenia ilustruj¹ce nowe ZAMÓW CENNIK funkcje Visual Basica 2005, platformy .NET Framework 2.0 i œrodowiska programistycznego Visual Studio 2005. Programiœci korzystaj¹cy z wczeœniejszych wersji tych narzêdzi szybko opanuj¹ nowe funkcje, takie jak definiowanie klas CZYTELNIA generycznych czy korzystanie z obiektów My. Godne odnotowania jest tak¿e znaczne przyspieszenie i udoskonalenie technologii ASP.NET. FRAGMENTY KSI¥¯EK ONLINE • Edycja kodu w Visual Studio 2005 • Tworzenie dokumentacji w formacie XML • Korzystanie z obiektów My • Definiowanie klas generycznych • Tworzenie aplikacji dla œrodowiska Windows oraz aplikacji WWW • Projektowanie formularzy • Komunikacja z bazami danych • Wdra¿anie aplikacji za pomoc¹ technologii ClickOnce Dziêki tej ksi¹¿ce najnowsza wersja Visual Basica ods³ania swoje tajemnice. Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl
  • 2. Spis treści Seria „Zapiski programisty” .................................................................. 7 Przedmowa .......................................................................................... 13 Rozdział 1. Visual Studio ..................................................................... 19 Podstawowe informacje o Visual Studio 2005 ..................................... 20 Kodowanie, debugowanie i kontynuacja bez ponownego uruchamiania aplikacji ............................................ 23 Zaglądanie do wnętrza obiektu podczas debugowania ........................ 26 Diagnozowanie i poprawianie błędów „w locie” .................................. 29 Zmiana nazwy wszystkich wystąpień dowolnego elementu programu .... 31 Filtrowanie IntelliSense i autokorekta ................................................. 35 Wywoływanie metod podczas projektowania aplikacji ........................ 37 Wstawianie szablonowego kodu .......................................................... 39 Tworzenie dokumentacji XML ............................................................ 41 Rozdział 2. Język Visual Basic ............................................................. 47 Wykonywanie popularnych zadań za pomocą obiektów My ............... 48 Uzyskiwanie informacji o aplikacji ..................................................... 52 Używanie ściśle typizowanych zasobów ............................................. 54 3
  • 3. Używanie ściśle typizowanych ustawień konfiguracyjnych ................57 Tworzenie klas generycznych .............................................................60 Używanie wartości pustych w prostych typach danych .......................65 Używanie operatorów w połączeniu z własnymi obiektami ................67 Dzielenie klasy na wiele plików ...........................................................72 Rozszerzanie przestrzeni nazw My .....................................................73 Przechodzenie do następnej iteracji pętli .............................................76 Automatyczne usuwanie obiektów .......................................................79 Ochrona właściwości przy użyciu różnych poziomów dostępu ............81 Testowanie kolejnych części wyrażenia warunkowego .......................82 Rozdział 3. Aplikacje Windows ............................................................ 85 Używanie pasków narzędzi w stylu pakietu Office ..............................86 Dodawanie dowolnych kontrolek do paska ToolStrip ...........................91 Dodawanie ikon do menu ....................................................................92 Wyświetlanie strony WWW w oknie aplikacji .....................................95 Weryfikowanie danych podczas ich wpisywania ................................99 Tworzenie pól tekstowych z funkcją autouzupełniania ......................103 Odtwarzanie systemowych dźwięków Windows ................................105 Odtwarzanie prostych dźwięków WAV ..............................................106 Tworzenie podzielonego okna w stylu Eksploratora Windows ...........108 Automatyczne rozmieszczanie kontrolek ...........................................111 Określanie momentu zakończenia aplikacji .......................................113 Zapobieganie uruchamianiu wielu kopii aplikacji ..............................117 Komunikacja między formularzami ..................................................118 Przyspieszanie przerysowywania GDI+ ...........................................120 Bezpieczna obsługa zadań asynchronicznych ...................................124 Lepsza siatka danych ........................................................................128 Formatowanie siatki DataGridView ...................................................132 Dodawanie obrazów i kontrolek do siatki DataGridView ....................135 4 Spis treści
  • 4. Rozdział 4. Aplikacje WWW ............................................................... 139 Tworzenie aplikacji WWW w Visual Studio 2005 ............................. 140 Administrowanie aplikacją WWW .................................................... 143 Wiązanie danych bez pisania kodu ................................................... 146 Wiązanie kontrolek WWW z niestandardową klasą ......................... 151 Wyświetlanie interaktywnych tabel bez pisania kodu ....................... 156 Wyświetlanie pojedynczych rekordów .............................................. 159 Ujednolicanie wyglądu aplikacji przy użyciu stron szablonu ............ 165 Dodawanie elementów nawigacyjnych do witryny WWW ................ 170 Łatwe uwierzytelnianie użytkowników ............................................. 174 Sprawdzanie bieżącej liczby użytkowników witryny ......................... 182 Uwierzytelnianie oparte na rolach .................................................... 183 Przechowywanie indywidualnych informacji o użytkownikach ........ 188 Rozdział 5. Pliki, bazy danych i XML .................................................. 195 Pobieranie informacji o dyskach ....................................................... 196 Pobieranie informacji o plikach i katalogach ..................................... 199 Kopiowanie, przenoszenie i usuwanie plików ................................... 201 Odczytywanie i zapisywanie plików .................................................. 204 Kompresowanie i dekompresowanie danych .................................... 206 Gromadzenie danych statystycznych o połączeniach ze źródłami danych ................................................ 209 Łączenie poleceń adaptera danych w celu zwiększenia wydajności .. 212 Hurtowe kopiowanie wierszy z jednej tabeli do drugiej ..................... 215 Pisanie kodu niezależnego od używanej bazy danych ....................... 219 Nowe klasy XPathDocument i XPathNavigator ................................. 224 Edycja dokumentów XML przy użyciu klasy XPathNavigator .......... 229 Rozdział 6. Usługi platformy .NET ...................................................... 235 Łatwe rejestrowanie zdarzeń ............................................................ 236 Sprawdzanie łączności z innym komputerem ................................... 240 Uzyskiwanie informacji o połączeniu sieciowym .............................. 243 Spis treści 5
  • 5. Wysyłanie i pobieranie plików przy użyciu FTP ................................246 Testowanie przynależności grupowej bieżącego użytkownika ...........253 Szyfrowanie danych dla bieżącego użytkownika ...............................255 Ujarzmianie konsoli ..........................................................................258 Mierzenie czasu wykonywania kodu .................................................262 Wdrażanie aplikacji za pomocą technologii ClickOnce .......................264 Skorowidz .......................................................................................... 271 6 Spis treści
  • 6. ROZDZIAŁ 2 Język Visual Basic W tym rozdziale: Wykonywanie popularnych zadań za pomocą obiektów My Uzyskiwanie informacji o aplikacji Używanie ściśle typizowanych zasobów Używanie ściśle typizowanych ustawień konfiguracyjnych Tworzenie klas generycznych Używanie wartości pustych w prostych typach danych Używanie operatorów w połączeniu z własnymi obiektami Dzielenie klasy na wiele plików Rozszerzanie przestrzeni nazw My Przechodzenie do następnej iteracji pętli Automatyczne usuwanie obiektów Kiedy pojawiła się pierwsza wersja Visual Basica .NET, lojalni progra- miści VB byli zaszokowani drastycznymi zmianami w ich ulubionym języku. Ni stąd, ni zowąd proste czynności, takie jak tworzenie instancji obiektu i deklarowanie struktury, wymagały nowej składni, a podsta- wowe typy, na przykład tablice, zostały przekształcone w coś zupełnie innego. Na szczęście w Visual Basicu 2005 nie ma takich niespodzianek. Zmiany w najnowszych wersjach języka upraszczają programowanie, 47
  • 7. ale nie sprawiają, że istniejący kod staje się przestarzały. Wiele spośród tych zmian to funkcje przeniesione z języka C# (na przykład przeciąża- nie operatorów), a inne to zupełnie nowe składniki wbudowane w naj- nowszą wersję wspólnego środowiska uruchomieniowego (na przykład klasy generyczne). W tym rozdziale opiszemy najprzydatniejsze zmiany w języku VB. Wykonywanie popularnych zadań za pomocą obiektów My Nowe obiekty My zapewniają łatwy dostęp do popularnych funkcji, które niełatwo jest znaleźć w obszernej bibliotece klas .NET. Zasadniczo obiekty My udostępniają różnorodne elementy, od rejestru Windows do ustawień bieżącego połączenia sieciowego. Co najlepsze, hierarchia obiektów My jest zorganizowana według zastosowań i łatwo się po niej poruszać przy użyciu IntelliSense. Przedzieranie się Jak to zrobić? przez obszerną bibliotekę klas .NET Istnieje siedem podstawowych obiektów My. Spośród nich trzy kluczowe w poszukiwaniu potrzebnej funkcji obiekty centralizują zestaw funkcji .NET Framework i dostarczają in- bywa męczące. formacji o komputerze. Są to: Dzięki nowym obiektom My można My.Computer szybko znaleźć Ten obiekt zawiera informacje o komputerze, w tym o jego połącze- najprzydatniejsze niu sieciowym, stanie myszy i klawiatury, bieżącym katalogu, dru- funkcje oferowane przez .NET. karce, ekranie oraz zegarze. Można też użyć go jako punktu wyjścia do odtwarzania dźwięków, wyszukiwania plików, dostępu do reje- stru albo korzystania ze schowka Windows. My.Application Ten obiekt zawiera informacje o bieżącej aplikacji i jej kontekście, w tym o podzespole i jego wersji, kulturze, a także o argumentach wiersza polecenia użytych podczas uruchamiania aplikacji. Można go również użyć do rejestrowania zdarzeń występujących w aplikacji. 48 Rozdział 2: Język Visual Basic
  • 8. My.User Ten obiekt zawiera informacje o bieżącym użytkowniku. Można użyć go do sprawdzenia konta użytkownika Windows i ustalenia, do jakiej grupy należy użytkownik. Obok tych trzech obiektów istnieją kolejne dwa, które zapewniają dostęp do instancji domyślnych. Instancje domyślne to obiekty, które .NET tworzy automatycznie dla pewnych typów klas zdefiniowanych w aplikacji. Są to: My.Forms Ten obiekt zapewnia instancję domyślną każdego formularza Windows w aplikacji. Można użyć go do obsługi komunikacji między formu- larzami bez śledzenia referencji do formularzy w oddzielnej klasie. My.WebServices Ten obiekt zapewnia instancję domyślną klasy pośredniczącej dla każdej usługi WWW. Jeśli na przykład projekt używa dwóch referen- cji WWW, poprzez ten obiekt można uzyskać dostęp do gotowej klasy pośredniczącej dla każdej z nich. Kolejne dwa obiekty My zapewniają łatwy dostęp do ustawień konfigura- cyjnych i zasobów: My.Settings Ten obiekt umożliwia pobranie ustawień z pliku konfiguracyjnego XML aplikacji. My.Resources Ten obiekt umożliwia pobieranie zasobów — bloków danych binar- nych lub tekstowych, które są kompilowane z podzespołem aplikacji. Zasobów zwykle używa się do przechowywania wielojęzycznych łań- cuchów, obrazów i plików dźwiękowych. O S T R Z EŻ ENIE Warto zaznaczyć, że działanie obiektów My zależy od typu projektu. Na przykład w aplikacjach WWW lub aplikacjach konsoli nie można korzystać z kolekcji My.Forms. Wykonywanie popularnych zadań za pomocą obiektów My 49
  • 9. Niektóre spośród klas My są zdefiniowane w przestrzeni nazw Microsoft. VisualBasic.MyServices, a inne, na przykład klasy używane w obiek- tach My.Settings i My.Resources, są tworzone dynamicznie przez Visual Studio 2005 podczas modyfikowania ustawień aplikacji i dodawania za- sobów do bieżącego projektu. Aby wypróbować obiekt My, można skorzystać z funkcji IntelliSense. Wystarczy wpisać słowo My oraz kropkę i obejrzeć dostępne obiekty (ry- sunek 2.1). Następnie można wybrać jeden z nich i wpisać kolejną kropkę, aby przejść na niższy poziom hierarchii. Rysunek 2.1. Przeglądanie obiektów My W celu wypróbowania prostego kodu, który wyświetla kilka podstawowych informacji z wykorzystaniem obiektu My, utwórzmy nowy projekt typu Console Application. Następnie dodajmy poniższy kod do procedury Main(): Console.WriteLine(My.Computer.Name) Console.WriteLine(My.Computer.Clock.LocalTime) Console.WriteLine(My.Computer.FileSystem.CurrentDirectory) Console.WriteLine(My.User.Name) Po uruchomieniu tego kodu w oknie konsoli zostanie wyświetlona nazwa komputera, bieżący czas, bieżący katalog oraz nazwa użytkownika: SALESSERVER 2005-07-06 11:18:18 C:KodNotatnikVB1.07Testbin MATTHEW 50 Rozdział 2: Język Visual Basic
  • 10. O S T R Z EŻ ENIE Obiekt My ma również „ciemną stronę”. Rozwiązania, w których go zastosowano, trudniej współużytkować z innymi programistami, ponieważ nie jest on obsługiwany w językach innych niż VB (na przykład C#). Więcej informacji Aby dowiedzieć się więcej o obiekcie My i zobaczyć przykłady jego uży- cia, należy zajrzeć pod hasło indeksu „My Object” w pomocy MSDN. Można też wykonać inne ćwiczenia, w których wykorzystano obiekt My. Oto kilka przykładów: • używanie obiektu My.Application do pobierania informacji o pro- gramie, takich jak bieżąca wersja oraz parametry wiersza polecenia podane podczas uruchamiania aplikacji (ćwiczenie „Uzyskiwanie informacji o aplikacji” dalej w tym rozdziale); • wczytywanie obrazów i innych zasobów z podzespołu aplikacji za pomocą obiektu My.Resources (ćwiczenie „Używanie ściśle typizo- wanych zasobów” dalej w tym rozdziale); • pobieranie ustawień aplikacji i użytkownika za pomocą obiektu My.Settings (ćwiczenie „Używanie ściśle typizowanych ustawień konfiguracyjnych” dalej w tym rozdziale); • używanie obiektu My.Forms do interakcji między oknami aplikacji (ćwiczenie „Komunikacja między formularzami” w rozdziale 3.); • manipulowanie plikami i połączeniami sieciowymi za pomocą obiektu My.Computer (rozdziały 5. i 6.); • uwierzytelnianie użytkownika za pomocą obiektu My.User (ćwiczenie „Testowanie przynależności grupowej bieżącego użytkownika” w roz- dziale 6.). Wykonywanie popularnych zadań za pomocą obiektów My 51
  • 11. Za pomocą obiektu My.Application Uzyskiwanie informacji o aplikacji można pobrać informacje o bieżącej Obiekt My.Application udostępnia wiele przydatnych informacji. W celu wersji aplikacji, ich pobrania wystarczy odczytać właściwości obiektu. jej położeniu oraz parametrach użytych do jej Jak to zrobić? uruchomienia. Informacje zawarte w obiekcie My.Application przydają się w wielu róż- nych sytuacjach. Oto dwa przykłady: • Chcemy ustalić dokładny numer wersji. Bywa to użyteczne, jeśli chcemy wyświetlić dynamiczne okno z informacjami o programie albo sprawdzić usługę WWW i upewnić się, że mamy najnowszą wersję podzespołu. • Chcemy zarejestrować pewne informacje diagnostyczne. Jest to istotne, jeśli problem występuje u klienta i musimy zapisać ogólne informacje o działającej aplikacji. Aby sprawdzić, jak to działa, można wykorzystać kod z listingu 2.1 w apli- kacji konsoli. Pobiera on wszystkie informacje i wyświetla je w oknie konsoli. Listing 2.1. Pobieranie informacji z obiektu My.Application ' Ustalamy parametry, z jakimi została uruchomiona aplikacja Console.Write("Parametry wiersza polecenia: ") For Each Arg As String In My.Application.CommandLineArgs Console.Write(Arg & " ") Next Console.WriteLine() Console.WriteLine() ' Pobieramy informacje o podzespole, w którym znajduje się ten kod ' Informacje te pochodzą z metadanych (atrybutów w kodzie) Console.WriteLine("Firma: " & My.Application.Info.CompanyName) Console.WriteLine("Opis: " & My.Application.Info.Description) Console.WriteLine("Lokalizacja: " & My.Application.Info.DirectoryPath) Console.WriteLine("Prawa autorskie: " & My.Application.Info.Copyright) Console.WriteLine("Znak towarowy: " & My.Application.Info.Trademark) Console.WriteLine("Nazwa: " & My.Application.Info.AssemblyName) Console.WriteLine("Produkt: " & My.Application.Info.ProductName) Console.WriteLine("Tytuł: " & My.Application.Info.Title) Console.WriteLine("Wersja: " & My.Application.Info.Version.ToString()) Console.WriteLine() 52 Rozdział 2: Język Visual Basic
  • 12. WS KAZÓWK A Visual Studio 2005 zawiera okno Quick Console, które jest uprosz- czoną wersją zwykłego okna wiersza poleceń. W niektórych przy- padkach okno to działa nieprawidłowo. W razie problemów z uru- chamianiem przykładowej aplikacji i wyświetlaniem jej wyników należy wyłączyć okno Quick Console. W tym celu należy wybrać z menu Tools polecenie Options, upewnić się, że zaznaczone jest pole wyboru Show all settings, po czym przejść do pozycji Debugging –> General. Następnie należy usunąć zaznaczenie z pola Redirect all console output to the Quick Console window. Przed przetestowaniem powyższego kodu warto skonfigurować środowisko tak, aby program zwrócił sensowne wyniki. Można na przykład przeka- zać parametry wiersza polecenia do uruchamianej aplikacji. W tym celu należy kliknąć dwukrotnie ikonę My Project w oknie Solution Explorer. Następnie należy przejść na zakładkę Debug i poszukać pola tekstowego Command line parameters. W polu tym należy wpisać parametry wiersza polecenia, na przykład /a /b /c. Aby określić informacje, takie jak autor podzespołu, produkt, wersja itd., trzeba dodać specjalne atrybuty do pliku AssemblyInfo.vb, który zwykle nie jest widoczny w oknie Solution Explorer. Aby go wyświetlić, należy wybrać z menu Project polecenie Show All Files. Plik AssemblyInfo.vb jest umieszczony pod węzłem My Project. Oto typowy zestaw znaczni- ków, które można określić w tym pliku: <Assembly: AssemblyVersion("1.0.0.0")> <Assembly: AssemblyCompany("Prosetech")> Nowością w VB <Assembly: AssemblyDescription("Program testujący obiekt My.Application")> 2005 jest możliwość <Assembly: AssemblyCopyright("(C) Matthew MacDonald")> dodawania info- <Assembly: AssemblyTrademark("(R) Prosetech")> rmacji o aplikacji <Assembly: AssemblyTitle("Aplikacja testowa")> <Assembly: AssemblyProduct("Aplikacja testowa")> w specjalnym oknie dialogowym. Aby Wszystkie te informacje zostaną osadzone w skompilowanym podze- skorzystać z tej funkcji, należy spole jako metadane. kliknąć dwukrotnie Teraz można uruchomić testową aplikację. Oto przykładowe wyniki: ikonę My Project w oknie Solution Parametry wiersza polecenia: /a /b /c Explorer, przejść na zakładkę Application Firma: Prosetech i kliknąć przycisk Opis: Program testujący obiekt My.Application Lokalizacja: C:NotatnikVB2InformacjeOAplikacjibinDebug Assembly Information. Uzyskiwanie informacji o aplikacji 53
  • 13. Prawa autorskie: (C) Matthew MacDonald Znak towarowy: (R) Prosetech Nazwa: InformacjeOAplikacji Produkt: Aplikacja testowa Tytuł: Aplikacja testowa Wersja: 1.0.0.0 A co… …z uzyskiwaniem bardziej szczegółowych informacji diagnostycznych? Obiekt My.Computer.Info ma dwie przydatne właściwości, które dostar- czają takich informacji. Właściwość LoadedAssemblies to kolekcja wszyst- kich podzespołów, które są obecnie wczytane (i dostępne dla aplikacji). Można też zbadać ich wersje oraz informacje o wydawcy. Właściwość StackTrace zawiera bieżący obraz stosu i pozwala ustalić, którą część kodu obecnie wykonuje program. Jeśli na przykład metoda Main() wy- wołuje metodę A(), a ta wywołuje metodę B(), na stosie będzie widać te trzy metody — B(), A() i Main() — w odwrotnej kolejności. Oto kod, który wyświetla te informacje: Console.WriteLine("Wczytane podzespoły:") For Each Assm As System.Reflection.Assembly In _ My.Application.Info.LoadedAssemblies Console.WriteLine(Assm.GetName().Name) Next Console.WriteLine() Console.WriteLine("Bieżący stos: " & My.Application.Info.StackTrace) Console.WriteLine() Ściśle typizowane zasoby umożliwiają Używanie ściśle typizowanych zasobów osadzanie statycz- Podzespoły .NET oprócz kodu mogą zawierać zasoby — osadzone dane nych danych (na przykład obrazów) binarne, na przykład obrazy i niezmienne łańcuchy. Choć środowisko w skompilowanych .NET obsługuje zasoby już od wersji 1.0, Visual Studio nie oferowało ich podzespołach zintegrowanej obsługi w czasie projektowania aplikacji. W rezultacie i zapewniają łatwy dostęp do tych danych programiści, którzy chcieli zapisać dane obrazu w swojej aplikacji, zwy- z poziomu kodu. kle dodawali je do kontrolek obsługujących obrazy podczas projektowa- nia aplikacji, takich jak PictureBox lub ImageList. Kontrolki te automa- tycznie wstawiały dane obrazu do pliku zasobów aplikacji. 54 Rozdział 2: Język Visual Basic
  • 14. W Visual Studio 2005 znacznie łatwiej jest dodawać informacje do plików zasobu i później je aktualizować. Co najlepsze, można uzyskać dostęp do tych informacji z dowolnego punktu kodu, i to ze ścisłą kontrolą typów. Jak to zrobić? Aby utworzyć ściśle typizowany zasób na użytek tego ćwiczenia, należy zacząć od utworzenia nowej aplikacji Windows. W celu dodania zasobu należy kliknąć dwukrotnie węzeł My Project w oknie Solution Explorer. Pojawi się okno projektu aplikacji, w którym można skonfigurować wiele różnorodnych ustawień programu. Następ- nie należy przejść na zakładkę Resources i wybrać żądany typ zasobów z listy rozwijanej umieszczonej w lewym górnym oknie (Strings, Images, Audio itd.). Widok łańcuchów przedstawia siatkę danych. Widok obrazów jest nieco inny — domyślnie pokazuje miniatury dołączonych obrazów. Aby dodać nowy obraz, należy wybrać z listy kategorię Images, a na- stępnie kliknąć strzałkę obok przycisku Add Resource i wybrać polecenie Add Existing File. Należy znaleźć plik obrazu, zaznaczyć go i kliknąć przycisk OK. Ci, którzy nie mają pod ręką innego obrazu, mogą wyko- rzystać jeden spośród plików przechowywanych w katalogu Windows, na przykład winnt256.bmp (który jest dołączany do większości wersji Windows). Domyślnie zasób ma tę samą nazwę co plik, ale można ją zmienić po dodaniu zasobu. W tym przykładzie zmienimy nazwę obrazu na EmbeddedGraphic Klasa zasobów (jak pokazano na rysunku 2.2). jest dodawana do węzła My Project Korzystanie z zasobów jest bardzo łatwe. Wszystkie zasoby są kompilo- i otrzymuje nazwę Resources.Designer.vb. wane dynamicznie w ściśle typizowaną klasę zasobów, do której można Aby ją zobaczyć, uzyskać dostęp poprzez obiekt My.Resources. Aby wypróbować nowo trzeba wybrać dodany zasób, należy dodać kontrolkę PictureBox do formularza Win- z menu Project polecenie Show All dows (i zachować domyślną nazwę PictureBox1). Następnie należy dodać Files. Oczywiście, nie poniższy kod, który wyświetli obraz podczas wczytywania formularza: należy modyfikować tego pliku ręcznie. Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load PictureBox1.Image = My.Resources.EmbeddedGraphic End Sub Używanie ściśle typizowanych zasobów 55
  • 15. Rysunek 2.2. Dodawanie obrazu jako ściśle typizowanego zasobu Po uruchomieniu programu obraz zostanie wyświetlony na formularzu. Aby upewnić się, że obraz jest pobierany z podzespołu, można skompi- lować aplikację, a następnie usunąć plik obrazu (kod będzie nadal dzia- łał bez żadnych problemów). Inną zaletą zasobów Kiedy dodajemy zasoby w taki sposób, Visual Studio kopiuje je do pod- jest to, że można katalogu Resources aplikacji. Katalog ten, wraz z zawartymi w nim za- wykorzystać te same obrazy w wielu sobami, można obejrzeć w oknie Solution Explorer. Podczas kompilowania kontrolkach na aplikacji wszystkie zasoby są osadzane w podzespole, ale przechowy- różnych formula- wanie ich w oddzielnym katalogu ma pewną ważną zaletę — pozwala rzach bez dodawania wielu kopii obrazu zaktualizować zasób przez zamianę pliku i ponowne skompilowanie apli- do jednego pliku. kacji. Nie trzeba modyfikować kodu. Jest to niezwykle przydatne, jeśli trzeba jednocześnie zaktualizować wiele obrazów albo innych zasobów. Zasoby można dołączać do różnych kontrolek za pomocą okna Properties. Na przykład po kliknięciu wielokropka (...) obok właściwości Image kontrolki PictureBox pojawi się okno z listą wszystkich obrazów dostęp- nych w zasobach aplikacji. 56 Rozdział 2: Język Visual Basic
  • 16. A co… …z kontrolką ImageList? Większość programistów Windows zna tę kontrolkę, która grupuje wiele obrazów (zwykle niewielkich map bitowych) na użytek innych kontrolek, takich jak menu, paski narzędzi, drzewa i li- sty. Kontrolka ImageList nie używa typizowanych zasobów, lecz wła- snej metody serializacji. Choć dostęp do zawartych w niej obrazów można uzyskać zarówno podczas projektowania aplikacji, jak i metodą progra- mistyczną, nie podlega ona kontroli typów. Używanie ściśle typizowanych Tworzenie ustawień konfiguracyjnych ustawień konfiguracyjnych w oknie projektu aplikacji. Aplikacje często używają ustawień konfiguracyjnych, na przykład wska- zujących położenie plików, parametry połączenia z bazą danych i prefe- rencje użytkownika. Zamiast kodować te ustawienia „na sztywno” (albo wymyślać własny mechanizm ich przechowywania), w .NET można dodać je do pliku konfiguracyjnego specyficznego dla aplikacji. Dzięki temu można je łatwo modyfikować poprzez edycję pliku tekstowego, bez po- nownego kompilowania aplikacji. W Visual Studio 2005 jest to jeszcze łatwiejsze, ponieważ ustawienia konfiguracyjne są kompilowane w oddzielną klasę i podlegają ścisłej kontroli typów. Oznacza to, że można pobierać ustawienia przy użyciu właściwości, z wykorzystaniem funkcji IntelliSense, zamiast zdawać się na wyszukiwanie tekstowe. Co najlepsze, .NET rozszerza ten model o możliwość używania ustawień specyficznych dla użytkownika w celu śledzenia preferencji i innych informacji. W niniejszym ćwiczeniu zo- staną zaprezentowane obie te techniki. Jak to zrobić? Każde ustawienie konfiguracyjne jest definiowane przez unikatową na- zwę. W poprzednich wersjach .NET można było pobrać wartość usta- wienia konfiguracyjnego poprzez wyszukanie jego nazwy w kolekcji. Je- śli jednak nazwa była nieprawidłowa, błąd można było wykryć dopiero po uruchomieniu programu i wystąpieniu wyjątku czasu wykonania. Używanie ściśle typizowanych ustawień konfiguracyjnych 57
  • 17. W aplikacji WWW W Visual Studio 2005 sytuacja wygląda znacznie lepiej. Aby dodać nowe ustawienia konfigura- ustawienie konfiguracyjne, należy kliknąć dwukrotnie węzeł My Project cyjne są umieszczane w pliku web.config. w oknie Solution Explorer. Pojawi się okno projektu aplikacji, w którym W innych aplikacjach można skonfigurować wiele różnorodnych ustawień programu. Następ- ustawienia są nie należy przejść na zakładkę Settings, która pokazuje listę niestandar- umieszczane w pliku noszącym tę samą dowych ustawień konfiguracyjnych i umożliwia zdefiniowanie nowych nazwę co aplikacja ustawień oraz ich wartości. i uzupełnioną rozszerzeniem Aby dodać do aplikacji nowe ustawienie konfiguracyjne, należy wpisać .config, na przykład MojaAplikacja. jego nazwę na dole listy. Następnie należy określić typ danych, zasięg exe.config. i rzeczywistą wartość ustawienia. Aby na przykład dodać ustawienie ze ścieżką do pliku, można użyć nazwy UserDataFilePath, typu String, zasięgu Application (niebawem powiemy więcej na ten temat) oraz warto- ści c:MyFiles. Ustawienie to pokazano na rysunku 2.3. Rysunek 2.3. Definiowanie ściśle typizowanego ustawienia konfiguracyjnego Po dodaniu tego ustawienia Visual Studio .NET wstawi poniższe infor- macje do pliku konfiguracyjnego aplikacji: <configuration> <applicationSettings> <TypizowaneUstawienia.Settings> <setting name="UserDataFilePath" serializeAs="String"> <value>c:MyFiles</value> </setting> 58 Rozdział 2: Język Visual Basic
  • 18. </TypizowaneUstawienia.Settings> </applicationSettings> </configuration> Jednocześnie „za kulisami” Visual Studio skompiluje klasę, która za- wiera informacje o niestandardowym ustawieniu konfiguracyjnym. Teraz z dowolnego miejsca w kodzie będzie można uzyskać dostęp do ustawie- nia według jego nazwy za pośrednictwem obiektu My.Settings. Oto kod, który pobiera wartość ustawienia o nazwie UserDataFilePath: Dim path As String path = My.Settings.UserDataFilePath W .NET 2.0 ustawienia konfiguracyjne nie muszą być łańcuchami. Klasa ustawień Można używać innych serializowalnych typów danych, w tym liczb cał- konfiguracyjnych kowitych i dziesiętnych, dat i czasów (wystarczy wybrać odpowiedni typ jest dodawana do z listy rozwijanej Type). Wartości te są przekształcane w tekst podczas węzła My Project i nosi nazwę zapisu w pliku konfiguracyjnym, ale można je pobrać za pośrednictwem Settings.Designer. obiektu My.Settings w odpowiednim formacie, bez analizy składniowej! Aby ją obejrzeć, należy wybrać z menu Project A co… polecenie Show All Files. …z aktualizowaniem ustawień? W przykładzie UserFileDataPath wy- korzystano ustawienie o zasięgu aplikacji, które można odczytywać w cza- sie działania programu, ale nie można go modyfikować. Jeśli konieczna jest aktualizacja ustawienia o zasięgu aplikacji, trzeba ręcznie zmodyfi- kować plik konfiguracyjny (albo użyć listy ustawień w Visual Studio). Alternatywą jest utworzenie ustawień o zasięgu użytkownika. W tym celu wystarczy wybrać pozycję User z listy rozwijanej Scope na liście ustawień. Jeśli ustawienie ma zasięg użytkownika, wartość ustawiona w Visual Studio jest zapisywana jako wartość domyślna w pliku konfi- guracyjnym, w katalogu aplikacji. Jednakże zmiana tych ustawień po- woduje utworzenie nowego pliku user.config i zapisanie go w katalogu specyficznym dla bieżącego użytkownika (o nazwie c:Documents and Settings[NazwaUżytkownika]Ustawienia lokalneDane aplikacji[Nazwa Firmy][UnikatowyKatalog][WersjaAplikacji]). W razie użycia ustawień specyficznych dla użytkownika trzeba pamię- tać o wywołaniu metody My.Settings.Save() w celu zapisania zmian. W przeciwnym razie zmiany będą obowiązywać tylko do momentu za- Używanie ściśle typizowanych ustawień konfiguracyjnych 59
  • 19. mknięcia aplikacji. Zwykle metodę My.Settings.Save() wywołuje się pod koniec działania aplikacji. Aby wypróbować ustawienia o zasięgu użytkownika, należy zmienić za- sięg ustawienia UserDataFilePath na User. Następnie należy utworzyć formularz z polem tekstowym (o nazwie txtFilePath) i dwoma przyci- skami: jednym do pobierania ustawienia (cmdRefresh), a drugim do ak- tualizowania go (cmdUpdate). Oto odpowiednie procedury obsługi zdarzeń: Private Sub cmdRefresh_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdRefresh.Click txtFilePath.Text = My.Settings.UserDataFilePath End Sub Private Sub cmdUpdate_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdUpdate.Click My.Settings.UserDataFilePath = txtFilePath.Text End Sub Aby zmiany obowiązywały podczas następnego uruchomienia aplikacji, konieczne jest utworzenie lub zaktualizowanie pliku user.config podczas zamykania formularza: Private Sub Form1_FormClosed(ByVal sender As Object, _ ByVal e As System.Windows.Forms.FormClosedEventArgs) _ Handles Me.FormClosed My.Settings.Save() End Sub To już cały kod, który trzeba dodać do formularza. Teraz można uru- chomić aplikację i sprawdzić, jak działa pobieranie bieżącego ustawienia i zapisywanie nowego. Następnie można poszukać pliku user.config, który zawiera zmienione ustawienia bieżącego użytkownika. Jak utworzyć klasę Tworzenie klas generycznych na tyle elastyczną, Programiści często stają przed trudnym wyborem. Z jednej strony, bar- aby mogła działać z dowolnym typem dzo ważne jest tworzenie rozwiązań uniwersalnych, które można wielo- obiektu, a jednocze- krotnie wykorzystywać w różnych sytuacjach. Dlaczego na przykład śnie w każdej sytuacji móc ograniczać mielibyśmy tworzyć klasę CustomerCollection, która przyjmuje tylko przyjmowane obiekty typu Customer, skoro możemy zaprojektować klasę Collection przez nią obiekty? zapewniającą dostęp do obiektów dowolnego typu? Z drugiej strony kwe- Rozwiązaniem są konstrukcje gene- stie wydajności i typizacji sprawiają, że rozwiązania uniwersalne są ryczne języka VB. mniej pożądane. Jeśli na przykład użyjemy generycznej klasy .NET 60 Rozdział 2: Język Visual Basic
  • 20. Collection do przechowywania obiektów Customer, to skąd mamy wie- dzieć, czy przypadkiem nie wstawimy do kolekcji obiektu innego typu, co później spowoduje trudne do wykrycia problemy? Visual Basic 2005 i .NET 2.0 zapewniają rozwiązanie nazywane kla- sami generycznymi. Są to klasy parametryzowane według typu. Innymi słowy, umożliwiają one zbudowanie szablonu obsługującego dowolny typ. Podczas tworzenia instancji klasy określamy, jakiego typu chcemy używać, i od tego momentu jesteśmy „przywiązani” do wybranego typu. Jak to zrobić? Przykładem, który pokazuje przydatność konstrukcji generycznych, jest klasa System.Collections.ArrayList. ArrayList — uniwersalna, au- tomatycznie skalowana kolekcja. Może ona przechowywać zwykłe obiekty .NET albo obiekty zdefiniowane przez użytkownika. Aby było to możliwe, klasa ArrayList traktuje wszystkie elementy jak bazowy typ Object. Problem polega na tym, że nie sposób narzucić żadnych ograniczeń na działanie klasy ArrayList. Jeśli, na przykład, chcemy użyć klasy ArrayList do przechowywania kolekcji obiektów Customer, nie możemy upewnić się, że jakiś fragment kodu nie wstawi do niej łańcuchów, liczb całko- witych albo jakichś innych obiektów, co później spowoduje problemy. Z tej przyczyny programiści często tworzą własne, ściśle typizowane klasy kolekcji — w rzeczywistości biblioteka .NET jest wypełniona dziesiąt- kami takich klas. Konstrukcje generyczne rozwiązują ten problem. Za pomocą słowa klu- czowego Of można zadeklarować klasę, która działa z dowolnym typem danych: Public Class GenericList(Of ItemType) ' (tutaj kod klasy) End Class W tym przypadku tworzymy nową klasę o nazwie GenericList, która może działać z obiektami dowolnego typu. Kod kliencki musi jednak określić, jakiego typu będzie używał. W kodzie klasy odwołujemy się do tego typu za pomocą słowa ItemType. Oczywiście, ItemType nie jest na- Tworzenie klas generycznych 61
  • 21. prawdę typem — to tylko parametr zastępujący typ, który zostanie wy- brany podczas tworzenia instancji obiektu GenericList. Na listingu 2.2 pokazano kompletny kod prostej klasy listy, która kon- troluje zgodność typów. Listing 2.2. Kolekcja kontrolująca zgodność typów Public Class GenericList(Of ItemType) Inherits CollectionBase Public Function Add(ByVal value As ItemType) As Integer Return List.Add(value) End Function Public Sub Remove(ByVal value As ItemType) List.Remove(value) End Sub Public ReadOnly Property Item(ByVal index As Integer) As ItemType Get ' Odpowiedni element jest pobierany z obiektu List i jawnie ' rzutowany na odpowiedni typ, a następnie zwracany Return CType(List.Item(index), ItemType) End Get End Property End Class Klasa GenericList jest nakładką na zwykłą klasę ArrayList, która jest do- stępna za pośrednictwem właściwości List bazowej klasy CollectionBase. Klasa GenericList działa jednak inaczej niż ArrayList, ponieważ ofe- ruje ściśle typizowane metody Add() i Remove(), w których wykorzysta- no zastępczy parametr ItemType. Oto przykład użycia klasy GenericList do utworzenia kolekcji ArrayList, która obsługuje tylko łańcuchy: ' Tworzymy instancję GenericList i wybieramy typ (w tym przypadku String) Dim List As New GenericList(Of String) ' Dodajemy dwa łańcuchy List.Add("niebieski") List.Add("zielony") ' Następna instrukcja nie zadziała, ponieważ dodaje do kolekcji błędny typ. ' Nie można automatycznie przekształcić identyfikatora GUID w łańcuch. ' Prawdę mówiąc, wiersz ten nie zostanie nigdy wykonany, ponieważ kompilator ' wykryje problem i odmówi zbudowania aplikacji. List.Add(Guid.NewGuid()) 62 Rozdział 2: Język Visual Basic
  • 22. Nie ma żadnych ograniczeń, jeśli chodzi o parametryzowanie klasy. W przykładzie GenericList jest tylko jeden parametr. Można jednak ła- two utworzyć klasę, która działa z dwoma lub trzema typami obiektów i pozwala sparametryzować każdy z nich. Aby użyć tej techniki, należy oddzielić każdy typ przecinkiem (między nawiasami na początku de- klaracji klasy). Rozważmy na przykład poniższą klasę GenericHashTable, która po- zwala zdefiniować typ elementów kolekcji (ItemType), a także typ kluczy używanych do indeksowania tych elementów (KeyType): Public Class GenericHashTable(Of ItemType, KeyType) Inherits DictionaryBase ' (tutaj kod klasy) End Class Inną ważną cechą konstrukcji generycznych jest możliwość nakładania ograniczeń na parametry. Ograniczenia zawężają zakres typów obsłu- giwanych przez klasę generyczną. Przypuśćmy, że chcemy utworzyć klasę obsługującą wyłącznie typy implementujące określony interfejs. W tym celu najpierw musimy zadeklarować typ lub typy akceptowane przez klasę, a następnie użyć słowa kluczowego As, aby określić klasę bazową, z której typ musi się wywodzić, albo interfejs, który musi im- plementować. Oto przykład, który ogranicza elementy przechowywane w kolekcji Generic- List do typów serializowalnych. Byłoby to użyteczne, gdybyśmy chcieli dodać do klasy GenericList metodę wymagającą serializacji, na przy- kład taką, która zapisywałaby wszystkie elementy listy w strumieniu: Public Class SerializableList(Of ItemType As ISerializable) Inherits CollectionBase ' (tutaj kod klasy) End Class A oto kolekcja, która może zawierać obiekt dowolnego typu, pod warun- kiem że wywodzi się on z klasy System.Windows.Forms.Control. Re- zultatem jest kolekcja ograniczona do kontrolek, przypominająca tę eks- ponowaną przez właściwość Forms.Controls okna: Public Class SerializableList(Of ItemType As Control) Inherits CollectionBase ' (tutaj kod klasy) End Class Tworzenie klas generycznych 63
  • 23. Czasem klasa generyczna musi mieć możliwość tworzenia sparametry- zowanych obiektów. Na przykład w klasie GenericList konieczne może być tworzenie instancji elementu, który ma być dodany do kolekcji. W ta- kim przypadku trzeba użyć ograniczenia New. Ograniczenie New zezwala tylko na typy, które mają publiczny, bezargumentowy konstruktor i nie są oznaczone jako MustInherit. Gwarantuje to, że kod będzie mógł tworzyć instancje typu. Oto kolekcja, która narzuca ograniczenie New: Public Class GenericList(Of ItemType As New) Inherits CollectionBase ' (tutaj kod klasy) End Class Warto też zauważyć, że można definiować dowolnie wiele ograniczeń. W tym celu należy umieścić ich listę w nawiasie klamrowym, jak w po- niższym przykładzie: Public Class GenericList(Of ItemType As {ISerializable, New}) Inherits CollectionBase ' (tutaj kod klasy) End Class Konstrukcje gene- Ograniczenia są wymuszone przez kompilator, więc naruszenie ograni- ryczne są wbudowane czenia podczas korzystania z klasy generycznej uniemożliwi skompilo- w środowisko CLR. Oznacza to, że są wanie aplikacji. one obsługiwane we wszystkich językach .NET, łącznie z C#. A co… …z innymi konstrukcjami generycznymi? Typów sparametryzowanych można używać nie tylko w klasach, ale również w strukturach, interfej- sach, delegacjach, a nawet metodach. Więcej informacji jest dostępnych pod hasłem „generics” w pomocy MSDN. Przykłady użycia zaawansowa- nych konstrukcji generycznych można znaleźć w artykule przeglądowym Microsoftu pod adresem http://www.msdn.net/library/en-us/dnvs05/html/ vb2005_generics.asp. Nawiasem mówiąc, twórcy .NET Framework zdawali sobie sprawę z przy- datności kolekcji generycznych, więc utworzyli kilka gotowych kolekcji na użytek programistów. Znajdują się one w przestrzeni nazw System. Collections.Generic. Są to między innymi: • List (prosta kolekcja podobna do przykładowej klasy GenericList); 64 Rozdział 2: Język Visual Basic
  • 24. • Dictionary (kolekcja typu „nazwa-wartość”, w której każdy element jest indeksowany przy użyciu klucza); • LinkedList (połączona lista, w której każdy element wskazuje następny); • Queue (kolekcja typu „pierwszy na wejściu, pierwszy na wyjściu”); • Stack (kolekcja typu „ostatni na wejściu, pierwszy na wyjściu”); • SortedList (kolekcja typu „nazwa-wartość”, która stale pozostaje posortowana). Większość spośród tych kolekcji powiela jedną z klas w przestrzeni nazw System.Collections. Stare kolekcje pozostawiono w celu zachowania zgodności. Używanie wartości pustych Czasem konieczne jest reprezentowanie w prostych typach danych danych, które mogą być nieobecne. Umożliwiają to nowe Dzięki obsłudze konstrukcji generycznych .NET Framework może za- typy danych VB .NET. oferować kilka nowych funkcji. Jedną z nich — generyczne, ściśle typi- zowane kolekcje — opisano w poprzednim ćwiczeniu, „Tworzenie klas generycznych”. Konstrukcje generyczne rozwiązują również inne często spotykane problemy, w tym obsługę wartości pustych w prostych typach danych. Jak to zrobić? Wartość pusta (w Visual Basicu identyfikowana przez słowo kluczowe Nothing) jest specjalnym znacznikiem, który wskazuje, że dane są nie- obecne. Większość programistów zna puste referencje do obiektów, które wskazują, że obiekt zdefiniowano, ale jeszcze go nie utworzono. Na przy- kład w poniższym kodzie obiekt FileStream zawiera pustą referencję, po- nieważ nie został jeszcze utworzony za pomocą słowa kluczowego New: Dim fs As FileStream If fs Is Nothing ' Ten warunek jest zawsze spełniony, ponieważ ' nie utworzono jeszcze obiektu FileStream Console.WriteLine("Obiekt zawiera pustą referencję") End If Używanie wartości pustych w prostych typach danych 65
  • 25. Podstawowe typy danych, takie jak liczby całkowite i łańcuchy, nie mogą zawierać wartości pustych. Zmienne liczbowe są automatycznie inicjali- zowane wartością 0, zmienne logiczne — wartością False, zmienne łańcuchowe — łańcuchem pustym (""). W rzeczywistości nawet jawne ustawienie zmiennej typu prostego na Nothing spowoduje automatycz- ne przekształcenie wartości pustej (w 0, False lub ""), jak pokazuje poniższy kod: Dim j As Integer = Nothing If j = 0 Then ' Ten warunek jest zawsze spełniony, ponieważ w przypadku liczb całkowitych ' zachodzi automatyczna konwersja między wartością Nothing a 0 Console.WriteLine("Zmienna całkowita nie może zawierać wartości pustej, j = " & j) End If Czasem powoduje to problemy, ponieważ nie da się odróżnić wartości zerowej od wartości, której nigdy nie podano. Wyobraźmy sobie, że pi- szemy kod, który pobiera z pliku tekstowego liczbę zamówień złożonych przez klienta. Później badamy tę wartość. Problem występuje wtedy, gdy jest ona równa zeru. Nie możemy stwierdzić, czy dane są prawidłowe (użytkownik nie złożył żadnych zamówień), czy może brakuje nam ja- kichś informacji (nie udało się pobrać wartości albo bieżący użytkownik nie jest zarejestrowanym klientem). Dzięki obsłudze konstrukcji generycznych .NET 2.0 oferuje rozwiązanie — klasę System.Nullable, która może „owijać” dowolny typ danych. Podczas tworzenia instancji klasy Nullable określamy typ danych. Jeśli nie ustawimy wartości, instancja ta będzie zawierać pustą referencję. Możemy sprawdzić, czy tak jest w istocie, wywołując metodę Nullable. HasType(), i pobrać bazowy obiekt za pośrednictwem właściwości Nullable.Value. Oto przykładowy kod tworzący zmienną całkowitą, która może zawierać wartość pustą: Dim i As Nullable(Of Integer) If Not i.HasValue Then ' Warunek jest spełniony, ponieważ zmiennej nie przypisano wartości Console.WriteLine("Zmienna i zawiera wartość pustą") End If 66 Rozdział 2: Język Visual Basic
  • 26. ' Przypisujemy wartość. Zauważmy, że trzeba ją przypisać bezpośrednio ' zmiennej i, ' a nie i.Value. Właściwość i.Value jest przeznaczona tylko do odczytu i zawsze ' odzwierciedla bieżący obiekt, jeśli nie jest to Nothing. i = 100 If i.HasValue Then ' Warunek jest spełniony, ponieważ obecnie zmienna zawiera wartość (100) Console.WriteLine("Zmienna całkowita i = " & i.Value) End If A co… …z używaniem klasy Nullable w połączeniu z typami referencyjnymi? Choć nie jest to konieczne (ponieważ typy referencyjne mogą zawierać pustą referencję), to ma pewne zalety. Możemy używać nieco czytelniej- szej metody HasValue() zamiast testować wartość Nothing. Co najlep- sze, możemy łatwo dokonać tej zmiany, ponieważ klasa Nullable po- zwala na niejawną konwersję między Nullable a typem bazowym. Więcej informacji Aby dowiedzieć się więcej na temat klasy Nullable i jej implementacji, należy zajrzeć pod hasło „Nullable class” w pomocy MSDN. Używanie operatorów Kto ma dość posłu- giwania się toporną w połączeniu z własnymi obiektami składnią w rodzaju ObjA.Subtract(ObjB) w celu wykonania Każdy programista VB dobrze zna operatory arytmetyczne służące do prostych operacji na dodawania (+), odejmowania (-), dzielenia (/) i mnożenia (*). Zwykle własnych obiektach? Dzięki przeciążaniu operatory te są zarezerwowane dla liczbowych typów .NET i nie można operatorów można używać ich w połączeniu z innymi obiektami. Jednakże w VB .NET 2.0 manipulować takimi można budować obiekty, które obsługują wszystkie te operatory (a także obiektami równie łatwo jak zwykłymi operatory używane do operacji logicznych i niejawnej konwersji typu). liczbami. Technika ta nie ma sensu w przypadku obiektów biznesowych, ale jest niezwykle przydatna do modelowania struktur matematycznych, takich jak wektory, macierze, liczby zespolone albo — jak w poniższym przy- kładzie — ułamki. Używanie operatorów w połączeniu z własnymi obiektami 67
  • 27. Jak to zrobić? Aby przeciążyć operator w Visual Basicu 2005, trzeba utworzyć specjal- ną metodę operatorową w klasie (lub strukturze). Metodę tę deklaruje się przy użyciu słów kluczowych Public Shared Operator, po których na- stępuje symbol operatora (na przykład +). WS KAZÓWK A Przeciążanie operatora to po prostu definiowanie, co robi operator, kiedy używamy go w połączeniu z konkretnym typem obiektu. In- nymi słowy, kiedy przeciążamy operator + klasy Fraction, infor- mujemy .NET, co należy zrobić, gdy kod dodaje do siebie dwa obiekty Fraction. Oto przykładowa metoda operatorowa, która dodaje obsługę operatora dodawania (+): Public Shared Operator(ObjA As MyClass, objB As MyClass) As MyClass ' (tutaj kody klasy) End Operator Każda metoda operatorowa przyjmuje dwa parametry, które reprezen- tują wartości po obu stronach operatora. W zależności od operatora i klasy kolejność może mieć znaczenie (jak w przypadku dzielenia). Kiedy zdefiniujemy operator, kompilator VB będzie wywoływał nasz kod podczas wykonywania każdej instrukcji, która używa operatora na obiek- cie danej klasy. Na przykład kompilator przekształci kod: ObjC = ObjA + ObjB do następującej postaci: ObjC = MyClass.Operator+(ObjA, ObjB) Na listingu 2.3 pokazano, jak przeciążyć operatory arytmetyczne Visual Basica na użytek klasy Fraction. Każdy obiekt Fraction składa się z dwóch części: licznika i mianownika (tzw. „góry” i „dołu” ułamka). Kod klasy Fraction przeciąża operatory +, -, * oraz /, umożliwiając wyko- nywanie obliczeń ułamkowych bez przekształcania liczb w wartości dziesiętne, a zatem bez utraty precyzji. 68 Rozdział 2: Język Visual Basic
  • 28. Listing 2.3. Przeciążanie operatorów arytmetycznych w klasie Fraction Public Structure Fraction ' Dwie części ułamka Public Denominator As Integer Public Numerator As Integer Public Sub New(ByVal numerator As Integer, ByVal denominator As Integer) Me.Numerator = numerator Me.Denominator = denominator End Sub Public Shared Operator +(ByVal x As Fraction, ByVal y As Fraction) _ As Fraction Return Normalize(x.Numerator * y.Denominator + _ y.Numerator * x.Denominator, x.Denominator * y.Denominator) End Operator Public Shared Operator -(ByVal x As Fraction, ByVal y As Fraction) _ As Fraction Return Normalize(x.Numerator * y.Denominator - _ y.Numerator * x.Denominator, x.Denominator * y.Denominator) End Operator Public Shared Operator *(ByVal x As Fraction, ByVal y As Fraction) _ As Fraction Return Normalize(x.Numerator * y.Numerator, _ x.Denominator * y.Denominator) End Operator Public Shared Operator /(ByVal x As Fraction, ByVal y As Fraction) _ As Fraction Return Normalize(x.Numerator * y.Denominator, _ x.Denominator * y.Numerator) End Operator ' Redukcja ułamka Private Shared Function Normalize(ByVal numerator As Integer, _ ByVal denominator As Integer) As Fraction If (numerator <> 0) And (denominator <> 0) Then ' Poprawianie znaków If denominator < 0 Then denominator *= -1 numerator *= -1 End If Dim divisor As Integer = GCD(numerator, denominator) numerator = divisor denominator = divisor End If Return New Fraction(numerator, denominator) End Function Używanie operatorów w połączeniu z własnymi obiektami 69
  • 29. ' Zwracanie największego wspólnego dzielnika przy użyciu algorytmu ' Euklidesa Private Shared Function GCD(ByVal x As Integer, ByVal y As Integer) _ As Integer Dim temp As Integer x = Math.Abs(x) y = Math.Abs(y) Do While (y <> 0) temp = x Mod y x = y y = temp Loop Return x End Function ' Przekształcanie ułamka w postać dziesiętną Public Function GetDouble() As Double Return CType(Me.Numerator, Double) / _ CType(Me.Denominator, Double) End Function ' Pobieranie łańcucha reprezentującego ułamek Public Overrides Function ToString() As String Return Me.Numerator.ToString & "/" & Me.Denominator.ToString End Function End Structure Aplikacja konsoli pokazana na listingu 2.4 przeprowadza szybki test klasy Fraction. Dzięki przeciążaniu operatorów liczba pozostaje w postaci ułamkowej i nie dochodzi do utraty precyzji. Listing 2.4. Test klasy Fraction Module FractionTest Sub Main() Dim f1 As New Fraction(2, 3) Dim f2 As New Fraction(1, 4) Console.WriteLine("f1 = " & f1.ToString()) Console.WriteLine("f2 = " & f2.ToString()) Dim f3 As Fraction f3 = f1 + f2 ' f3 obecnie wynosi 11/12 Console.WriteLine("f1 + f2 = " & f3.ToString()) f3 = f1 / f2 ' f3 obecnie wynosi 8/3 Console.WriteLine("f1 / f2 = " & f3.ToString()) 70 Rozdział 2: Język Visual Basic
  • 30. f3 = f1 - f2 ' f3 obecnie wynosi 5/12 Console.WriteLine("f1 - f2 = " & f3.ToString()) f3 = f1 * f2 ' f3 obecnie wynosi 1/6 Console.WriteLine("f1 * f2 = " & f3.ToString()) Console.ReadLine() End Sub End Module Po uruchomieniu tej aplikacji pojawią się następujące wyniki: f1 = 2/3 f2 = 1/4 f1 + f2 = 11/12 f1 / f2 = 8/3 f1 - f2 = 5/12 f1 * f2 = 1/6 Parametry i wartość zwrotna metody operatorowej zwykle są tego sa- mego typu. Można jednak utworzyć kilka wersji metody operatorowej, aby używać obiektów w wyrażeniach z różnymi typami. A co… …z przeciążaniem operatorów w innych typach danych? Istnieją klasy, które są naturalnymi kandydatami do przeciążania operatorów. Oto kilka przykładów: • klasy matematyczne, które modelują wektory, macierze, liczby ze- spolone lub tensory; • klasy finansowe, które zaokrąglają obliczenia do najbliższego grosza i obsługują różne typy walut; • klasy miar, które używają jednostek nieregularnych, na przykład cali i stóp. Więcej informacji Aby dowiedzieć się więcej o składni przeciążania operatorów oraz o wszyst- kich operatorach, które można przeciążać, należy zajrzeć pod hasło in- deksu „Operator procedures” w pomocy MSDN. Używanie operatorów w połączeniu z własnymi obiektami 71
  • 31. Niektóre klasy są tak duże, że przecho- Dzielenie klasy na wiele plików wywanie ich definicji Jeśli otworzymy klasę .NET 2.0 Windows Forms, zauważymy, że nie ma w jednym pliku jest niewygodne. Za w niej automatycznie wygenerowanego kodu! Aby zrozumieć, gdzie po- pomocą nowego dział się ten kod, trzeba zapoznać się z funkcją klas częściowych, która słowa kluczowego Partial można umożliwia dzielenie klasy na kilka części. podzielić klasę na kilka oddzielnych plików. Jak to zrobić? Za pomocą słowa kluczowego Partial można podzielić klasę na dowol- ną liczbę części. Wystarczy zdefiniować tę samą klasę w więcej niż jed- nym miejscu. Oto przykład, w którym klasę SampleClass zdefiniowano w dwóch częściach: Partial Public Class SampleClass Public Sub MethodA() Console.WriteLine("Wywołano metodę A") End Sub End Class Partial Public Class SampleClass Public Sub MethodB() Console.WriteLine("Wywołano metodę B") End Sub End Class W tym przykładzie deklaracje znajdują się w tym samym pliku, jedna za drugą. Nic jednak nie stoi na przeszkodzie, aby umieścić dwie części klasy SampleClass w różnych plikach kodu źródłowego należących do tego samego projektu (jedyne ograniczenie polega na tym, że nie można zdefiniować dwóch części klasy w oddzielnych podzespołach albo róż- nych przestrzeniach nazw). Podczas kompilowania aplikacji zawierającej powyższy kod Visual Studio wyszuka każdą część SampleClass i połączy ją w kompletną klasę z dwoma metodami, MethodA() i MethodB(). Można używać obu tych metod: Dim Obj As New SampleClass() Obj.MethodA() Obj.MethodB() Klasy częściowe nie pomagają w rozwiązywaniu problemów programi- stycznych, ale przydają się do dzielenia bardzo dużych, nieporęcznych klas. Oczywiście, sama obecność dużych klas w aplikacji może świadczyć 72 Rozdział 2: Język Visual Basic
  • 32. o tym, że programista źle rozłożył problem na czynniki, a w takim przy- padku lepiej jest podzielić kod na odrębne, a nie częściowe klasy. Jednym z kluczowych zastosowań klas częściowych w .NET jest ukrywanie kodu generowanego automatycznie przez Visual Studio, który w starszych wersjach był widoczny, co przeszkadzało niektórym programistom VB. Na przykład podczas budowania formularza .NET w Visual Basicu 2005 kod obsługi zdarzeń jest umieszczany w pliku kodu źródłowego formu- larza, ale kod, który tworzy poszczególne kontrolki i łączy je z procedu- rami obsługi zdarzeń, jest niewidoczny. Aby go zobaczyć, trzeba wybrać z menu Project polecenie Show All Files. Plik z brakującą częścią klasy pojawi się wówczas w oknie Solution Explorer. Jeśli formularz nosi na- zwę Form1, to składa się na niego plik Form1.vb, który zawiera kod pisany przez programistę, oraz plik Form1.Designer.vb, który zawiera auto- matycznie wygenerowaną część. A co… …z używaniem słowa kluczowego Partial w połączeniu ze struktu- rami? To działa, ale nie można tworzyć częściowych interfejsów, wyli- czeń ani żadnych innych konstrukcji programistycznych .NET. Więcej informacji Więcej informacji o klasach częściowych można znaleźć pod hasłem in- deksu „Partial keyword” w pomocy MSDN. Rozszerzanie przestrzeni nazw My Niektórzy tak często używają obiektów Obiekty My nie są zdefiniowane w jednym miejscu. Niektóre z nich po- My, że chcieliby dostosować je do chodzą od klas zdefiniowanych w przestrzeni nazw Microsoft.Visual- własnych potrzeb. Basic.MyServices, a inne są generowane automatycznie w miarę do- VB 2005 umożliwia dołączenie własnych dawania formularzy, usług WWW, ustawień konfiguracyjnych i osa- klas do przestrzeni dzonych zasobów do projektu aplikacji. Programista może jednak roz- nazw My. szerzyć przestrzeń nazw My o własne składniki (na przykład przydatne obliczenia oraz zadania specyficzne dla aplikacji). Rozszerzanie przestrzeni nazw My 73
  • 33. Jak to zrobić? Aby dołączyć nową klasę do hierarchii obiektów My, wystarczy użyć bloku Namespace z nazwą My. Na przykład poniższy kod definiuje nową klasę BusinessFunctions, która zawiera specyficzne dla firmy funkcje prze- znaczone do generowania identyfikatorów (poprzez połączenie nazwy klienta z identyfikatorem GUID): Namespace My Public Class BusinessFunctions Public Shared Function GenerateNewCustomerID( _ ByVal name As String) As String Return name & "_" & Guid.NewGuid.ToString() End Function End Class End Namespace Po utworzeniu obiektu BusinessFunctions można używać go w aplikacji tak samo jak dowolnego innego obiektu My. Na przykład poniższa in- strukcja wyświetla nowy identyfikator klienta: Console.WriteLine(My.BusinessFunctions.GenerateNewCustomerID("matthew")) Zwróćmy uwagę, że nowe klasy My muszą używać współdzielonych metod i właściwości, ponieważ obiekty My nie są konkretyzowane automatycz- nie. Gdybyśmy użyli zwykłych składowych instancyjnych, musielibyśmy sami tworzyć obiekt My i nie moglibyśmy manipulować nim przy użyciu tej samej składni. Innym rozwiązaniem jest utworzenie modułu w prze- strzeni nazw My, ponieważ wszystkie metody i właściwości w module są współdzielone. Składowe współdzie- Można również rozszerzać niektóre spośród istniejących obiektów lone to składowe, które są zawsze My dzięki klasom częściowym. W ten sposób można na przykład do- dostępne za po- dać nowe informacje do obiektu My.Computer albo nowe procedury do średnictwem nazwy klasy, nawet jeśli obiektu My.Application. Wymaga to nieco innego podejścia. Właści- obiekt nie został wość My.Computer eksponuje instancję obiektu MyComputer. Właściwość utworzony. W razie My.Application eksponuje instancję obiektu MyApplication. Aby więc użycia zmiennej współdzielonej rozszerzyć którąś z tych klas, trzeba utworzyć klasę częściową o odpo- istnieje tylko jedna wiedniej nazwie i dodać do niej odpowiednie składowe. Należy również kopia tej zmiennej, zadeklarować tę klasę przy użyciu słowa kluczowego Friend, aby dopa- globalna dla całej aplikacji. sować ją do istniejącej klasy. 74 Rozdział 2: Język Visual Basic
  • 34. Oto przykład rozszerzania obiektu My.Application o metodę, która sprawdza, czy dostępna jest zaktualizowana wersja programu: Namespace My Partial Friend Class MyApplication Public Function IsNewVersionAvailable() As Boolean ' Zwykle numer najnowszej wersji aplikacji byłby odczytywany ' z usługi WWW albo jakiegoś innego zasobu. ' W tym przykładzie jest zakodowany "na sztywno" Dim LatestVersion As New Version(1, 2, 1, 1) Return Application.Info.Version.CompareTo(LatestVersion) End Function End Class Teraz możemy wykorzystać tę metodę: If My.Application.IsNewVersionAvailable() Console.WriteLine("Dostępna jest nowsza wersja") Else Console.WriteLine("To jest najnowsza wersja") End If A co… …z używaniem rozszerzeń My w wielu aplikacjach? Klasy My możemy traktować dokładnie tak samo, jak inne przydatne klasy, które chcemy ponownie wykorzystać w innej aplikacji. Innymi słowy, możemy utwo- rzyć projekt biblioteki klas, dodać do niego kilka rozszerzeń My i skom- pilować go do postaci biblioteki DLL. Następnie możemy odwoływać się do tej biblioteki DLL w innych aplikacjach. Oczywiście, pomimo tego, co mogliby twierdzić entuzjaści Microsoftu, taki sposób rozszerzania przestrzeni nazw My ma dwa potencjalnie nie- bezpieczne aspekty: • Trudniejsze staje się wykorzystanie komponentu w innych językach. Na przykład język C# nie obsługuje przestrzeni nazw My. Choć można używać niestandardowego obiektu My w aplikacji C#, jest to dużo mniej wygodne. • Używanie przestrzeni nazw My oznacza rezygnację z jednej spośród największych zalet przestrzeni nazw — unikania konfliktów na- zewniczych. Rozważmy na przykład dwie firmy, które tworzą kom- ponenty przeznaczone do rejestrowania zdarzeń. Gdyby firmy uży- Rozszerzanie przestrzeni nazw My 75
  • 35. wały zalecanego standardu nazewniczego przestrzeni nazw .NET (NazwaFirmy.NazwaAplikacji.NazwaKlasy), komponenty najprawdo- podobniej nie miałyby takich samych w pełni kwalifikowanych nazw; jeden mógłby nazywać się Acme.SuperLogger.Logger, a drugi — ComponentTech.LogMagic.Logger. Gdyby jednak oba komponenty roz- szerzały obiekt My, mogłyby używać takiej samej nazwy (na przy- kład My.Application.Logger). W rezultacie nie można byłoby wy- korzystać ich obu w tej samej aplikacji. Nowe słowo kluczowe Przechodzenie do następnej iteracji pętli Continue Visual Basica umożliwia szybkie Visual Basic oferuje kilka instrukcji kontroli przepływu, które pozwalają wyjście ze skom- plikowanego bloku sterować kolejnością wykonywania kodu. Można na przykład użyć słowa kodu i przejście do kluczowego Return, aby wyjść z funkcji, albo słowa Exit, aby zakończyć następnej iteracji pętli. pętlę. Jednakże przed wersją VB 2005 nie było sposobu przejścia do na- stępnej iteracji pętli. Jak to zrobić? Instrukcja Continue to jeden z tych mechanizmów językowych, które po- czątkowo wydają się mało istotne, ale z czasem okazują się bardzo przy- datne. Instrukcja Continue ma trzy wersje: Continue For, Continue Do i Continue While, których używa się z różnymi typami pętli (For ... Next, Do ... Loop oraz While ... End While). Aby zrozumieć, jak działa instrukcja Continue, przeanalizujmy poniższy kod: For i = 1 To 1000 If i Mod 5 = 0 Then ' (kod zadania A) Continue For End If ' (kod zadania B) Next Pętla ta wykonuje się 1000 razy, stopniowo zwiększając wartość liczni- ka i. Kiedy licznik i jest podzielny przez 5, wykonywany jest kod zada- nia A. Następnie instrukcja Continue For powoduje zwiększenie licznika i wznowienie wykonywania od początku pętli, z pominięciem kodu za- dania B. 76 Rozdział 2: Język Visual Basic
  • 36. W tym przykładzie instrukcja Continue nie jest właściwie potrzebna, ponieważ można łatwo przepisać kod w następujący sposób: For i = 1 To 1000 If i Mod 5 = 0 Then ' (kod zadania A) Else ' (kod zadania B) End If Next Jest to jednak znacznie trudniejsze, gdy trzeba wykonać kilka różnych testów. Aby przekonać się o zaletach instrukcji Continue, należy rozwa- żyć bardziej skomplikowany (i realistyczny) przykład. Na listingu 2.5 pokazano pętlę, która przetwarza tablicę słów. Program analizuje każde słowo i ustala, czy jest ono puste, czy też składa się z liter lub cyfr. Jeśli spełniony jest jeden z tych warunków (na przykład słowo składa się z liter), trzeba przejść do następnego słowa bez wyko- nywania następnego testu. Aby osiągnąć to bez użycia instrukcji Continue, trzeba zastosować zagnieżdżone pętle, co zmniejsza czytelność kodu. Listing 2.5. Analizowanie łańcucha bez użycia instrukcji Continue ' Definiujemy zdanie Dim Sentence As String = "Końcowy wynik obliczeń to 433." ' Przekształcamy zdanie w tablicę słów Dim Delimiters() As Char = {" ", ".", ","} Dim Words() As String = Sentence.Split(Delimiters) ' Badamy każde słowo For Each Word As String In Words ' Sprawdzamy, czy słowo jest puste If Word <> "" Then Console.Write("'" + Word + "'" & vbTab & "= ") ' Sprawdzamy, czy słowo składa się z liter Dim AllLetters As Boolean = True For Each Character As Char In Word If Not Char.IsLetter(Character) Then AllLetters = False End If Next If AllLetters Then Console.WriteLine("słowo") Else ' Jeśli słowo nie składa się z liter, ' sprawdzamy, czy składa się z cyfr Przechodzenie do następnej iteracji pętli 77
  • 37. Dim AllNumbers As Boolean = True For Each Character As Char In Word If Not Char.IsDigit(Character) Then AllNumbers = False End If Next If AllNumbers Then Console.WriteLine("liczba") Else ' Jeśli słowo nie składa się z samych liter albo cyfr, ' zakładamy, że zawiera ich kombinację (albo inne znaki) Console.WriteLine("mieszane") End If End If End If Next Teraz rozważmy wersję z listingu 2.6, w której użyto instrukcji Continue, aby działanie programu było bardziej zrozumiałe. Listing 2.6. Analizowanie łańcucha przy użyciu instrukcji Continue ' Definiujemy zdanie Dim Sentence As String = "Końcowy wynik obliczeń to 433." ' Przekształcamy zdanie w tablicę słów Dim Delimiters() As Char = {" ", ".", ","} Dim Words() As String = Sentence.Split(Delimiters) ' Badamy każde słowo For Each Word As String In Words ' Sprawdzamy, czy słowo jest puste If Word = "" Then Continue For Console.Write("'" + Word + "'" & vbTab & "= ") ' Sprawdzamy, czy słowo składa się z liter Dim AllLetters As Boolean = True For Each Character As Char In Word If Not Char.IsLetter(Character) Then AllLetters = False End If Next If AllLetters Then Console.WriteLine("słowo") Continue For End If ' Jeśli słowo nie składa się z liter, ' sprawdzamy, czy składa się z cyfr Dim AllNumbers As Boolean = True For Each Character As Char In Word If Not Char.IsDigit(Character) Then AllNumbers = False End If 78 Rozdział 2: Język Visual Basic
  • 38. Next If AllNumbers Then Console.WriteLine("liczba") Continue For End If ' Jeśli słowo nie składa się z samych liter albo cyfr, ' zakładamy, że zawiera ich kombinację (albo inne znaki) Console.WriteLine("mieszane") Next A co… …z użyciem instrukcji Continue w zagnieżdżonej pętli? Jest to możliwe. Jeśli zagnieździmy pętlę For w pętli Do, będziemy mogli użyć instrukcji Continue For, aby przejść do następnej iteracji wewnętrznej pętli, albo instrukcji Continue Do, aby przejść do następnej iteracji zewnętrznej pętli. Technika ta działa także w odwrotnej sytuacji (pętla Do wewnątrz pętli For), ale nie w przypadku dwóch zagnieżdżonych pętli tego samego typu. W takiej sytuacji nie da się jednoznacznie odwołać do zewnętrznej pętli, więc instrukcja Continue zawsze dotyczy pętli wewnętrznej. Więcej informacji Szczegółowe informacje o instrukcji Continue można znaleźć pod ha- słem indeksu „continue statement” w pomocy MSDN. Automatyczne usuwanie obiektów Jak uniknąć pozostawiania W środowisku .NET trzeba zwracać szczególną uwagę na to, aby obiekty w pamięci obiektów, które zajmują zasoby używające niezarządzanych zasobów (na przykład uchwytów plików, aż do momentu, połączeń z bazami danych i kontekstów graficznych) zwalniały je na- w którym wyszuka tychmiast, kiedy będzie to możliwe. Obiekty tego typu powinny imple- je „odśmiecacz”? Dzięki instrukcji mentować interfejs IDisposable i udostępniać metodę Dispose(), którą Using można upewnić można wywołać w celu natychmiastowego zwolnienia zasobów. się, że obiekty zostaną usunięte Jedyny problem z tą techniką polega na tym, że trzeba pamiętać o wy- we właściwym wołaniu metody Dispose() (albo innej metody wywołującej Dispose(), momencie. na przykład Close()). VB 2005 oferuje nowe zabezpieczenie, które gwa- rantuje wywołanie metody Dispose() — instrukcję Using. Automatyczne usuwanie obiektów 79
  • 39. Jak to zrobić? Instrukcji Using używa się w strukturze bloku. W pierwszym wierszu bloku Using należy określić usuwalny obiekt. Często w tym samym momencie tworzy się obiekt za pomocą słowa kluczowego New. Następ- nie w bloku Using należy napisać kod, który używa usuwalnego obiektu. Oto krótki fragment kodu, który tworzy nowy plik i zapisuje w nim dane: Using NewFile As New System.IO.StreamWriter("c:MojPlik.txt") NewFile.WriteLine("To jest wiersz 1") NewFile.WriteLine("To jest wiersz 2") End Using ' Plik jest zamykany automatycznie ' Obiekt NewFile w tym miejscu jest już niedostępny W tym przykładzie natychmiast po opuszczeniu bloku Using wywoły- wana jest metoda Dispose() obiektu NewFile, co powoduje zwolnienie uchwytu pliku. A co… …z błędami występującymi w bloku Using? Na szczęście .NET zwalnia zasób bez względu na sposób wyjścia z bloku Using, nawet w przypadku nieobsłużonego wyjątku. Instrukcji Using można używać w połączeniu ze wszystkimi usuwalnymi obiektami, na przykład: • plikami (w tym FileStream, StreamReader i StreamWriter); • połączeniami z bazą danych (w tym SqlConnection, OracleConnection i OleDbConnection); • połączeniami sieciowymi (w tym TcpClient, UdpClient, NetworkStream, FtpWebResponse, HttpWebResponse); • grafiką (w tym Image, Bitmap, Metafile, Graphics). Więcej informacji Szczegółowe informacje o instrukcji Using można znaleźć pod hasłem indeksu „Using block” w pomocy MSDN. 80 Rozdział 2: Język Visual Basic
  • 40. W przeszłości nie Ochrona właściwości dało się utworzyć właściwości, przy użyciu różnych poziomów dostępu która mogła być odczytywana Większość właściwości zawiera procedurę Get (która umożliwia pobie- przez każdego, ranie wartości właściwości) oraz procedurę Set (która umożliwia okre- ale aktualizowana tylko przez aplikację. ślenie nowej wartości właściwości). W poprzednich wersjach Visual Ba- VB 2005 wreszcie sica poziom dostępu do obu procedur musiał być jednakowy. W VB 2005 poluzowuje reguły można zabezpieczyć właściwość, przypisując procedurze Set niższy po- i oferuje większą elastyczność. ziom dostępu niż procedurze Get. Jak to zrobić? VB rozróżnia trzy poziomy dostępu. W kolejności od najmniej do najbar- dziej ograniczonego są to: • Public (element dostępny dla wszystkich klas we wszystkich podze- społach); • Friend (element dostępny dla wszystkich klas w bieżącym podzespole); • Private (element dostępny tylko dla kodu w tej samej klasie). Wyobraźmy sobie, że tworzymy komponent DLL, który będzie używany przez inną aplikację. Zawiera on właściwość Status, która będzie od- czytywana przez aplikację kliencką, więc deklarujemy ją jako publiczną: Public Class ComponentClass Private _Status As Integer Public Property Status() As Integer Get Return _Status End Get Set(ByVal value As Integer) _Status = value End Set End Property End Class Problem w tym, że poziom dostępu przypisany właściwości Status po- zwala klientowi na jej zmianę, co nie ma sensu. Właściwość Status mogłaby być przeznaczona tylko do odczytu (w tym celu należałoby po- minąć procedurę Set), ale wtedy nie mogłyby jej zmieniać inne klasy, które stanowią część aplikacji i znajdują się w tym samym podzespole. Ochrona właściwości przy użyciu różnych poziomów dostępu 81
  • 41. Rozwiązaniem jest przypisanie procedurze Set poziomu dostępu Friend. Oto, jak powinien wyglądać kod (jedyną zmianę wyróżniono pogrubioną czcionką): Public Property Status() As Integer Get Return _Status End Get Friend Set(ByVal value As Integer) _Status = value End Set End Property A co… …z właściwościami przeznaczonymi tylko do odczytu lub tylko do zapisu? Różne poziomy dostępu nie pomogą, jeśli potrzebna jest właściwość przeznaczona tylko do odczytu (na przykład wartość obliczana) albo tyl- ko do zapisu (na przykład hasło, które po ustawieniu nie powinno pozo- stawać dostępne). W celu utworzenia właściwości przeznaczonej tylko do odczytu należy dodać słowo kluczowe ReadOnly do deklaracji właści- wości (tuż po słowie kluczowym określającym poziom dostępu) i usunąć procedurę Set. W celu utworzenia właściwości przeznaczonej tylko do zapisu należy usunąć procedurę Get i dodać słowo kluczowe WriteOnly. Te słowa kluczowe nie są niczym nowym — były dostępne już w Visual Basicu .NET 1.0. Nowe operatory logiczne umożliwiają Testowanie kolejnych części łączenie wielu warun- ków i pisanie bardziej wyrażenia warunkowego zwartego kodu. W poprzednich wersjach Visual Basica istniały dwa operatory logiczne: And i Or. W Visual Basicu 2005 wprowadzono dwa dodatkowe operatory: AndAlso oraz OrElse. Działają one tak samo jak And i Or, ale pozwalają oszacować tylko jedną część długiego wyrażenia warunkowego. Jak to zrobić? W wielu programach trzeba oszacować kilka warunków z rzędu. Często najpierw sprawdzamy, czy obiekt nie jest pusty, a następnie badamy jedną z jego właściwości. 82 Rozdział 2: Język Visual Basic
  • 42. W tym celu musimy używać zagnieżdżonych bloków If, jak w poniż- szym przykładzie: If Not MyObject Is Nothing Then If MyObject.Value > 10 Then ' (robimy coś) End If End If Byłoby miło połączyć te dwa warunki w jednym wierszu: If Not MyObject Is Nothing And MyObject.Value > 10 Then ' (robimy coś) End If Niestety, to nie zadziała, ponieważ VB zawsze testuje oba warunki. In- nymi słowy, nawet jeśli MyObject jest równy Nothing, VB sprawdzi drugi warunek i spróbuje pobrać właściwość MyObject.Value, co spo- woduje wyjątek NullReferenceException. W Visual Basicu 2005 rozwiązano ten problem dzięki słowom kluczo- wym AndAlso i OrElse. Kiedy używamy tych operatorów, Visual Basic nie testuje drugiego warunku, jeśli pierwszy nie jest spełniony. Oto po- prawiony kod: If Not MyObject Is Nothing AndAlso MyObject.Value > 10 Then ' (robimy coś) End If A co… …z innymi ulepszeniami języka? W tym rozdziale przedstawiono naj- ważniejsze innowacje w języku VB. Warto jednak wspomnieć o kilku innych nowościach, które nie zostały tu opisane: • Słowo kluczowe IsNot pozwala uprościć niezgrabną składnię. Dzięki niemu można zastąpić konstrukcję If Not x Is Nothing równo- ważną instrukcją If x IsNot Nothing. • Za pomocą funkcji TryCast() można nieco przyspieszyć rzutowanie typów. Działa ona tak jak funkcje CType() lub DirectCast(), z jednym wyjątkiem — jeśli obiektu nie można przekształcić w żądany typ, zwracana jest pusta referencja. Zamiast więc sprawdzać typ obiektu, a potem go rzutować, można od razu użyć funkcji TryCast(), a na- stępnie sprawdzić, czy zwróciła ona rzeczywistą referencję do obiektu. Testowanie kolejnych części wyrażenia warunkowego 83
  • 43. • Zmienne całkowite bez znaku umożliwiają przechowywanie wartości, które nie mogą być ujemne. Ograniczenie to oszczędza pamięć, po- zwalając na przechowywanie większych liczb. Liczby bez znaku zaw- sze były obsługiwane przez .NET Framework, ale obecnie VB 2005 zawiera odpowiednie słowa kluczowe (UInteger, ULong i UShort). 84 Rozdział 2: Język Visual Basic