Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00101 009737 11027983 na godz. na dobę w sumie
Visual Basic 2005. Zapiski programisty - książka
Visual Basic 2005. Zapiski programisty - książka
Autor: Liczba stron: 304
Wydawca: Helion Język publikacji: polski
ISBN: 83-246-0087-6 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> visual basic - programowanie
Porównaj ceny (książka, ebook, audiobook).

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, w które wyposażono zarówno najnowszą wersję Visual Basica, jak i środowisko programistyczne Visual Studio 2005, pozwalają znacznie przyspieszyć pisanie kodu. Jednocześnie został zachowany dostęp do wszystkich możliwości platformy .NET.

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 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 generycznych czy korzystanie z obiektów My. Godne odnotowania jest także znaczne przyspieszenie i udoskonalenie technologii ASP.NET.

Dzięki tej książce najnowsza wersja Visual Basica odsłania swoje tajemnice.

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

IDZ DO IDZ DO PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ SPIS TREŒCI SPIS TREŒCI KATALOG KSI¥¯EK KATALOG KSI¥¯EK KATALOG ONLINE KATALOG ONLINE ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG TWÓJ KOSZYK TWÓJ KOSZYK DODAJ DO KOSZYKA DODAJ DO KOSZYKA CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE ZAMÓW INFORMACJE O NOWOŒCIACH O NOWOŒCIACH ZAMÓW CENNIK ZAMÓW CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl Visual Basic 2005. Zapiski programisty Autor: Matthew MacDonald T³umaczenie: Grzegorz Werner ISBN: 83-246-0087-6 Tytu³ orygina³u: Visual Basic 2005: A Developers Notebook Format: B5, stron: 304 Przyk³ady na ftp: 1986 kB 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, w które wyposa¿ono zarówno najnowsz¹ wersjê Visual Basica, jak i œrodowisko programistyczne Visual Studio 2005, pozwalaj¹ znacznie przyspieszyæ pisanie kodu. Jednoczeœnie zosta³ zachowany dostêp do wszystkich mo¿liwoœci platformy .NET. 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 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 generycznych czy korzystanie z obiektów My. Godne odnotowania jest tak¿e znaczne przyspieszenie i udoskonalenie technologii ASP.NET. (cid:129) Edycja kodu w Visual Studio 2005 (cid:129) Tworzenie dokumentacji w formacie XML (cid:129) Korzystanie z obiektów My (cid:129) Definiowanie klas generycznych (cid:129) Tworzenie aplikacji dla œrodowiska Windows oraz aplikacji WWW (cid:129) Projektowanie formularzy (cid:129) Komunikacja z bazami danych (cid:129) Wdra¿anie aplikacji za pomoc¹ technologii ClickOnce Dziêki tej ksi¹¿ce najnowsza wersja Visual Basica ods³ania swoje tajemnice. 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: (cid:22) Wykonywanie popularnych zadań za pomocą obiektów My (cid:22) Uzyskiwanie informacji o aplikacji (cid:22) Używanie ściśle typizowanych zasobów (cid:22) Używanie ściśle typizowanych ustawień konfiguracyjnych (cid:22) Tworzenie klas generycznych (cid:22) Używanie wartości pustych w prostych typach danych (cid:22) Używanie operatorów w połączeniu z własnymi obiektami (cid:22) Dzielenie klasy na wiele plików (cid:22) Rozszerzanie przestrzeni nazw My (cid:22) Przechodzenie do następnej iteracji pętli (cid:22) 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. Jak to zrobić? Istnieje siedem podstawowych obiektów My. Spośród nich trzy kluczowe obiekty centralizują zestaw funkcji .NET Framework i dostarczają in- formacji o komputerze. Są to: My.Computer Ten obiekt zawiera informacje o komputerze, w tym o jego połącze- niu sieciowym, stanie myszy i klawiatury, bieżącym katalogu, dru- 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. Przedzieranie się przez obszerną bibliotekę klas .NET w poszukiwaniu potrzebnej funkcji bywa męczące. Dzięki nowym obiektom My można szybko znaleźć najprzydatniejsze funkcje oferowane przez .NET. 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. OSTRZEŻ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. (cid:166)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.07Testin MATTHEW 50 Rozdział 2: Język Visual Basic OSTRZEŻ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 można pobrać informacje o bieżącej wersji aplikacji, jej położeniu oraz parametrach użytych do jej uruchomienia. Uzyskiwanie informacji o aplikacji Obiekt My.Application udostępnia wiele przydatnych informacji. W celu ich pobrania wystarczy odczytać właściwości obiektu. Jak to zrobić? 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 WSKAZÓWKA 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 ) Assembly: AssemblyDescription( Program testujący obiekt My.Application ) Assembly: AssemblyCopyright( (C) Matthew MacDonald ) Assembly: AssemblyTrademark( (R) Prosetech ) Assembly: AssemblyTitle( Aplikacja testowa ) Assembly: AssemblyProduct( Aplikacja testowa ) Wszystkie te informacje zostaną osadzone w skompilowanym podze- spole jako metadane. Teraz można uruchomić testową aplikację. Oto przykładowe wyniki: Parametry wiersza polecenia: /a /b /c Firma: Prosetech Opis: Program testujący obiekt My.Application Lokalizacja: C:NotatnikVB2InformacjeOAplikacjiinDebug Nowością w VB 2005 jest możliwość dodawania info- rmacji o aplikacji w specjalnym oknie dialogowym. Aby skorzystać z tej funkcji, należy kliknąć dwukrotnie ikonę My Project w oknie Solution Explorer, przejść na zakładkę Application i kliknąć przycisk 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ą osadzanie statycz- nych danych (na przykład obrazów) w skompilowanych podzespołach i zapewniają łatwy dostęp do tych danych z poziomu kodu. Używanie ściśle typizowanych zasobów Podzespoły .NET oprócz kodu mogą zawierać zasoby — osadzone dane binarne, na przykład obrazy i niezmienne łańcuchy. Choć środowisko .NET obsługuje zasoby już od wersji 1.0, Visual Studio nie oferowało ich zintegrowanej obsługi w czasie projektowania aplikacji. W rezultacie programiści, którzy chcieli zapisać dane obrazu w swojej aplikacji, zwy- 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 (jak pokazano na rysunku 2.2). Korzystanie z zasobów jest bardzo łatwe. Wszystkie zasoby są kompilo- wane dynamicznie w ściśle typizowaną klasę zasobów, do której można uzyskać dostęp poprzez obiekt My.Resources. Aby wypróbować nowo dodany zasób, należy dodać kontrolkę PictureBox do formularza Win- dows (i zachować domyślną nazwę PictureBox1). Następnie należy dodać poniższy kod, który wyświetli obraz podczas wczytywania formularza: Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load PictureBox1.Image = My.Resources.EmbeddedGraphic End Sub Klasa zasobów jest dodawana do węzła My Project i otrzymuje nazwę Resources.Designer.vb. Aby ją zobaczyć, trzeba wybrać z menu Project polecenie Show All Files. Oczywiście, nie należy modyfikować tego pliku ręcznie. Używanie ściśle typizowanych zasobów 55 Inną zaletą zasobów jest to, że można wykorzystać te same obrazy w wielu kontrolkach na różnych formula- rzach bez dodawania wielu kopii obrazu do jednego pliku. 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). Kiedy dodajemy zasoby w taki sposób, Visual Studio kopiuje je do pod- katalogu Resources aplikacji. Katalog ten, wraz z zawartymi w nim za- sobami, można obejrzeć w oknie Solution Explorer. Podczas kompilowania aplikacji wszystkie zasoby są osadzane w podzespole, ale przechowy- wanie ich w oddzielnym katalogu ma pewną ważną zaletę — pozwala zaktualizować zasób przez zamianę pliku i ponowne skompilowanie apli- 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 Tworzenie ustawień konfiguracyjnych w oknie projektu aplikacji. 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 ustawień konfiguracyjnych 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 ustawienia konfigura- cyjne są umieszczane w pliku web.config. W innych aplikacjach ustawienia są umieszczane w pliku noszącym tę samą nazwę co aplikacja i uzupełnioną rozszerzeniem .config, na przykład MojaAplikacja. (cid:166)exe.config. W Visual Studio 2005 sytuacja wygląda znacznie lepiej. Aby dodać nowe ustawienie konfiguracyjne, 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ę Settings, która pokazuje listę niestandar- dowych ustawień konfiguracyjnych i umożliwia zdefiniowanie nowych ustawień oraz ich wartości. Aby dodać do aplikacji nowe ustawienie konfiguracyjne, należy wpisać jego nazwę na dole listy. Następnie należy określić typ danych, zasięg 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 Klasa ustawień konfiguracyjnych jest dodawana do węzła My Project i nosi nazwę Settings.Designer. Aby ją obejrzeć, należy wybrać z menu Project polecenie Show All Files. /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. Można używać innych serializowalnych typów danych, w tym liczb cał- kowitych i dziesiętnych, dat i czasów (wystarczy wybrać odpowiedni typ z listy rozwijanej Type). Wartości te są przekształcane w tekst podczas zapisu w pliku konfiguracyjnym, ale można je pobrać za pośrednictwem obiektu My.Settings w odpowiednim formacie, bez analizy składniowej! A co… …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 (cid:166)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ę na tyle elastyczną, aby mogła działać z dowolnym typem obiektu, a jednocze- śnie w każdej sytuacji móc ograniczać przyjmowane przez nią obiekty? Rozwiązaniem są konstrukcje gene- ryczne języka VB. Tworzenie klas generycznych Programiści często stają przed trudnym wyborem. Z jednej strony, bar- dzo ważne jest tworzenie rozwiązań uniwersalnych, które można wielo- krotnie wykorzystywać w różnych sytuacjach. Dlaczego na przykład mielibyśmy tworzyć klasę CustomerCollection, która przyjmuje tylko obiekty typu Customer, skoro możemy zaprojektować klasę Collection zapewniającą dostęp do obiektów dowolnego typu? Z drugiej strony kwe- stie wydajności i typizacji sprawiają, że rozwiązania uniwersalne są 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 Ograniczenia są wymuszone przez kompilator, więc naruszenie ograni- czenia podczas korzystania z klasy generycznej uniemożliwi skompilo- wanie aplikacji. 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. (cid:166)Collections.Generic. Są to między innymi: • List (prosta kolekcja podobna do przykładowej klasy GenericList); Konstrukcje gene- ryczne są wbudowane w środowisko CLR. Oznacza to, że są one obsługiwane we wszystkich językach .NET, łącznie z C#. 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 w prostych typach danych Dzięki obsłudze konstrukcji generycznych .NET Framework może za- 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 Czasem konieczne jest reprezentowanie danych, które mogą być nieobecne. Umożliwiają to nowe typy danych VB .NET. 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. (cid:166)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 w połączeniu z własnymi obiektami Każdy programista VB dobrze zna operatory arytmetyczne służące do dodawania (+), odejmowania (-), dzielenia (/) i mnożenia (*). Zwykle operatory te są zarezerwowane dla liczbowych typów .NET i nie można używać ich w połączeniu z innymi obiektami. Jednakże w VB .NET 2.0 można budować obiekty, które obsługują wszystkie te operatory (a także operatory używane do operacji logicznych i niejawnej konwersji typu). 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. Kto ma dość posłu- giwania się toporną składnią w rodzaju ObjA.Subtract(ObjB) w celu wykonania prostych operacji na własnych obiektach? Dzięki przeciążaniu operatorów można manipulować takimi obiektami równie łatwo jak zwykłymi liczbami. 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 +). WSKAZÓWKA 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- wywanie ich definicji w jednym pliku jest niewygodne. Za pomocą nowego słowa kluczowego Partial można podzielić klasę na kilka oddzielnych plików. Dzielenie klasy na wiele plików Jeśli otworzymy klasę .NET 2.0 Windows Forms, zauważymy, że nie ma w niej automatycznie wygenerowanego kodu! Aby zrozumieć, gdzie po- dział się ten kod, trzeba zapoznać się z funkcją klas częściowych, która umożliwia dzielenie klasy na kilka części. 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 Obiekty My nie są zdefiniowane w jednym miejscu. Niektóre z nich po- chodzą od klas zdefiniowanych w przestrzeni nazw Microsoft.Visual- Basic.MyServices, a inne są generowane automatycznie w miarę do- dawania formularzy, usług WWW, ustawień konfiguracyjnych i osa- dzonych zasobów do projektu aplikacji. Programista może jednak roz- szerzyć przestrzeń nazw My o własne składniki (na przykład przydatne obliczenia oraz zadania specyficzne dla aplikacji). Niektórzy tak często używają obiektów My, że chcieliby dostosować je do własnych potrzeb. VB 2005 umożliwia dołączenie własnych klas do przestrzeni nazw My. 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. Można również rozszerzać niektóre spośród istniejących obiektów My dzięki klasom częściowym. W ten sposób można na przykład do- dać nowe informacje do obiektu My.Computer albo nowe procedury do obiektu My.Application. Wymaga to nieco innego podejścia. Właści- wość My.Computer eksponuje instancję obiektu MyComputer. Właściwość My.Application eksponuje instancję obiektu MyApplication. Aby więc rozszerzyć którąś z tych klas, trzeba utworzyć klasę częściową o odpo- wiedniej nazwie i dodać do niej odpowiednie składowe. Należy również zadeklarować tę klasę przy użyciu słowa kluczowego Friend, aby dopa- sować ją do istniejącej klasy. Składowe współdzie- lone to składowe, które są zawsze dostępne za po- średnictwem nazwy klasy, nawet jeśli obiekt nie został utworzony. W razie użycia zmiennej współdzielonej istnieje tylko jedna kopia tej zmiennej, globalna dla całej aplikacji. 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
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Visual Basic 2005. Zapiski programisty
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: