Lubię używać: ArgumentException
, ArgumentNullException
, i ArgumentOutOfRangeException
.
Istnieją również inne opcje, które nie koncentrują się tak bardzo na samym argumencie, ale raczej oceniają połączenie jako całość:
InvalidOperationException
- Argument może być prawidłowy, ale nie w bieżącym stanie obiektu. Kredyt trafia do STW (wcześniej Yoooder). Zagłosuj również na jego odpowiedź .
NotSupportedException
- Przekazane argumenty są prawidłowe, ale po prostu nie są obsługiwane w tej implementacji. Wyobraź sobie klienta FTP i wydajesz polecenie, którego klient nie obsługuje.
Sztuczka polega na rzuceniu wyjątku, który najlepiej wyraża, dlaczego metody nie można nazwać taką, jaka jest. W idealnym przypadku wyjątek powinien zawierać szczegółowe informacje o tym, co poszło nie tak, dlaczego jest nie tak i jak to naprawić.
Uwielbiam, gdy komunikaty o błędach wskazują pomoc, dokumentację lub inne zasoby. Na przykład firma Microsoft wykonała dobry pierwszy krok z artykułami KB, np. „Dlaczego otrzymuję komunikat o błędzie„ Operacja przerwana ”, gdy odwiedzam stronę sieci Web w programie Internet Explorer?” . Gdy napotkasz błąd, wskażą Ci artykuł KB w komunikacie o błędzie. To, czego nie robią dobrze, to to, że nie mówią ci, dlaczego to się nie udało.
Jeszcze raz dziękuję STW (ex Yoooder) za komentarze.
W odpowiedzi na Twoją kontynuację rzuciłbym plik ArgumentOutOfRangeException
. Zobacz, co MSDN mówi o tym wyjątku:
ArgumentOutOfRangeException
jest generowany, gdy wywoływana jest metoda i co najmniej jeden z argumentów przekazanych do metody nie jest odwołaniem o wartości null ( Nothing
w języku Visual Basic) i nie zawiera prawidłowej wartości.
Zatem w tym przypadku przekazujesz wartość, ale nie jest to prawidłowa wartość, ponieważ Twój zakres to 1–12. Jednak sposób, w jaki go dokumentujesz, wyjaśnia, co rzuca twój interfejs API. Bo chociaż mógłbym powiedzieć ArgumentOutOfRangeException
, inny programista mógłby powiedzieć ArgumentException
. Ułatw to i udokumentuj zachowanie.
FormatException
: wyjątek, który jest generowany, gdy format argumentu jest nieprawidłowy lub gdy ciąg formatu złożonego nie jest poprawnie sformułowany.Głosowałem za odpowiedzią Josha , ale chciałbym dodać jeszcze jedną do listy:
System.InvalidOperationException należy zgłosić, jeśli argument jest prawidłowy, ale obiekt jest w stanie, w którym argument nie powinien być używany.
Aktualizacja pobrana z MSDN:
Powiedzmy, że twój obiekt ma metodę PerformAction (akcja enmSomeAction), prawidłowe enmSomeActions to Otwórz i Zamknij. Jeśli wywołasz PerformAction (enmSomeAction.Open) dwa razy z rzędu, drugie wywołanie powinno zgłosić wyjątek InvalidOperationException (ponieważ arugment był prawidłowy, ale nie dla bieżącego stanu formantu)
Ponieważ już robisz właściwą rzecz, programując defensywnie, mam jeszcze jeden wyjątek, o którym warto wspomnieć, to ObjectDisposedException. Jeśli twój obiekt implementuje IDisposable, to zawsze powinieneś mieć zmienną klasy śledzącą stan usunięty; jeśli twój obiekt został usunięty i zostanie wywołana metoda, powinieneś zgłosić ObjectDisposedException:
Aktualizacja: Odpowiadając na dalsze uwagi: sytuacja jest trochę niejednoznaczna i jest trochę bardziej skomplikowana przez ogólny (nie w sensie .NET Generics) typ danych używany do reprezentowania określonego zestawu danych; wyliczenie lub inny silnie wpisany obiekt byłby bardziej idealny - ale nie zawsze mamy taką kontrolę.
Osobiście skłaniałbym się do ArgumentOutOfRangeException i udostępnił komunikat wskazujący, że prawidłowe wartości to 1-12. Moje rozumowanie jest takie, że kiedy mówisz o miesiącach, zakładając, że wszystkie liczby całkowite miesięcy są prawidłowe, to oczekujesz wartości z zakresu 1-12. Gdyby tylko niektóre miesiące (takie jak miesiące, które miały 31 dni) były ważne, nie miałbyś do czynienia z Range per se i rzuciłbym ogólny ArgumentException, który wskazywałby prawidłowe wartości, a także udokumentowałbym je w komentarzach do metody.
źródło
W zależności od rzeczywistej wartości i tego, który wyjątek pasuje najlepiej:
ArgumentException
(coś jest nie tak z wartością)ArgumentNullException
(argument ma wartość null, podczas gdy jest to niedozwolone)ArgumentOutOfRangeException
(argument ma wartość spoza prawidłowego zakresu)Jeśli to nie jest wystarczająco dokładne, po prostu wyprowadź własną klasę wyjątków z
ArgumentException
.Odpowiedź Yooodera oświeciła mnie. Dane wejściowe są niepoprawne, jeśli są nieprawidłowe w dowolnym momencie, natomiast dane wejściowe są nieoczekiwane, jeśli nie są poprawne w bieżącym stanie systemu. Więc w późniejszym przypadku
InvalidOperationException
wybór jest rozsądny.źródło
wyjątek argumentu.
źródło
ArgumentException :
Istnieje również kilka podklas dla określonych rodzajów inwalidztwa. Link zawiera podsumowania podtypów i kiedy powinny mieć zastosowanie.
źródło
Krótka odpowiedź:
żadne
Dłuższa odpowiedź:
używanie Argument * Wyjątek (z wyjątkiem biblioteki, w której jest włączony produkt, takiej jak biblioteka komponentów) to zapach. Wyjątki dotyczą sytuacji wyjątkowych, a nie błędów, a nie błędów użytkownika (tj. Konsumenta API).
Najdłuższa odpowiedź:
rzucanie wyjątków dla nieprawidłowych argumentów jest niegrzeczne, chyba że napiszesz bibliotekę.
Wolę używać asercji z dwóch (lub więcej) powodów:
Oto jak wygląda obsługa wyjątku zerowego (oczywiście sarkastyczny):
Wyjątki są stosowane, gdy sytuacja jest oczekiwana, ale wyjątkowa (zdarzają się rzeczy, na które konsument nie ma wpływu, np. Awaria IO). Argument * Wyjątek wskazuje na błąd i powinien być (moim zdaniem) obsługiwany za pomocą testów i wspomagany debugowaniem.
BTW: W tym konkretnym przypadku możesz użyć typu Month zamiast int. C # nie spełnia wymagań, jeśli chodzi o bezpieczeństwo typów (Aspect # rulez!), Ale czasami można zapobiec (lub złapać w czasie kompilacji) te błędy razem.
I tak, MicroSoft się co do tego myli.
źródło
Istnieje standardowy wyjątek ArgumentException, którego możesz użyć lub możesz utworzyć podklasę i utworzyć własną. Istnieje kilka określonych klas ArgumentException:
http://msdn.microsoft.com/en-us/library/system.argumentexception(VS.71).aspx
Którykolwiek działa najlepiej.
źródło