2013-09-26 4 views
9

Der Code voraus return-Anweisungwarum müssen wird unten eine throw-Anweisung in einem catch-Block

try 
{ 
    session.Save(obj); 
    return true; 
} 
catch (Exception e) 
{ 
    throw e; 
    return false; // this will be flagged as unreachable code 
} 

beklagen, während dies nicht:

try 
{ 
    session.Save(obj); 
    return true; 
} 
catch (Exception e) 
{ 
    return false; 
    throw e; 
} 

ich es nicht ... dachte ich, mein csc101 sagte mir, dass Return-Anweisungen immer die letzte Anweisung in einer Funktion sein sollten und dass sie die Funktion beenden und die Steuerung an den aufrufenden Code zurückgeben. Warum widerspricht das der Logik meines Professors, und warum erzeugt nur einer von ihnen eine Warnung?

+2

„csc101 mir gesagt, diese Return-Anweisungen sollten immer die letzte Aussage in einer Funktion sein. ": Ich rufe dies als überholten Rat von Djikstra aus, der sich auf mehr altmodische Sprachen bezog, die unterschiedliche Ressourcen-Allokations-/Bereinigungsmodelle haben. – spender

+0

ist es C# oder Java? –

+0

C# ... ist Java anders? – sirbombay

Antwort

12

return wird die Methode beenden; throw wird auch verlassen Sie die Methode, vorausgesetzt, es ist nicht innerhalb der try. Es kann nur einmal verlassen werden!

Also unabhängig von der Reihenfolge - die erste der throw/return effektiv die Methode zu beenden.

Als allgemeinere Feedback, aber: wenn es die Absicht, bei einem Fehler zurück falsch ist, alles, was Sie brauchen, ist:

try 
{ 
    session.Save(obj); 
    return true; 
} 
catch 
{ 
    return false; 
} 

Ich persönlich würde sagen, dass diese schlechten Code - es versteckt sich das eigentliche Problem aus der Aufrufer, so dass es sehr schwer zu debuggen. Es sagt uns nichts von warum es fehlgeschlagen ist. Ich würde sagen, dass der bessere Ansatz ist einfach lassen Sie die Ausnahme Blase. In diesem Fall gibt es keinen Punkt, der true zurückgibt, weil wir niemals false zurückgeben würden - und es hat keinen Sinn, eine Ausnahme zu fangen, nur um sie erneut zu werfen. So ist die gesamte Methode wird:

session.Save(obj); 

(nichts anderes überhaupt erforderlich)


Wenn Ihre Frage ist: „Warum ist nur eine davon erzeugen eine Warnung“: eine faire Frage, aber der Compiler isn 't erforderlich zu spot entweder von ihnen für Sie. Vielleicht sollte es es erkennen. I verdächtigen, dass gmcswürde Spot dies und warnen darüber - der Compiler in Mono ist viel mehr bereit, auf Dummheit hinweisen.


Edit: wie erwartet, [g] mcs Ausgänge:

Program.cs(15,13): warning CS0162: Unreachable code detected 
Program.cs(28,13): warning CS0162: Unreachable code detected 

für den Code unten - so ist es in der Tat sowohl meldet verwendet als Warnung:

class Program 
{ 
    static void Main() { } 
    static void DoSomething() { } 
    bool ReturnFirst() 
    { 
     try 
     { 
      DoSomething(); 
      return true; 
     } 
     catch 
     { 
      return false; 
      throw; // line 15 
     } 
    } 
    bool ThrowFirst() 
    { 
     try 
     { 
      DoSomething(); 
      return true; 
     } 
     catch 
     { 
      throw; 
      return false; // line 28 
     } 
    } 
} 
+0

Ihre Antwort ist detaillierter und verdient es, die richtige Antwort zu sein.pls freundlicherweise aktualisieren, um das Szenario, wo die Absicht ist, den Anrufer wissen, ob oder nicht speichern (object) erfolgreich sein ... und will immer noch die Ausnahme zu propagieren upward.thanks – sirbombay

+0

@sirbombay das macht keinen Sinn: die Art, wie sie wissen, ob es gelungen ist oder nicht, ist einfach durch ** ob ** eine Ausnahme kam. Es kann nicht ** ** ** gibt ** zurück ** und ** eine Ausnahme auslösen - das macht einfach keinen Sinn. –

+0

Ich stoße heute auf diesen Standart-Compiler-Dummheit und dachte wirklich einmal kann es throw-Anweisung ausgeführt werden, auch nach Rückkehr Aussage? Vielen Dank für Ihre Antwort. –

1

Weil jeder Code nach der return-Anweisung innerhalb eines Codeblocks nicht erreichbar ist.

0

Diese Antwort basiert auf C# und ist möglicherweise nicht auf Java anwendbar.

In diesem Fall brauchen Sie nicht wirklich die return Anweisung. throw wird der letzte Schritt der Funktion sein. In diesem Beispiel wird sowohl die return als auch die throw die aktuelle Funktion beenden. Unabhängig davon, in welcher Richtung Sie sie platzieren, wird immer zuerst verhindert, dass die Sekunde erreichbar ist.

HINWEIS: Die Ausnahme, wenn eine throw Anweisung würde die Funktion beenden, wenn es in einem try Block gewickelt ist werden. In diesem Fall würde die Funktion throw die Ausführung des verbleibenden try Blockcodes beenden und zum relevantesten catch Block - oder finally Block gehen, wenn catch nicht anwendbar ist.

Ihr Code sollte wie folgt aussehen:

try 
{ 
    session.Save(obj); 

    return true; 
} 
catch(Exception e) 
{ 
    throw e; 
} 

Allerdings gibt nicht viel Sinn ist sowieso in mit der try/fangen, wenn alles, was Sie tun, ist die Ausnahme erneut zu werfen.


speziell auf Ihre einzige Frage zu beantworten:

Warum diese Logik mein Professor schändet?

Nun entweder Ihr Professor ist falsch, oder Sie haben sie mißverstanden

12

Sie sind falsch: beide Ihre Beispiele erhöhen die Toter Code Compiler-Fehler, weil beide throw und return den Ausgangspunkt einer Markierung Methode und kein weiterer Code ist über diesen Punkt hinaus erlaubt.

Egal, ob der Compiler dies erlaubt oder nicht, der Code unter throw oder return ist immer noch tot und wird niemals eine Chance zur Ausführung bekommen.

(Anmerkung: diese Frage wurde zunächst markiert als Java und mein erster Satz bezieht sich auf Java-Compiler Semantik)

+1

+1 für die einzig richtige Antwort. (Andere werden bald korrigieren) – xyz

+0

@musefan: Ich meine, zeigen Sie diese Frage selbst ist falsch, da beide Code Kompilierungsfehler gibt. – xyz

+2

Nein in VS2012, die 'Return -> Throw' geben keine Warnung während der' throw -> return' ja. –

0

Der "return false;" im Catch-Block ist nicht erreichbar wegen der "werfen e;" kurz davor. Wenn der Code im catch-Block ausgeführt wird, ist die erste Zeile ein throw, was bedeutet, dass Sie die Exception sofort an die aufrufende Methode übergeben, und daher wird der folgende Code nicht ausgeführt.

try 
    { 
     session.Save(obj); 
     return true; 
    } 
    catch(Exception e) 
    { 
     throw e; //Throws exception to calling method 
     return false; //this will be flagged as unreachable code 

    } 

Ich hoffe, das hilft.

Verwandte Themen