W języku C# wyjątki (exceptions) to mechanizm obsługi błędów, który pozwala reagować na nieoczekiwane sytuacje w czasie wykonywania programu.
Opisz jakie zadanie pełnią następujące słówka kluczowe w języku c#:
try -
catch -
finally -
Które z tych bloków możemy pominąć? Które są wymagane?
Jeśli musimy wywołać fragment kodu po wystąpieniu wyjątku aby np. przywrócić hermetycznosć klasy ale nie chcemy przechwytywać wyjątku, z jakich bloków skorzystamy? Podaj przkład kodu.
Większość wyjątków w C# dziedziczy po klasie Exception. Wyjątki wystemowe dziedziczą po SystemException. Aby zgłosić wyjątek w trakcie działania programu używamy słówka throw, następnie tworzymy obiekt wyjątku który chcemy zwrócić.
Znajdź klasy odpowiadające za zgłaszanie następujących oraz podaj przykłady kodu kiedy dany wyjątek występuje:
Nieprawidłowy argument metody -
Przekazano null, ale wymagano wartości -
Wartość argumentu poza zakresem -
Operacja niewłaściwa dla bieżącego stanu obiektu -
Odwołanie do obiektu, który ma wartość null -
Przekroczenie zakresu tablicy -
Dzielenie przez zero -
Błędy we/wy, np. brak dostępu do pliku -
Plik nie został znaleziony -
Brak uprawnień do operacji -
Przepełnienie stosu -
Dzielenie przez zero -
Dzielenie przez zero -
Dzielenie przez zero -
Kiedy standardowe wyjątki (np. ArgumentException, InvalidOperationException) nie pasują do sytuacji, kiedy chcemy przekazać dodatkowe dane w wyjątku, gdy chcemy zachować jednolity sposób obsługi błędów w aplikacji c# umożliwia tworzenie własnych wyjątków.
Aby stworzyć własny wyjątek w C#, należy utworzyć klasę, która dziedziczy po Exception lub jednej z jej pochodnych (np. ApplicationException).
public class MyCustomException : Exception
{
public MyCustomException() { }
public MyCustomException(string message) : base(message) { }
public MyCustomException(string message, Exception innerException) : base(message, innerException) { }
}
Zainicjalizuj blok
tryw którym wyrzucisz wyjątek. Następnie w bloku catch spróbuj wypisać co zawierają poszczeólne właściwości wyrzuconego obiektu. Następnie opisz co przechowują poszczególne właściwości.
Message -
StackTrace -
InnerException -
try
{
try
{
throw new ArgumentNullException("parametr", "Parametr nie może być null.");
}
catch (ArgumentNullException ex)
{
throw new InvalidOperationException("Błąd w operacji biznesowej.", ex);
}
}
catch (Exception ex)
{
Console.WriteLine("=== Ścieżka błędu ===");
Exception currentEx = ex;
while (currentEx != null)
{
Console.WriteLine($"Wyjątek: {currentEx.GetType()} - {currentEx.Message}");
currentEx = currentEx.InnerException;
}
}
Source -
HResult -
Podobnie jak poprzednio utwórz kod który zawsze wyrzuca wyjątek a w bloku obsługującym go wywołaj poniższe metody. Następnie sporządź opis co robią podane metody.
ToString() -
GetType() -
GetBaseException() -
Equals(object obj) -
GetHashCode() -
Jeśli dany fragment programu może zwrócić różne wyjątki możliwe jest wielokrotne użycie bloku catch aby przechwycić różne typy wyjątków:
try
{
int[] numbers = new int[3];
Console.WriteLine(numbers[5]); // IndexOutOfRangeException
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine($"Błąd indeksu: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Inny błąd: {ex.Message}");
}
Jeśli chcemy obsłużyć wyjątków w ten sam sposób/w jednym bloku od C# 8.0 jest to możliwe w poniższy sposób:
catch (ArgumentException or FormatException ex)
{
Console.WriteLine("Błąd argumentu lub formatu.");
}
Wyjątki możemy również filtrować - np. obsługiwać dany wyjątek jeśli wiadomosć zawiera podany teskt. Używając słowa kluczowego when, możemy dodać dodatkowe warunki, które muszą być spełnione, aby dany wyjątek został obsłużony.
catch (Exception ex) when (ex.Message.Contains("specjalny"))
{
Console.WriteLine("Złapano wyjątek zawierający 'specjalny'.");
}
W C# checked i unchecked kontrolują przepełnienie arytmetyczne dla operacji na liczbach całkowitych (int, long, short, byte, itp.). Przepełnienie występuje, gdy wynik operacji przekracza zakres typu danych. Przykład dla int (-2 147 483 648 do 2 147 483 647). Domyślnie dla operacji arytmetycznych wykorzystywane jest unchecked.
checked – Włącza sprawdzanie przepełnienia
unchecked – Wyłącza sprawdzanie przepełnienia
checked
{
int max = int.MaxValue;
int result = max + 1; // Powoduje wyjątek OverflowException
}
unchecked
{
int max = int.MaxValue;
int result = max + 1; // Brak wyjątku! Wynik: -2147483648
}
Napisz program, który prosi użytkownika o wprowadzenie dwóch liczb całkowitych. Następnie program wykonuje dzielenie jednej liczby przez drugą i wyświetla wynik. Jakie wyjątki mogą wystapić w czasie działania programu? Obsłuż wystepujące wyjątki wyświetlając stosowne komunikaty w konsoli oraz dajac użytkownikowi mozliwość poprawy błędów.
-Jeśli użytkownik poda 0 jako dzielnik, program wyświetli komunikat o błędzie.
-Jeśli użytkownik wprowadzi coś, co nie jest liczbą całkowitą, program wyświetli komunikat o błędzie.
Stwórz własny wyjątek
NegativeNumberException, który będzie rzucany, gdy użytkownik poda liczbę ujemną.InvalidEmailException, który będzie wyrzucany gdy wpisany email jest prawidłowy.InvalidPhoneNumberException, który będzie rzucany gdy numer telefonu nie jest w formacie 000-000-000 lub innym prawidłowym. Program powinien demonstrować obsługę stworoznych wyjątków, przypadki brzegowe gdy dane wyjątki wystepują.
Dana jest metoda symująca działanie żądań http zwracająca wyjątki HttpRequestException:
public static HttpResponseMessage SimulateHttpRequest(string url) { if (url == "/moved") { // Zwraca kod 301 - Moved Permanently (przekierowanie) throw new HttpRequestException("301 - Moved Permanently"); } else if (url == "/notfound") { // Zwraca kod 404 - Not Found (nie znaleziono zasobu) throw new HttpRequestException("404 - Not Found"); } else if (url == "/ok") { // Zwraca kod 200 - OK (żądanie udane) return new HttpResponseMessage(System.Net.HttpStatusCode.OK); } else { // Zwraca kod 500 - Internal Server Error (błąd serwera) throw new HttpRequestException("500 - Internal Server Error"); } }Zasymuluj zapytania pod odpowiednie endpointy oraz obsłuż wyjątki (301, 404, 500) w zależności od kodu błędu: 301 wyświetl w konsoli - Błąd: Przekierowanie (301) - Zasób został przeniesiony. 404 wyświetl w konsoli - Błąd: Zasób nie znaleziony (404). 500 wyświetl w konsoli - Błąd: Błąd serwera (500). Proszę spróbować ponownie później.
Wykorzystaj słówko kluczowe when.