|
|
|
|
|
Zu a)
Eine NotImplementedException halt ich persönlich dafür unpassend. Die Implementierung ist ja gemacht, eben nur nicht vollständig oder wurde nach Änderungen nicht erweitert. Zu b1) Für den Aufrufer hat ein eigener Exception-Typ keinen Mehrwehrt - wohl aber für den Programmierer. Wenn der Fehler bei einem Kunden passiert, ist anhand der spezifizierten Exception erkennbar in welcher Ecke der Fehler liegt. Klar, ich kann Messages verwenden. Das ist aber auch mit erheblichem Aufwand verbunden und setzt voraus, daß auch die richtigen Messages mitgegeben werden. – Joachim 15.02.2011
|
||
|
zu a) in Ermangelung einer "PartlyNotImplementedException" finde ich die NotImplementedException ausreichend aussagekräftig. Die NotSupportedException käme auch noch in Frage, noch mehr aber für b2).
– Matthias Hlawatsch 15.02.2011
|
||
|
zu b1) Ich halte mich hier an die "Framework Design Guidelines" von K. Cwalina u. B. Abrams:
"Do not create new exception types to communicate usage errors. Throw one of the existing Framework exceptions instead. ... Usage errors need to be communicated to the developer calling the API and should not be handled directly in code. The exception type is generally less important to developers trying to fix their code than the message string. Therefore ... you should concentrate on designing a really good ... exception message and using one of the existing .NET Framework exception types" – Matthias Hlawatsch 15.02.2011
|
||
|
Schön. Für meinen Teil habe ich aber nicht vor, nur das zu tun, was andere mir vordenken. Wenn Cwalina und B.Abrams das so sehen, sollen sie es so tun. Ich versuche nur abzuwägen, was in meinen Fällen Sinn macht und was nicht. Und da jeder nunmal anders denkt, wird jeder unterschiedliche Wege beschreiten.
– Joachim 15.02.2011
|
||
| 2 |
Man könnte die eigene Exception von der ArgumentOutOfRangeException oder der NotImplementedException ableiten. Je nachdem was gerade benötigt wird. Eine ordentliche Vererbungshierachie finde ich gerade bei Exceptions wichtig damit man sich beim behandeln für ein Detail-Level entscheiden kann.
– Floyd 15.02.2011
|
|
public class AutoTypNichtErmittelbarException : Exception { }cars GetCarType(string car)
{
cars c;
bool result = System.Enum.TryParse<cars>(car, out c);
if (result == false) throw new AutoTypNichtErmittelbarException();
return c;
}
|
|
|
Der eigene Exception-Typ kristallisiert sich als beste Variante heraus. Allerdings nicht unbedingt abgeleitet von Exception und auch nicht unbedingt für jede Enum ein eigener Exception-Typ.
In Deinem Beispiel wird ein Wert in einen Enum-Wert konvertiert und darum geht es bei meiner Frage nicht. Ich möchte ja nicht Werte konvertieren, sondern auf Basis eines Enum-Werts eine Entscheidung treffen und dies tue ich normalerweise entweder mit "if" oder "switch". – Torsten Weber 15.02.2011
|
ArgumentOutOfRangeExceptiongedacht.
Die Ausnahme, die ausgelöst wird, wenn der Wert eines Arguments nicht in dem Wertebereich liegt, der durch die aufgerufene Methode als zulässig definiert ist.
|
|
|
Kommt auf die Situation an. Ein erhöhter Aufwand beim Erstellen spezifischer Exceptions ist u.U. schnell wieder aufgeholt. Alles mit vordefinierten Exceptions abzuwickeln ist auch nicht unbedingt die Lösung.
– Joachim 15.02.2011
|
||
|
Wodurch habe ich denn den Erstellungsaufwand einer der Exceptions (pro Enumtype einen) wieder aufgeholt?
"Alles mit vordefinierten..." wie ist das gemeint? Ich spreche mich nicht grundsätzlich gegen eigene Exceptions aus, aber für den Fall der Enums auf jeden Fall. – KHoffmann 15.02.2011
|
||
| 1 |
So wie ich es sehe, meinte Joachim nicht das Instanziieren der Exception, sondern die Erstellung der eigentlichen Klasse.
Mit vordefinierten Exception sind die im .NET-Framework mitgelieferten Exception-Typen gemeint. Soll heißen, sie passen nicht zu jedem Anwendungsfall. Man sollte nicht immer auf diese Typen zurückgreifen, nur wenn die Verwendung sinnvoll ist. – Andy Stumpp 15.02.2011
|
|
| 1 |
Nochmal: Es kommt auf die Situation an. Angenommen neben einer ArgumentOutOfRangeException durch ein enum, könnte eine weitere ArgumentOutOfRangeException auftreten, die mit dem enum nix zu tun hat. Durch das Werfen einer spezifischen Exception ist das Handling meines Erachtens einfacher. Wenn in der switch Anweisung wirklich nur bei falschem enum eine Exception geworfen werden soll, dann geb' ich Dir recht mit der Wahl von ArgumentOutOfRangeException
– Joachim 15.02.2011
|
|
|
@Andy: Das ist mir schon klar, das nicht die Instanziierung der Ex gemeint ist.
_____________________________________________________ Nach Jochaims Erläuterung ist mir klar, wie er "... schnell wieder aufgeholt" meinte. Ich kann mich jedoch an keine Situation erinnern, wo ich den Fall einer doppelten ArgumentOutOfRangeException hätte. Aber belassen wir es dabei ;) – KHoffmann 15.02.2011
|
||
|
Na, dann verstehe ich aber nicht, warum Du zuerst so gar nicht verstehen wolltest, warum "schnell wieder aufgeholt" :)
– Joachim 15.02.2011
|
|
|
|
Das gibt's ja gar nicht! Wie blind bin ich bitte? Diesen Exception-Typ gibt es seit .NET 1.1! Unlgaublich. Vielen Dank für Deinen Link!
– Torsten Weber 17.02.2011
|
||
|
Ich muss da glaube ich noch mal drauf rum denken, denn diese Ausnahme scheint mir auch nicht "ausnahmslos" ;-) die Beste Wahl zu sein.
– Torsten Weber 17.02.2011
|
||
|
Nee, ausnahmslos gut ist das Ding sicher nicht. Wie ich das sehe, ist InvalidEnumArgumentException mehr geeignet wenn der übergebene Enum-TYP(!) ungültig ist, während für einen ungültigen Enum-WERT(!) ArgumentOutOfRangeException irgendwie besser passt. Aber irgendwie ist das eine reine Geschmacksfrage :-)
– Andi 20.02.2011
|
||
|
In der MSDN-Dokumentation (englische Version) zu dieser Ausnahme ist wohl auch irgendwas falsch. Die sprechen nämlich dort von "Enumerators" und es gibt einen Community-Kommentar, der darauf hinweist, dass der Hilfetext falsch ist.
– Torsten Weber 20.02.2011
|
||
|
Du hast mich allerdings trotzdem inspiriert und ich habe einen Kommentar zu meiner Frage hinzugefügt. Dort entscheide ich mich nämlich für die InvalidEnumArgumentException.
– Torsten Weber 20.02.2011
|
public class MyEnumException: Exception
{
public MyEnumException()
{
}
public MyEnumException(string message)
: base(message)
{
}
...
}
|
|
|
In meiner Antwort hätte ich besser schreiben sollen, das von Exception oder einer davon abgeleiteten Klasse abgeleitet werden soll. Aber das war ja auch nur ein Beispiel
– Joachim 16.02.2011
|
Wenn ein switch-Block einfach immer in einer eigenen Methode implementiert wird, handelt es sich beim Enum-Wert immer um ein Argument und somit kann dann auch immer diese Ausnahme verwendet werden. Dazu kommt noch, dass ein so gekapselter switch-Block unit-testbar wird und dokumentiert sich - einen ordentlichen Methodennamen vorausgesetzt - auch noch von selbst. Ha!