Edytuj stronę Odnośniki Fold/unfold all ODT export Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić. ~~NOCACHE~~ ~~REVEAL theme=simple&disableLayout=0&transition=none&controls=1&show_progress_bar=1&build_all_lists=0&show_image_borders=0&horizontal_slide_level=2&enlarge_vertical_slide_headers=0&show_slide_details=1&open_in_new_window=1&size=1024x768~~ <html> <style type="text/css"> p { text-align: left;} .reveal pre code { height: 100%; max-height: 100%; box-sizing: border-box; } </style> </html> ====== Obsługa wyjątków ====== ===== Typ pusty ===== Typy wartościowe mają wersję typu umożliwiającą przypisanie wartości ''null''. Deklaracja: typ? nazwa = null; Przykład: <code C#> int? a = null; int? b = 42; double? x = null; bool? czy_prawda = null; //int k = null; // ta deklaracja nie jest dozwolona </code> ===== Operator ?? ===== Operator ''??'' ułatwia obsługę sytuacji, gdy zmienna posiada wartość ''null''. W takiej sytuacji ''??'' zwraca wartość podaną po prawej stronie. <code C#> int? x = null; int y = x ?? 42; string linia = Console.ReadLine() ?? ""; </code> Równoważnie <code C#> if (x == null) y = 42; </code> ===== Wyjątki ===== {{https://i2.wp.com/masterdotnet.com/wp-content/uploads/2020/11/Exception-Code-Snippet.png?600|}} Źródło: [[https://masterdotnet.com/csharptutorial/exception-in-csharp/|Learn Coding from Experts]] ===== ===== * Wyjątki - odpowiedź na nieoczekiwane zdarzenia w trakcie wykonywania programu, np. dzielenie przez zero, niepoprawne rzutowanie. * Wystąpienie wyjątku przerywa działanie programu * Rzucony wyjątek możemy "złapać" zabezpieczając wrażliwy fragment kodu instrukcją ''try'' ''catch'' * Informacje o wyjątkach rzucanych z metody opisane są w dokumentacji \\ Przykład: [[https://learn.microsoft.com/en-us/dotnet/api/system.convert.toint32?view=net-6.0#system-convert-toint32(system-string)|Convert.ToInt32()]] * Rzucanie wyjątków, instrukcja ''throw'' * Predefiniowane wyjątki ''System.Exception'' ===== Łapanie wyjątków ===== Składnia <code C#> try { // blok kodu, w którym spodziewamy się wyjątku } catch(TypWyjątku ex) { // obsługa wyjątku konkretnego typu } </code> ===== Przykład ===== <code C#> string napis = Console.ReadLine(); int wynik = 0; try { wynik = Convert.ToInt32(napis); Console.WriteLine($"Zamieniam '{napis}' na wartość typu int {wynik}."); } catch (FormatException) { Console.WriteLine($"'{napis}' nie jest liczbą całkowitą."); } </code> ===== Przykład ===== <code C#> string napis = Console.ReadLine(); int wynik = 0; try { wynik = Convert.ToInt32(napis); Console.WriteLine($"Zamieniam napis '{napis}' na wartość typu int {wynik}."); } catch (OverflowException) { Console.WriteLine($"{napis} jest poza zakresem typu int"); } catch (FormatException) { Console.WriteLine($"Napis '{napis}' nie jest liczbą całkowitą."); } </code> ===== Kto łapie wyjątki? ===== {{zajecia:cs:exceptions.png?600|}} ===== Hierarchia wyjątków ===== * Wyjątki zorganizowane są w hierarchię * Każdy wyjątek jest typu ''System.Exception'' (najogólniejszy) {{zajecia:cs:exceptions_hierarchy.png?600|}} ===== Przykład: Exception ===== <code C#> try { int wynik = Convert.ToInt32("Ala ma kota"); } catch(Exception e) { Console.WriteLine($"Złapałem wyjątek {e}"); } </code> ===== Try catch finally ====== Sekcja ''finally'' jest uruchamiana na końcu sekcji ''try/catch'', wykorzystywana jest do zwalniania zasobów zarezerwowanych w instrukcji ''try'' (np. zamknięcie pliku) <code C#> try { // blok kodu, w którym spodziewamy się wyjątku } catch(TypWyjątku ex) { // obsługa wyjątku konkretnego typu } finally { // Kod uruchamiany ZAWSZE, niezależnie od tego, czy wystąpił wyjątek } </code> ===== Typowe wyjątki ===== ^ Typ ^ Opis ^ | ''ArithmeticException'' | błędna operacja arytmetyczna (dzielenie przez 0, nadmiar) | | ''DivideByZeroException'' | dzielenie przez zero | | ''OverflowException'' | nadmiar, przekroczenie zakresu typu | ===== ===== | ''ArrayTypeMismatchException'' | niepoprawny typ elementu tablicy | | ''IndexOutOfRangeException'' | indeks poza zakresem tablicy | | ''InvalidCastException'' | niepoprawne rzutowania | | ''NullReferenceException'' | odwołanie do wartości ''null'' zamiast do obiektu | | ''OutOfMemoryException'' | brak pamięci (niepowodzenie operacji ''new'') | ===== ===== | ''ArgumentException'' | niepoprawny argument metody | | ''StackOverflowException'' | przepełnienie stosu (np. nieskończona rekurencja) | | ''IO.IOException'' | błąd obsługi wejścia/wyjścia (pliki) | | ''IO.FileNotFoundException'' | próba dostępu do nieistniejącego pliku | ===== Rzucanie wyjątków ===== W sytuacjach wyjątkowych rzucamy wyjątek odpowiedniego typu <code C#> throw new Exception("Komunikat wyjątku"); </code> <code C#> if(x == 0) throw new DivideByZeroException(); int y=1 / x; </code> ===== TryParse ===== Niektóre metody komunikują wystąpienie błedu zwracając odpowiednia wartość <code C#> int x; string s = Console.ReadLine(); if (int.TryParse(s, out int wartość)) { x = wartość; } else { Console.WriteLine("Błąd formatowania"); } </code> ===== Ćwiczenie ===== Napisz metodę wyznaczającą pierwiastek kwadratowy $\sqrt{a}$ liczby rzeczywistej za pomocą algorytmu Herona. W przypadku niepoprawnego argumentu $a<0$ metoda rzuca wyjątek ''ArgumentException'' z odpowiednim komunikatem. Napisz program, który wczyta z konsoli liczbę i wyznaczy jej pierwiastek kwadratowy. Obsłuż wszystkie sytuacje wyjątkowe (niepoprawny format liczby, zły argument metody pierwiastkującej). ===== ===== Przybliżenie pierwiastka liczby $a$ wyznaczamy wzorem iteracyjnym $$x_{i+1} =\frac{1}{2} \left( x_i + \frac{a}{x_i}\right)$$ Algorytm: - ustaw wartości początkowe $x_0=1, i=0, \epsilon=0.0000001$ - oblicz $x_{i+1}$ - jeśli $|x_{i+1} - x_i | < \epsilon$ to zwróć pierwiastek równy $x_{i+1}$ - zwiększ $i=i+1$ i wróć do pkt. 2