2009-07-10 5 views
3

Ich bin mir ziemlich sicher, dass ich die Antwort bereits kenne, aber ich bin immer noch neugierig, was die Meinung über die Behandlung eines Fehlers in einem Try, Catch, Finally Block ist - aber wenn du dich wiederholst.Throw Ausnahme VS Return Fehler innerhalb eines Try, Catch, schließlich

BTW - ich spreche nicht über User Input - aber mit, dass für ein Beispiel, weil es klar und kurz ist

dieses Stück Code Betrachten ...

try {  
    if (success) { 
     return someSuccessMessage; 
    } 
    else { 
     logError("User input not correct format"); 
     return someErrorMessage; // repeats itself 
    } 
} 
catch (Exception ex) { 
    logError(ex.Message); 
    return someErrorMessage; // repeats itself 
} 

Say Wir haben eine Funktion, die, wenn sie fehlschlägt, eine Fehlermeldung zurücksenden soll, weil die Ausnahme irrelevant ist - unsere Funktion war nicht erfolgreich und der Benutzer benötigt keine zusätzlichen Details.

Ich habe immer geglaubt, dass, wenn Sie mit dem Fehler umgehen können, die Ausnahme vermeiden - da es nicht mehr außergewöhnlich ist, aber ich fragte mich die Meinung über die Vermeidung von sich selbst zu wiederholen ... Sie könnten das tun folgende zu vermeiden, sich zu wiederholen ...

try {  
    if (success) { 
     return someSuccessMessage; 
    } 
    else { 
     throw new Exception("User input not correct format"); 
    } 
} 
catch (Exception ex) { 
    logError(ex.Message); 
    return someErrorMessage; 
} 

Dies ist nicht das beste Beispiel ist, aber ich war der Kürze halber werde den Punkt des Wiederholens Code zu machen.

Es ist bekannt, dass Ausnahmen eine Leistungseinbuße verursachen, aber was sind die Gedanken über eine Situation wie diese?

+0

Dies ist ein klassisches Beispiel für Ausnahmen Missbrauch für Kontrollfluss, hier diskutiert [Warum Ausnahmen nicht als regelmäßigen Kontrollfluss verwenden?] (Http://StackOverflow.com/q/729379/2444725) – Lightman

Antwort

3

IMO, eine Ausnahme sollte nur ausgelöst werden, wenn es außerhalb der korrigierbaren Situation ist. Benutzer, die ein falsches Format eingeben, sind bekannt und sollten keine Ausnahmen auslösen.

Behandlung Ausnahme wie es ist katastrophal (Datenzentrum in Brand, Erdbeben, etc.). Auf diese Weise sehen Sie den Unterschied zwischen der Behandlung von "regulärem Fehler" und "Ausnahme".

Und ja, werfen und fangen Ausnahme kostet eine Menge Leistung, am besten ist es, sie zu vermeiden.

0

in diesem Fall würde ich sagen eigentlich die try/catch nicht erforderlich ist, wie Ihr, wenn

mehr als ausreichend Umgang mit Ihrem Fehler ist

aber der Boden ist der Stil i für kompliziertere Situationen verwendet werden, glauben sollte

4

Ich Frage die Trennung von Bedenken hier. Sofern diese Funktion nicht Teil der Benutzeroberfläche ist, sollte sie sich nicht mit Fehlermeldungen befassen. Es sollte stattdessen Ausnahmen auslösen. Der Aufrufer dieser Methode, wenn er Teil der Benutzeroberfläche ist, möchte möglicherweise eine Fehlermeldung zur Anzeige erzeugen. Wenn der Aufrufer ein Webdienst wäre, würde er einen SOAP-Fehler erzeugen wollen, der möglicherweise nicht die gleiche Nachricht verwendet (wenn er überhaupt eine Nachricht verwendet hat).

Ich würde auch stark empfehlen, dass Sie ex.ToString() und nicht ex.Message protokollieren.

1

In Ihrem Fall würde ich nur die Fehlermeldung (erstes Beispiel) zurückgeben, denn eine Ausnahme zu werfen, nur um es 3 Zeile unten zu fangen scheint ein bisschen seltsam.

Eine ganz andere Sache ist, dass ich in der Regel vermeiden Fehlercodes wenn möglich zurückgeben - wenn ich eine Fehlersituation habe, ich durch eine Ausnahme und ich fange es auf dem höchsten möglichen Niveau. Auf diese Weise ist der Code nicht überall mit Fehlerbehandlung übersät und es ist viel einfacher, die Geschäftslogik zu sehen.In Ihrem Fall (wenn Sie es natürlich kontrollieren) könnte die Methode, die Erfolg zurückgibt, eine Ausnahme im Falle eines Fehlers ausgelöst haben und Sie müssten diese Frage gar nicht stellen :)

Es stimmt, dass Ausnahmen sind teuer in C#, so sollten sie nicht missbraucht werden. Wenn Sie sagen, dass die Leistungssteigerung von etwa 50 ms irrelevant ist, wenn Sie einen Fehler haben, tendiere ich dazu, sie zu verwenden, um den Code sauber zu halten.

+0

Ich hätte a komplexeres Beispiel - Das kurze Beispiel dient nur zur Veranschaulichung - ich spreche von einem größeren Beispiel mit mehr Vorgängen. Versuchen zu vermeiden, Fehlerbehandlungscode zu wiederholen. Danke für die Antwort aber – Hugoware

1

Ich würde Ihrer Logik in Ihrem Beispiel zustimmen, aber welche Exception behandeln Sie in Ihrem Ausnahmebehandlungsblock im Gegensatz zu Ihrem programmatischen Test? Ich vermute, dass Ihr Ausnahmebehandlungsblock wirklich "nur für den Fall, dass etwas passiert ist" ist. Es kommt also wirklich auf die Ausnahmebehandlungsregel an.

Wenn Sie keine Ausnahme behandeln müssen und nicht über eine bestimmte architektonische Grenze hinweg, können Sie damit nicht umgehen. Wenn es sich am Rand einer Komponentengrenze befindet, möchten Sie es möglicherweise umbrechen, indem Sie das Original in die innere Ausnahme einfügen.

Wenn die Funktionalität aus Code aufgerufen wird, möchten Sie das Ergebnis entweder mit einer Statusdarstellung wie einer Antwort testen (HRESULT ist ein Paradebeispiel dafür. 0 == SUCCESS,! = 0 == Fehler) oder Verwenden Sie Ausnahmen.

Beim Testen auf programmatische Fehler oder Komponentenfehler würden Sie Ausnahmen verwenden. Wenn Sie Eingaben des Benutzers auf einer Benutzeroberfläche validieren, können Sie einfach Logik verwenden und Statuscodes zurücksenden, um den Fehler dem Benutzer mitzuteilen.

Schließlich denke auch über die Lokalisierung nach. Wenn Sie eine englische Fehlernachricht durch das System krümmen und sie Ihrem französisch sprechenden Benutzer präsentieren, die nicht nützlich wäre, und Sie nicht wollen, Strings auf Ihrer Benutzeroberfläche zu analysieren, um die französische Version zu generieren, so sind Ausnahmen der Weg Gehen Sie so lange vor, wie die Nutzlast der Ausnahmebedingung über genügend Informationen verfügt, um eine sinnvolle Fehlermeldung zu generieren, damit der Benutzer Korrekturmaßnahmen ergreifen kann.

Verwenden Sie den Statuscode, bei dem Sie eine enge Kopplung zwischen den Komponenten haben und die aufrufende Komponente weiß, was in den verschiedenen Statusbedingungen zu tun ist.

BTW Möglicherweise möchten Sie den Stack-Trace sowie nur die Nachricht mithilfe von ToString() protokollieren, da Sie dadurch mehr hilfreiche Informationen zum Beheben des Problems erhalten.

HTH

+0

Danke für Ihre Antwort - BTW - das ist nicht wirklich Code - es war einfach, um den Punkt zu veranschaulichen :) – Hugoware

1

Extrahieren Sie die duplizierten Code aus in eine Funktion, wenn Sie sich fühlen Wiederholung ein Problem ist.

Um ehrlich zu sein, würde ich mich nicht sorgen, ein paar Zeilen in der gleichen Funktion zu duplizieren.

+0

Ich stimme nicht auf den letzten Satz. Es kann auf den ersten Blick als "nicht so wichtig" erscheinen, Doppelungen von ein paar Zeilen zu entfernen, aber stellen Sie sich die gleiche "leichte Wiederholung" in 10 verschiedenen Methoden vor. Duplikation ist böse. Wie sagte St. Exupery: Perfektion ist nicht, wenn es nichts hinzuzufügen, aber wenn es nichts zu entfernen gibt. –