Waldemar Bartyna 1 Programowanie zaawansowane Strukturalna obsługa wyjątków
Waldemar Bartyna Pytania egzaminacyjne (Zestaw01) 1.Co to jest takiego ta cała platforma.NET? 2.Jakie są jej najważniejsze cechy? 3.Jakie elementy składają się na platformę.NET? 4.Co to jest CLR? 5.Co to jest CTS? 6.Co to jest CLS? 7.Co to jest CIL? 8.Co to jest CLI? 2
Waldemar Bartyna Pytania egzaminacyjne (Zestaw02) 9.Co to są pakiety? 10.Co to są typy i co do nich zaliczamy? 11.Jaka jest zależność między pakietami, przestrzeniami nazw i typami? 12.W jaki sposób wykonywane są programy na platformie.NET? 3
Waldemar Bartyna Pytania egzaminacyjne (Zestaw03) 13.Na czym polega OOP i jakie są jego trzy podstawowe filary? 14.Na czym polega dziedziczenie? 15.Do czego wykorzystujemy słowa kluczowe protected, base, sealed? 16.Na czym polega agregacja? 17.Na czym polega zagnieżdżanie? 18.Na czym polega delegacja? 4
Waldemar Bartyna Pytania egzaminacyjne (Zestaw04) 19.Na czym polega polimorfizm? 20.Co to są abstrakcyjne klasy bazowe? 21.Co to jest interfejs polimorficzny? 22.Na czym polega nadpisywanie i zasłanianie składowych? 5
Waldemar Bartyna B. z M. 1 6
Waldemar Bartyna B. z M. 2 7
Waldemar Bartyna B. z M. 3 8
Waldemar Bartyna B. z M. 4 9
Waldemar Bartyna B. z M. 5 10
Waldemar Bartyna B. z M. 6 11
Waldemar Bartyna B. z M. 7 12
Waldemar Bartyna B. z M. 8 13
Waldemar Bartyna Ciekawostek 14
Waldemar Bartyna Strukturalna obsługa wyjątków 1.Główna klasa nadrzędna 2.Strukturalna obsługa wyjątków 15
Waldemar Bartyna 16 Główna klasa nadrzędna System.Object
Waldemar Bartyna Zagadka Co jest klasą nadrzędną naszej klasy bazowej Car, Employee, Shape? 17 W świecie.NET każda klasa jest pochodną (bezpośrednio lub pośrednio) klasy bazowej System. Object.
Waldemar Bartyna Główna klasa nadrzędna Klasa Object definiuje zbiór składowych wspólny dla wszystkich języków platformy.NET Jeżeli definiujemy klasę nie podając jawnie jej klasy bazowej, kompilator automatycznie traktuje ją jako pochodną klasy Object. Możemy to sami jawnie zapisać podczas definiowania klasy 18
Waldemar Bartyna Definicja klasy Object 19
Waldemar Bartyna Metoda wirtualna Equals() Domyślnie, metoda ta zwraca wartość true tylko wtedy, gdy porównywane elementy odnoszą się do tego samego miejsca w pamięci Oznacza to, że służy ona do porównywania referencji, a nie stanów obiektów. Z reguły jest przesłaniana tak, że zwraca true wtedy, gdy porównywane obiekty mają takie same wewnętrzne wartości stanu (semantyka na bazie wartości). Gdy przesłaniamy tę metodę, należy również przesłonić metodę GetHashCode() (obie te metody są używane wewnętrznie przez typ Hashtable podczas pobierania obiektów z kolekcji. 20
Waldemar Bartyna Składowe klasy System.Object GetHashCode() – zwraca wartość typu int, która identyfikuje daną instancję klasy Object GetType() – zwraca obiekt klasy Type, który szczegółowo opisuje wskazany obiekt. Jest to metoda identyfikacji typów w czasie wykonania dostępna dla wszystkich obiektów (Runtime Type Identification – RTTI). Finalize() – metoda ta jest wywoływana w celu zwolnienia wszystkich zaalokowanych zasobów przed zniszczeniem obiektu. 21
Waldemar Bartyna Składowe klasy System.Object (c. d.) ToString() – zwraca wartość typu string reprezentującą dany obiekt. o Reprezentacja ta ma format. (nazywany ją pełną nazwą kwalifikowaną – ang. fully qualified name). o Metoda ta może być (i często jest) przesłaniana przez klasy pochodne, które za jej pomocą zwracają łańcuch znaków zawierający opis wewnętrznego stanu obiektu (najczęściej w postaci par: nazwa pola, wartość). MemberwiseClone() – metoda ta zwraca klon obiektu (kopiowana jest każda jego skłądowa). 22
Waldemar Bartyna Wywołanie metod domyślnych 23
Waldemar Bartyna Wynik wywołania 24 Domyślna implementacja metody ToString() zwraca pełną nazwę kwalifikowaną. Każdy projekt w C# definiuje główną przestrzeń nazw o domyślnej nazwie identycznej z nazwą projektu. W niej umieszczona została klasa Person. Domyślne zachowanie metody Equals() polega na sprawdzeniu, czy podane zmienne wskazują na tą samą instancję klasy (na to samo miejsce w pamięci).
Waldemar Bartyna Dodanie pól danych Uzupełniamy naszą przykładową klasę o pola reprezentujące jej stan wewnętrzny 25
Waldemar Bartyna Nadpisanie System.Object.Tostring() Wiele klas nadpisuje metodę ToString(); ułatwia to testowanie aplikacji i nie tylko Metodę tą można implementować w dowolny sposób, ale przyjęty standard to oddzielanie nazwy pola i jego wartości dwukropkiem oraz zamknięcie opisu w nawiasy kwadratowe. 26
Waldemar Bartyna Nadpisanie System.Object.Tostring() (c. d.) Należy pamiętać, że właściwa implementacja metody ToString() powinna uwzględniać wszystkie dane zdefiniowane w łańcuchu dziedziczenia. Gdy nadpisujemy metodę ToString() dla klasy rozszerzającej niestandardową klasę bazową, pierwszym krokiem powinno być pozyskanie wyniku działania metody ToString() z klasy nadrzędnej. Kolejnym krokiem jest dodanie opisu informacji specyficznych dla klasy pochodnej. 27
Waldemar Bartyna Nadpisanie System.Object.Equals() 28 Sposób porównania obiektów ma bazować na porównaniu ich wewnętrznych stanów.
Waldemar Bartyna Nadpisanie System.Object.Equals() 2 29 W tej implementacji, metoda Equals() zwraca wartość true tylko wtedy, gdy dwa porównywane obiekty zawierają te same wartości stanu (a nie wskazują na ten sam obiekt w pamięci). Ponieważ argumentem metody Equals() jest obiekt ogólnej klasy System.Object, pierwszym krokiem jest upewnienie się, czy przekazano obiekt odpowiedniej klasy. Należy również sprawdzić, czy przesłany parametr nie ma wartości null.
Waldemar Bartyna Nadpisanie System.Object.Equals() 3 Zaimplementowana w ten sposób metoda Equals() będzie działać poprawnie. W przypadku klasy Person mieliśmy jednak tylko kilka pól prostych typów składających się na stan obiektu. W przypadku bardziej złożonych klas, częstym skrótem stosowanym w implementacji metody Equals() jest wykorzystywanie metody ToString() (ale tylko pod warunkiem, że została ona dobrze napisana –uwzględnia wartości wszystkich pól) 30
Waldemar Bartyna Nadpisanie System.Object.GetHashCode() Kod hash to wartość liczbowa reprezentująca określony stan obiektu. Na przykład, dwa obiekty typu string zawierające napis „Hello”, mają ten sam kod hash. Jeżeli jeden z tych napisów będzie składał się tylko z małych liter („hello”), wartości kodu hash będą różne. Domyślnie, metoda GetHashCode() generuje kod na podstawie aktualnej lokalizacji danego obiektu w pamięci operacyjnej. Jeżeli tworzymy typ z myślą o umieszczaniu go w kolekcji Hashtable, musimy przesłonić zarówno metodę Equals(), jak i GetHashCode(), ponieważ obie te metody są wykorzystywane przez Hasztable w momencie pobierania obiektu. 31
Waldemar Bartyna NadpisanieSystem.Object.GetHashCode() 2 Jest wiele sposobów tworzenia kodu hash. W większości przypadków można go wygenerować dla definiowanej klasy poprzez wykorzystanie metody GetHashCode() klasy System.String. Jednym ze sposobów jest zidentyfikowanie unikalnego pola i wywołanie dla nim metody GetHashCode(). Jeżeli takiego pola nie mamy, a nadpisaliśmy metodę ToString(), możemy to wykorzystać do wygenerowania kodu hash dla obiektów naszej klasy. 32
Waldemar Bartyna Testowanie zmodyfikowanej klasy Person 33
Waldemar Bartyna Wynik działania programu 34
Waldemar Bartyna Statyczne składowe klasy System.Object Oprócz metod instancyjnych klasa System.Object definiuje również dwie metody statyczne Equals(Object o1, Object o2) do porównywania stanów obiektów, ReferenceEquals(Object o1, Object o2) do porównywania referencji. 35
Waldemar Bartyna 36/24 Strukturalna obsługa wyjątków
Waldemar Bartyna Rodzaje problemów Błędy programisty (ang. bugs): są rezultatem pomyłki twórcy aplikacji. Przykładem może być zezwolenie na przekroczenie indeksu w tablicy. Błędy użytkownika: mogą się pojawiać w pojedynczym uruchomieniu aplikacji, a nie w każdym (tak jak ma to miejsce w przypadku błędów programisty). Tradycyjnym przykładem jest wpisanie przez użytkownika danych niewłaściwego typu (napis zamiast liczby) lub podanie danych w niewłaściwym formacie. 37
Waldemar Bartyna Rodzaje problemów (c. d.) Wyjątki: są z reguły postrzegane jako anomalie w czasie wykonania, które są trudne (albo których wręcz nie można) przewidzieć w czasie tworzenia aplikacji. Można do nich zaliczyć: Próbę połączenia się z bazą danych, która już nie istnieje, Otwieranie uszkodzonego pliku, Próba nawiązania łączności z komputerem, aktualnie nie podłączonym do sieci, Itp. 38
Waldemar Bartyna Obsługa wyjątków w.NET Sam termin obsługa wyjątków może nam się kojarzyć jedynie z obsługą problemów w czasie wykonania. Na platformie.NET, silnik CLR często generuje odpowiedni wyjątek, który pozwala na identyfikację aktualnego problemu również w przypadku błędów programisty i użytkownika. W poprzednich architekturach (np. COM), z problemami radzono sobie poprzez stosowanie różnych technik, które często były specyficzne dla danego języka, a nawet projektu..NET wprowadza standardowy sposób obsługi błędów identyczny dla wszystkich języków platformy 39
Waldemar Bartyna Zalety strukturalnej obsług wyjątków Jednakowe podejście do obsługi błędów, wspólne dla wszystkich języków Jednakowa składnia używana do wyrzucania i przechwytywania wyjątków we wszystkich językach W miejsce kodowania wyjątku w postaci mało mówiącej liczby, zostały wprowadzone wyjątki jako obiekty niosące ze sobą wiele przydatnych, czytelnych dla człowieka, informacji (jak również stan stosu, pomocnicze linki, i kilka innych) 40
Waldemar Bartyna Elementy obsługi wyjątków Programowanie oparte na strukturalnej obsłudze wyjątków wiąże się z wykorzystaniem czterech elementów: Klasy, która reprezentuje szczegółowe informacje o wyjątku Składowej, która wyrzuca instancję odpowiedniej klasy wyjątku do wywołującego, Bloku kodu po stronie wywołującego, w którym korzysta z mogącej wyrzucić wyjątek składowej, Bloku kodu po stronie wywołującego, który przechwyci i obsłuży zgłoszony wyjątek. 41
Waldemar Bartyna Słowa kluczowe Język C# posiada cztery słowa kluczowe związane z obsługą wyjątków: try, catch, throw, finally. Typem, który reprezentuje pojawiające się błędy jest klasa dziedzicząca po klasie System.Exception lub po jej pochodnych. 42
Waldemar Bartyna Klasa bazowa System.Excepiton 43
Waldemar Bartyna Cechy klasy System.Excepiton Wiele z właściwości jest zadeklarowana jako tylko do odczytu. Wynika to z tego, że typowym postępowaniem podczas tworzenia klasy pochodnej jest nadawanie tym właściwościom wartości domyślnych, które się później nie zmieniają. Klasa System.Exception implementuje dwa interfejsy: ISerializable pozwala na utrwalanie lub przekazywanie danych obiektów na zewnątrz programu, _Exception dzięki niemu wyjątki platformy.NET mogą być przetwarzane przez niezarządzany kod, takie jak aplikacje COM. 44
Waldemar Bartyna Główne składowe klasy System.Exception Data – Właściwość ta pobiera kolekcję par klucz/wartość (reprezentowaną przez obiekt implementujący interfejs IDictionary), która dostarcza dodatkowe, zdefiniowane przez programistę, informacje o błędzie. Domyślnie jest ona pusta. HelpLink – Właściwość ta zwraca adres URL do pliku z pomocą lub do strony internetowej szczegółowo opisującej dany błąd. 45
Waldemar Bartyna Główne składowe klasy System.Exception 2 InnerException – Ta właściwość tylko do odczytu może być używana do zdobycia informacji o wyjątkach, które wystąpiły podczas obsługi danego wyjątku. Wyjątki te są zapisywane poprzez przekazywanie ich jako argumentu konstruktora. Message – Ta właściwość tylko do odczytu zwraca tekstowy opis danego błędu. Jest ona ustawiana poprzez podanie jej jako argumentu konstruktora. Source – Właściwość ta zwraca nazwę pakietu, który dany wyjątek wyrzucił (zgłosił). 46
Waldemar Bartyna Główne składowe klasy System.Exception 3 StackTrace – Ta właściwość tylko do odczytu zawiera łańcuch znaków identyfikujący sekwencję wywołań, która spowodowała dany wyjątek. Jest ona bardzo pomocna przy debugowaniu kodu lub zapisywaniu informacji o błędzie do dziennika. TargetSite – Ta właściwość tylko do odczytu zwraca typ MethodBase, który zawiera wiele szczegółów dotyczących metody, która dany wyjątek wyrzuciła (wywołanie metody ToString() wyświetli nazwę metody). 47
Waldemar Bartyna Prosty przykład Klasa Radio 48
Waldemar Bartyna Prosty przykład 2 49 Klasa Car
Waldemar Bartyna Prosty przykład 3 50 Klasa Car (c. d.)
Waldemar Bartyna Przykładowe wywołanie 51
Waldemar Bartyna Wyrzucanie wyjątku 52
Waldemar Bartyna Wyrzucanie wyjątku 2 Wyjątek jest zgłaszany wywołującemu daną metodę za pomocą słowa kluczowego throw. W konstruktorze obiektu (wyjątku) podawana jest wiadomość o rodzaju błędu (Message). Ważnymi kwestiami projektowymi jest ustalenie: Jakie wydarzenie powinno powodować zgłoszenie wyjątku,? Kiedy (w którym miejscu kodu) powinien on być wyrzucony?. Wyjątki powinny być wyrzucane w sytuacjach awaryjnych, z których dana metoda nie może automatycznie się „podnieść”, np. nieistniejący plik o wskazanej nazwie. 53
Waldemar Bartyna Przechwytywanie wyjątku 54
Waldemar Bartyna Przechwytywanie wyjątku 2 55
Waldemar Bartyna Przechwytywanie wyjątku 3 W przypadku wywołania metody, która może wyrzucić wyjątek korzystamy z bloku try/catch. Z przechwyconego obiektu wyjątku możemy pobrać szczegółowe informacje o błędzie za pomocą odpowiednich właściwości. Blok try jest sekcją kodu, w którym może nastąpić wyrzucenie wyjątku. Jeżeli wyjątek zostanie wykryty, sterowanie zostaje przeniesione do odpowiedniego bloku catch. Z drugiej strony, jeżeli w bloku try nie wystąpił żaden wyjątek, blok catch zostaje w całości pominięty. Po obsłużeniu wyjątku sterowanie wraca do aplikacji do punktu zaraz po bloku catch. 56
Waldemar Bartyna Konfigurowanie stanu wyjątka Obecnie, nasz obiekt klasy System.Exception wyrzucany przez metodę Accelerate() przekazuje nam tylko informacje poprzez właściwość Message (przekazywaną jako parametr konstruktora). Dodatkowe składowe klasy Exception mogą być użyte do dalszego, bardziej szczegółowego opisania samego błędu i powodu jego powstania. Te składowe to: TargetSite, StackTrace, HelpLink, Data. 57
Waldemar Bartyna Właściwość TargetSite Właściwość System.Exception.TargetSite pozwala na ustalenie wielu szczegółów o metodzie, która wyrzuciła dany wyjątek. Wyświetlenie tej właściwości poprzez metodę ToString() pokaże nam zwracany typ, nazwę metody oraz typy jej parametrów. Wartość zwracana przez właściwość TargetSite jest typu System.Reflection.MethodBase. Zawiera on informacje nie tylko o samej metodzie, ale np. również o typie, w którym został zdefiniowany. DeclaringTyp – mówi nam, o typie, w jakim dana metoda została zadeklarowana, MemberType – mówi nam, składową jakiego typu jest dany element wyrzucający wyjątek. 58
Waldemar Bartyna Właściwość TargetSite 2 59
Waldemar Bartyna Właściwość TargetSite 3 60
Waldemar Bartyna Właściwość StackTrace Właściwość System.Exception.StackTrace umożliwia zidentyfikowanie serii wywołań, które doprowadziły do wyrzucenia wyjątku Najniższy wpis odpowiada pierwszemu wywołaniu w sekwencji prowadzącej do powstania wyjątku Idąc w górę, możemy prześledzić kolejne wywołania, aż do metody, która dany wyjątek wyrzuciła. 61
Waldemar Bartyna Właściwość HelpLink Właściwość TargetSite i StackTrace są pomocne dla programisty w debugowaniu kodu, ale mało mówią użytkownikowi aplikacji Właściwość Message może stanowić czytelny przekaż dla użytkownika końcowego aplikacji. Dodatkowo, właściwość HelperLink może wskazywać odpowiedni URL lub standardowy plik pomocy systemu Windows, który dokładnie opisuję błąd. Domyślnie, właściwość ta jest pusta. Jeżeli chcemy ją ustawić, musimy to zrobić jeszcze przed wyrzuceniem wyjątku. 62
Waldemar Bartyna Właściwość HelpLink 2 63 Dodajemy odpowiednią linie w bloku catch Odpowiednia modyfikacja metody Accelerate()
Waldemar Bartyna Właściwość Data Właściwość System.Exception.Data pozwala na dodanie do obiektu dodatkowych informacji o błędzie w postaci par klucz/wartość. Właściwość ta zwraca obiekt implementujący interfejs IDictionary zdefiniowany w przestrzeni nazw System.Collections. Przestrzeń tą musimy dodać po stronie wywołującego, jeżeli chcemy korzystać z typu DictionaryEntry (a chcemy). 64
Waldemar Bartyna Właściwość Data 2 Odpowiednio modyfikujemy metodę Accelerate() i tworzenie wyjątku 65
Waldemar Bartyna Właściwość Data 3 Odpowiednio modyfikujemy metodę main i przechwycenie wyjątku 66
Waldemar Bartyna Właściwość Data 4 67
Waldemar Bartyna Właściwość Data 5 Właściwość ta pozwala na przekazywanie wywołującemu większej ilości informacji bez konieczności tworzenia własnej klasy dziedziczącej po klasie Exception. Z drugiej strony tworzenie takich klas może być wygodniejsze, jeżeli wolimy przechwycić konkretny typ wyjątku (klasy), a nie „łapać” ogólną klasę i próbować znaleźć odpowiednie informacje we właściwości Data 68
Waldemar Bartyna Wyjątki systemowe Biblioteka klas bazowych platformy.NET definiuje wiele klas (wyjątków) dziedziczących po klasie System.Exception, np.: ArgumentOutOfRangeException IndexOutOfRangeException, StackOverflowException itp. Wyjątki wyrzucane przez platformę.NET nazywamy wyjątkami systemowymi. Wyjątki systemowe dziedziczą po klasie System.SystemException, która dopiero dziedziczy po klasie System. Exception Jak sprawdzić, czy klasa NullReferenceException jest wyjątkiem systemowym? 69
Waldemar Bartyna Wyjątki aplikacji W odróżnieniu od wyjątków systemowych wyrzucanych przez klasy bazowej biblioteki lub silnik uruchomieniowy platformy.NET, wyjątki aplikacji definiowane są w ramach i wyrzucane na poziomie tworzonej aplikacji. Przy ich definiowaniu, dobrym zwyczajem jest dziedziczenie klasy System.ApplicationException, a nie bezpośrednio klasy System.Exception. Tak jak w przypadku wyjątków systemowych dziedziczenie po dodatkowej pośredniej klasie ma znaczenie prawie wyłącznie informacyjne (rozróżnienie wyjątków systemowych i aplikacyjnych). 70
Waldemar Bartyna Tworzenie niestandardowych wyjątków Chociaż zawsze można wyrzucić wyjątek w postaci klasy Exception, a dodatkowe informacje przesłać za pomocą właściwości Data, w niektórych przypadkach może okazać się wygodniejsze zdefiniowanie właśnej klasy. Dobrą praktyką jest kończenie nazw klas będących wyjątkami słowem „Exception”. Regułą jest również nadawanie modyfikatora public tworzonym klasom (wyjątkom). Powodem jest to, że mogą one być wyrzucane na zewnątrz pakietu, a zatem wywołujący odpowiednią metodę musi mieć dostęp do klasy wyjątku. 71
Waldemar Bartyna Tworzenie niestandardowych wyjątków 2 72 Definiujemy klasę CarIsDeadException
Waldemar Bartyna Tworzenie niestandardowych wyjątków 3 73 Definiujemy klasę CarIsDeadException (c. d.)
Waldemar Bartyna Tworzenie niestandardowych wyjątków 4 74 Odpowiednio modyfikujemy funkcję wyrzucającą wyjątek
Waldemar Bartyna Tworzenie niestandardowych wyjątków 5 75 Zmieniamy nazwę klasy wyjątku, który spodziewamy się przechwycić
Waldemar Bartyna Lepsze wyjątki Niestandardową klasę wyjątku definiujemy w przypadku, gdy błędy, które będą przez nie reprezentowane ściśle dotyczą dziedziny aplikacji, a nie ogólnych problemów. Zdefiniowana przez nas klasa dotyczy zachowania samochodu, a nie, np., przekroczenia indeksu w tablicy. W poprzedniej wersji klasy przeesłonilismy właściwość Message. Nie musimy tego robić. Wystarczy skorzystać z konstruktora klasy bazowej. Tym samym staje się niepotrzebne pole przechowujące wartość wiadomości. W większości przypadków, tworzenie klasy reprezentującej wyjątki związane z dziedziną aplikacji, sprowadzało się będzie do wprowadzenia klasy wyjątku o odpowiedniej, nowej nazwie. 76
Waldemar Bartyna Lepsze wyjątki 2 77
Waldemar Bartyna Wyjątki zgodne z dobrą praktyką.NET Jeżeli chcemy zdefiniować klasę wyjątku zgodną z dobrą praktyką.NET, należy: Dziedziczyć po klasie Exception/ApplicationException, Oznaczyć ją atrybutem [System.Serializable], Zdefiniować konstruktor domyślny, Zdefiniować konstruktor ustawiający właściwość Message, Zdefiniować konstruktor obsługujący wyjątki wewnętrzne, Zdefiniować konstruktor obsługujący serializację danego typu. 78
Waldemar Bartyna Wyjątki zgodne z dobrą praktyką.NET 2 79 Wersja uwzględniająca wszystkie wymagane elementy
Waldemar Bartyna Korzystajmy z udogodnień środowiska! Skoro znane są zasady tworzenia wyjątków zgodnych z dobrą praktykę, to powinny istnieć narzędzia do wspomagania ich tworzenia. I oczywiście istnieją! Z menu kontekstowego wybieramy Insert snippet … Następnie wybieramy Visual C# Z listy dostępnych „gotowców” wybieramy exception. Nadajemy nazwę klasie wyjątku, ewentualnie zmieniamy klasę bazową. Uzupełniamy definicję klasy o dodatkowe dane i właściwości. Voilà ! 80
Waldemar Bartyna Przetwarzanie wielu wyjątków Zmodyfikujmy odpowiednio metodę Accelaerate() dodając wyrzucanie jeszcze jednego wyjątku. 81
Waldemar Bartyna Przetwarzanie wielu wyjątków 2 Teraz będziemy przechwytywać dwa typy wyjątków 82
Waldemar Bartyna Przetwarzanie wielu wyjątków 3 83
Waldemar Bartyna Przetwarzanie wielu wyjątków 4 Sposób przechwycenie wielu wyjątków pokazany na poprzednim slajdzie spowoduje błąd w czasie kompilacji. Powodem jest to, że pierwszy w kolejności blok catch przechwytuje najbardziej ogólny wyjątek, czyniąc kolejne bloki nieosiągalnymi. Bloki catch należy definiować w kolejności od najbardziej specjalizowanych do najbardziej ogólnych. Kolejny slajd pokazuje prawidłowe uszeregowanie bloków catch. 84
Waldemar Bartyna Przetwarzanie wielu wyjątków 5 85
Waldemar Bartyna Ogólny blok catch Nie pozwala na uzyskanie danych o błędzie, tylko ogólnie o fakcie wystąpienia błędu. Przydatne, jeżeli wprowadzamy obsługę błędów na bardzo ogólnym poziomie. 86
Waldemar Bartyna Przerzucanie wyjątku Przerzucanie obsługi wyjątku do wyższego poziomu aplikacji ma sens, jeżeli wiemy, że będzie on w stanie poprawnie go obsłużyć, a sami tego nie możemy zrobić. Użycie słowa throw bez parametrów powoduje przerzucenie wyjątku w nienaruszonej postaci. 87
Waldemar Bartyna Wyjątki wewnętrzne W przypadku wystąpienia wyjątku podczas obsługi wyjątku (czyli w bloku catch), powinniśmy udokumentować jego wystąpienia. Czynimy to poprzez utworzenie i zgłoszenie oryginalnego wyjątku, przekazując jako drugi parametr konstruktora (czyli ustawiając właściwość InnerException) obiekt wewnętrznego wyjątku. Podejście takie ma sens, jeżeli odbiorca będzie potrafił obsłużyć taki wyjątek 88
Waldemar Bartyna Blok finally Blokowi try/catch może również towarzyszyć opcjonalny blok finally. Blok finally jest wywoływany zawsze, nie zależnie czy wystąpił wyjątek czy nie. Stanowi najwłaściwsze miejsce do porządnego „posprzątania”: Pozbycie się niepotrzebnych obiektów, Zamknięcie plików, Rozłączenie się z bazą danych. 89
Waldemar Bartyna Blok finally 2 90
Waldemar Bartyna Kilka uwag Platforma.NET (w przeciwieństwie do Javy) nie obsługuje sprawdzanych wyjątków, co oznacza, że obsługa wyjątków jest całkowicie opcjonalna (kompilator jej nie wymusza). Aby sprawdzić, jakie wyjątki są wyrzucane przez daną metodę, można sięgnąć do dokumentacji platformy.NET lub skorzystać z opisu metody pojawiającego się po najechaniu kursorem myszy na nazwę tej metody. Nie obsłużone wyjątki wyświetlane są przy pomocy odpowiedniego okna dialogowego w czasie wykonania programu. Możemy się w nim zapoznać ze wszystkimi omówionymi składowymi wyjątków. 91
Waldemar Bartyna Pytania egzaminacyjne (Zestaw05) 23.Czym charakteryzuje się klasa System.Object? 24.Na czym polega obsługa wyjątków? 25.Jakie są bloki i słowa kluczowe związane z obsługą wyjątków? 26.Jak realizujemy przechwytywanie wielu wyjątków? 92
Waldemar Bartyna 93 Dziękuję za uwagę