→ Slide 1

Obsługa wyjątków

→ Slide 2

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
→ Slide 3

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; 
→ Slide 4

Wyjątki

Źródło: Learn Coding from Experts

→ Slide 5

Ł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
}
→ Slide 6

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ą.");
}
→ Slide 7

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ą.");
}
→ Slide 8

Kto łapie wyjątki?

→ Slide 9

Hierarchia wyjątków

→ Slide 10

Przykład: Exception

try
{
    int wynik = Convert.ToInt32("Ala ma kota");
}
catch(Exception e)
{
    Console.WriteLine($"Złapałem wyjątek {e}");
}
→ Slide 11

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 
}
→ Slide 12

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
→ Slide 13

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;
→ Slide 14

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");
}
→ Slide 15

Ć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:

  1. ustaw wartości początkowe $x_0=1, i=0, \epsilon=0.0000001$
  2. oblicz $x_{i+1}$
  3. jeśli $|x_{i+1} - x_i | < \epsilon$ to zwróć pierwiastek równy $x_{i+1}$
  4. zwiększ $i=i+1$ i wróć do pkt. 2