~~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~~
====== 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:
int? a = null;
int? b = 42;
double? x = null;
bool? czy_prawda = null;
//int k = null; // ta deklaracja nie jest dozwolona
===== Operator ?? =====
Operator ''??'' ułatwia obsługę sytuacji, gdy zmienna posiada wartość ''null''. W takiej sytuacji ''??'' zwraca wartość podaną po prawej stronie.
int? x = null;
int y = x ?? 42;
string linia = Console.ReadLine() ?? "";
Równoważnie
if (x == null) y = 42;
===== 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
try
{
// blok kodu, w którym spodziewamy się wyjątku
}
catch(TypWyjątku ex)
{
// obsługa wyjątku konkretnego typu
}
===== Przykład =====
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ą.");
}
===== Przykład =====
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ą.");
}
===== 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 =====
try
{
int wynik = Convert.ToInt32("Ala ma kota");
}
catch(Exception e)
{
Console.WriteLine($"Złapałem wyjątek {e}");
}
===== 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)
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
}
===== 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
throw new Exception("Komunikat wyjątku");
if(x == 0) throw new DivideByZeroException();
int y=1 / x;
===== TryParse =====
Niektóre metody komunikują wystąpienie błedu zwracając odpowiednia wartość
int x;
string s = Console.ReadLine();
if (int.TryParse(s, out int wartość))
{
x = wartość;
}
else
{
Console.WriteLine("Błąd formatowania");
}
===== Ć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