Exception
jest typem podstawowym dla wszystkich wyjątków i jako taki jest strasznie niespecyficzny. Nie powinieneś nigdy zgłaszać tego wyjątku, ponieważ po prostu nie zawiera on żadnych przydatnych informacji. Wywołanie kodu przechwytującego wyjątki nie może odróżnić celowo rzuconego wyjątku (z Twojej logiki) od innych wyjątków systemowych, które są całkowicie niepożądane i wskazują rzeczywiste błędy.
Ten sam powód dotyczy również SystemException
. Jeśli spojrzysz na listę typów pochodnych, zobaczysz ogromną liczbę innych wyjątków o bardzo różnej semantyce.
NullReferenceException
i IndexOutOfRangeException
są innego rodzaju. Teraz są to bardzo specyficzne wyjątki, więc ich wyrzucenie może być w porządku. Jednak nadal nie będziesz chciał ich wyrzucać, ponieważ zwykle oznaczają one, że w twojej logice są pewne błędy. Na przykład wyjątek odwołania zerowego oznacza, że próbujesz uzyskać dostęp do elementu członkowskiego obiektu, którym jest null
. Jeśli taka możliwość występuje w Twoim kodzie, zawsze powinieneś jawnie sprawdzić null
i zamiast tego zgłosić bardziej przydatny wyjątek (na przykład ArgumentNullException
). Podobnie IndexOutOfRangeException
s pojawiają się, gdy uzyskujesz dostęp do nieprawidłowego indeksu (na tablicach - nie na listach). Powinieneś zawsze się upewnić, że nie robisz tego w pierwszej kolejności i najpierw sprawdź granice np. Tablicy.
Istnieje kilka innych wyjątków, takich jak te dwa, na przykład InvalidCastException
lub DivideByZeroException
, które są generowane w przypadku określonych błędów w kodzie i zwykle oznaczają, że robisz coś źle lub nie sprawdzasz najpierw niektórych nieprawidłowych wartości. Wyrzucając je świadomie z kodu, utrudniasz po prostu kodowi wywołującemu określenie, czy zostały one wyrzucone z powodu błędu w kodzie, czy po prostu dlatego, że zdecydowałeś się użyć ich ponownie w implementacji.
Oczywiście są pewne wyjątki (hah) od tych zasad. Jeśli tworzysz coś, co może powodować wyjątek, który dokładnie pasuje do istniejącego, możesz z tego skorzystać, zwłaszcza jeśli próbujesz dopasować jakieś wbudowane zachowanie. Po prostu upewnij się, że wybrałeś bardzo konkretny typ wyjątku.
Ogólnie rzecz biorąc, jeśli nie znajdziesz (konkretnego) wyjątku, który spełnia Twoje wymagania, zawsze powinieneś rozważyć utworzenie własnych typów wyjątków dla określonych oczekiwanych wyjątków. Szczególnie podczas pisania kodu biblioteki może to być bardzo przydatne do oddzielenia źródeł wyjątków.