Ich mag zu verwenden: ArgumentException
, ArgumentNullException
, und ArgumentOutOfRangeException
.
Es gibt auch andere Optionen, die sich nicht so sehr auf das Argument selbst konzentrieren, sondern den Aufruf als Ganzes beurteilen:
InvalidOperationException
- Das Argument ist möglicherweise in Ordnung, jedoch nicht im aktuellen Status des Objekts. Das Guthaben geht an STW (früher Yoooder). Stimmen Sie auch seine Antwort ab.
NotSupportedException
- Die übergebenen Argumente sind gültig, werden in dieser Implementierung jedoch nicht unterstützt. Stellen Sie sich einen FTP-Client vor und Sie übergeben einen Befehl, den der Client nicht unterstützt.
Der Trick besteht darin, die Ausnahme auszulösen, die am besten ausdrückt, warum die Methode nicht so aufgerufen werden kann, wie sie ist. Im Idealfall sollte die Ausnahme detailliert beschrieben werden, was schief gelaufen ist, warum es falsch ist und wie es behoben werden kann.
Ich liebe es, wenn Fehlermeldungen auf Hilfe, Dokumentation oder andere Ressourcen verweisen. Zum Beispiel hat Microsoft mit seinen KB-Artikeln einen guten ersten Schritt getan, z. B. "Warum erhalte ich die Fehlermeldung" Vorgang abgebrochen ", wenn ich eine Webseite in Internet Explorer besuche?" . Wenn Sie auf den Fehler stoßen, verweisen sie auf den KB-Artikel in der Fehlermeldung. Was sie nicht gut machen, ist, dass sie dir nicht sagen, warum es speziell fehlgeschlagen ist.
Nochmals vielen Dank an STW (ex Yoooder) für die Kommentare.
Als Antwort auf Ihr Follow-up würde ich eine werfen ArgumentOutOfRangeException
. Sehen Sie sich an, was MSDN zu dieser Ausnahme sagt:
ArgumentOutOfRangeException
wird ausgelöst, wenn eine Methode aufgerufen wird und mindestens eines der an die Methode übergebenen Argumente keine Nullreferenz ( Nothing
in Visual Basic) ist und keinen gültigen Wert enthält.
In diesem Fall übergeben Sie also einen Wert, der jedoch kein gültiger Wert ist, da Ihr Bereich zwischen 1 und 12 liegt. Die Art und Weise, wie Sie es dokumentieren, macht jedoch deutlich, was Ihre API auslöst. Denn obwohl ich sagen könnte ArgumentOutOfRangeException
, könnte ein anderer Entwickler sagen ArgumentException
. Machen Sie es sich einfach und dokumentieren Sie das Verhalten.
FormatException
: Die Ausnahme, die ausgelöst wird, wenn das Format eines Arguments ungültig ist oder wenn eine zusammengesetzte Formatzeichenfolge nicht gut gebildet ist.Ich habe für Joshs Antwort gestimmt , möchte aber noch eine zur Liste hinzufügen:
System.InvalidOperationException sollte ausgelöst werden, wenn das Argument gültig ist, das Objekt sich jedoch in einem Zustand befindet, in dem das Argument nicht verwendet werden sollte.
Update aus MSDN entnommen:
Angenommen, Ihr Objekt verfügt über eine PerformAction-Methode (enmSomeAction action). Gültige enmSomeActions sind Open und Close. Wenn Sie PerformAction (enmSomeAction.Open) zweimal hintereinander aufrufen, sollte der zweite Aufruf die InvalidOperationException auslösen (da das Arugment gültig war, jedoch nicht für den aktuellen Status des Steuerelements).
Da Sie bereits das Richtige tun, indem Sie defensiv programmieren, muss ich noch eine weitere Ausnahme erwähnen: ObjectDisposedException. Wenn Ihr Objekt IDisposable implementiert, sollte immer eine Klassenvariable vorhanden sein, die den bereitgestellten Status verfolgt. Wenn Ihr Objekt entsorgt wurde und eine Methode darauf aufgerufen wird, sollten Sie die ObjectDisposedException auslösen:
Update: Um Ihre Nachverfolgung zu beantworten: Es handelt sich um eine mehrdeutige Situation, die durch einen generischen Datentyp (nicht im Sinne von .NET Generics), der zur Darstellung eines bestimmten Datensatzes verwendet wird, etwas komplizierter wird. Eine Aufzählung oder ein anderes stark typisiertes Objekt wäre idealer - aber wir haben diese Kontrolle nicht immer.
Ich würde mich persönlich der ArgumentOutOfRangeException zuwenden und eine Nachricht bereitstellen, die angibt, dass die gültigen Werte 1-12 sind. Meine Argumentation ist, dass Sie, wenn Sie über Monate sprechen und davon ausgehen, dass alle ganzzahligen Darstellungen von Monaten gültig sind, einen Wert im Bereich von 1-12 erwarten. Wenn nur bestimmte Monate (wie Monate mit 31 Tagen) gültig wären, würden Sie sich nicht mit einem Bereich an sich befassen, und ich würde eine generische ArgumentException auslösen, die die gültigen Werte angibt, und ich würde sie auch in den Kommentaren der Methode dokumentieren.
quelle
Abhängig vom tatsächlichen Wert und welcher Ausnahme am besten passt:
ArgumentException
(etwas stimmt nicht mit dem Wert)ArgumentNullException
(Das Argument ist null, solange dies nicht zulässig ist.)ArgumentOutOfRangeException
(Das Argument hat einen Wert außerhalb des gültigen Bereichs.)Wenn dies nicht genau genug ist, leiten Sie einfach Ihre eigene Ausnahmeklasse von ab
ArgumentException
.Yoooders Antwort erleuchtete mich. Eine Eingabe ist ungültig, wenn sie zu keinem Zeitpunkt gültig ist, während eine Eingabe unerwartet ist, wenn sie für den aktuellen Status des Systems nicht gültig ist. Im späteren Fall
InvalidOperationException
ist also eine vernünftige Wahl.quelle
Argument Ausnahme.
quelle
ArgumentException :
Es gibt auch einige Unterklassen für bestimmte Arten von Invalidität. Der Link enthält Zusammenfassungen der Untertypen und wann sie gelten sollten.
quelle
Kurze Antwort:
Weder noch
Längere Antwort: Die
Verwendung von Argument * Exception (außer in einer Bibliothek, in der ein Produkt aktiviert ist, z. B. eine Komponentenbibliothek) ist ein Geruch. Ausnahmen sind die Behandlung von Ausnahmesituationen, keine Fehler und keine Mängel des Benutzers (dh des API-Verbrauchers).
Längste Antwort: Das
Auslösen von Ausnahmen für ungültige Argumente ist unhöflich, es sei denn, Sie schreiben eine Bibliothek.
Ich bevorzuge Behauptungen aus zwei (oder mehr) Gründen:
So sieht die Behandlung von Null-Ausnahmen aus (offensichtlich sarkastisch):
Ausnahmen sind zu verwenden, wenn eine Situation erwartet wird, die jedoch außergewöhnlich ist (Dinge, die außerhalb der Kontrolle des Verbrauchers liegen, wie z. B. E / A-Fehler). Argument * Ausnahme ist ein Hinweis auf einen Fehler und soll (meiner Meinung nach) mit Tests behandelt und mit Debug.Assert unterstützt werden
Übrigens: In diesem speziellen Fall hätten Sie den Monatstyp anstelle von int verwenden können. C # ist nicht ausreichend, wenn es um die Typensicherheit geht (Aspect # rulez!), Aber manchmal können Sie diese Fehler alle zusammen verhindern (oder zur Kompilierungszeit abfangen).
Und ja, MicroSoft ist falsch.
quelle
Es gibt eine Standard-ArgumentException, die Sie verwenden oder eine Unterklasse erstellen und eine eigene erstellen können. Es gibt mehrere spezifische ArgumentException-Klassen:
http://msdn.microsoft.com/en-us/library/system.argumentexception(VS.71).aspx
Was auch immer am besten funktioniert.
quelle