2009-06-13 11 views
20

Ich schreibe eine benutzerdefinierte Klasse in C# und ich gebe ein paar Ausnahmen, wenn Leute in einigen der Methoden die falschen Eingaben geben. Wenn die Ausnahme ausgelöst wird, wird irgendeiner der Code in der Methode nach dem Wurf noch ausgeführt? Muss ich nach dem Wurf eine Pause machen, oder bricht ein Wurf immer die Methode ab?Muss ich nach dem Auslösen der Ausnahme brechen?

+1

Teilen Sie dies in drei Fragen auf. (1) Wird irgendein Code in der Methode nach dem Wurf ausgeführt? JA. Wenn die Ausnahme in einem Versuch war, dann wird der Code in passenden catch-Blöcken oder schließlich blocks ausgeführt. Wenn es keinen Testblock gibt, dann NEIN. Die Steuerung verzweigt zu dem nächsten umschließenden finally, catch oder (in vb) Ausnahmefilter, der den Stapel blockiert. –

+2

(2) Muss ich nach dem Wurf eine Pause machen? NEIN, tu das nie. Der Endpunkt der throw-Anweisung ist nicht erreichbar. Ein throw wird vom Compiler als goto behandelt. Eine Anweisung unmittelbar nach einem Wurf ist nicht erreichbar und wird niemals ausgeführt. –

+1

(3) Beendet ein Wurf immer die Methode? NEIN. Wenn der Wurf in einem Versuch ist und der Versuch einen passenden Fangblock hat, kann der Fangblock die Ausnahme "essen". Nur wenn es keinen catch-Block gibt, führt die Exception einen nicht-lokalen Aufruf des Aufruf-Stacks aus. –

Antwort

30

Wenn Sie throw eine Ausnahme sind, ist der nächste Code, der ausgeführt wird, ein catch-Block, der den throw innerhalb der Methode (falls vorhanden) abdeckt, dann die finally block (falls vorhanden). Sie können es versuchen, versuchen, zu fangen, zu versuchen - endlich - oder schließlich versuchen. Wenn die Ausnahme nicht behandelt wird, durch einen catch-Block erneut ausgelöst oder überhaupt nicht abgefangen wird, wird die Steuerung an den Aufrufer zurückgegeben. Zum Beispiel werden Sie "ja1, Ja2, Ja3" von diesem Code erhalten ...

try 
{ 
    Console.WriteLine("Yes1"); 
    throw (new Exception()); 
    Console.WriteLine("No1"); 

} 
catch 
{ 
    Console.WriteLine("Yes2"); 
    throw; 
    Console.WriteLine("No2"); 
} 
finally 
{ 
    Console.WriteLine("Yes3"); 
} 

Console.WriteLine("No3"); 
+0

Dies wäre eine Ausnahme (kleines e) zu meiner Antwort. Ich dachte dabei an eine Exception, die im gemeinsamen Kontext verwendet und nicht wie eine GOTO-Anweisung verwendet werden würde. –

+0

@jarrett: Dies ist genau der gemeinsame Kontext, außer dass der throw in Funktionsaufrufen versteckt ist. – configurator

27

Throw bewegt sich den Stapel nach oben und beendet so die Methode.

+2

Danke. Tut mir leid, eine solche grundlegende Frage zu stellen. – Ross

1

Wenn Sie Ihren Code in einem Try gewickelt haben ... Catch ... Finally-Block, dann wird der Code unter Endlich wird immer ausgeführt. Zum Beispiel:

Try 
    ' do some stuff here 
    ' Examine user input 
    If user input isn't valid 
     Throw new exception 
Catch 
    Throw ' Just re-throws the same exception 
Finally 
    ' This code will execute, no matter what - exception or not 
End Try 
1

Als eine Nebenfrage zu Ihrer eigentlichen Frage: Sie möchten möglicherweise über Ausnahmen überprüfen, um Validierungsinformationen an den Benutzer zurück zu geben.

Das Erhöhen von Ausnahmen ist in Bezug auf die Ressourcen teuer und langsam. Wenn Sie eine Reihe von Validierungsregeln haben, die Sie anwenden müssen, schreiben Sie spezifischen Code für diese - Sie sollten sich wahrscheinlich nur auf Ausnahmen für Dinge verlassen, die Sie nicht erwarten.

+0

Ich habe mich auch darüber gewundert. Ich schreibe eine Highscore-Klasse, und der Konstruktor kann einen "max" -Param nehmen. welches die maximal verfügbare Punktzahl anzeigt. gut, wenn sie eine Zahl überschreiten, die größer ist, als meine Klasse unterstützt, warf ich eine Ausnahme, weil ich nicht wollte, dass der Konstruktor mit schlechten Informationen endete. Ich bin neu darin, gibt es einen besseren Weg, es zu tun? – Ross

+0

Dies ist ein Kommentar und keine wirkliche Antwort auf das OP. – Drellgor

3

Ich empfehle, mit einem Debugger durch Ihr Programm zu gehen, dann werden Sie selbst sehen, was vor sich geht. Sehr nützlich zum Lernen!

+0

Dies ist ein guter Tipp. Ich werde das machen! Danke – Ross

+0

Dies ist ein "Tipp" und keine Antwort auf die ursprüngliche Frage. – Drellgor

+0

Wow meine Flagge "keine Antwort" war umstritten. – Almo

2

Ich kam hier auf der Suche nach einer Antwort auf den ursprünglichen Beitrag und fast eine sehr wertvolle Antwort von Eric Lippert geschrieben verfehlt. Hier ist seine Antwort in den Kommentaren geschrieben:

Teilen Sie dies in drei Fragen auf.

(1) Wird der Code in der Methode nach dem Wurf ausgeführt?
JA. Wenn die Ausnahme in einem Versuch war, dann wird der Code in passenden catch-Blöcken oder schließlich blocks ausgeführt. Wenn es keinen Testblock gibt, dann NEIN. Die Steuerung verzweigt zu dem nächsten umschließenden finally, catch oder (in vb) Ausnahmefilter, der den Stapel blockiert.

(2) Muss ich nach dem Wurf eine Pause machen?
NEIN, tu das nie. Der Endpunkt der throw-Anweisung ist nicht erreichbar. Ein throw wird vom Compiler als goto behandelt. Eine Anweisung unmittelbar nach einem Wurf ist nicht erreichbar und wird niemals ausgeführt.

(3) Beendet ein Wurf immer die Methode?
NR. Wenn der Wurf in einem Versuch ist und der Versuch einen passenden Fangblock hat, kann der Fangblock die Ausnahme "essen". Nur wenn es keinen catch-Block gibt, führt die Exception einen nicht-lokalen Aufruf des Aufruf-Stacks aus.

Wenn Sie weitere Fragen dazu haben, empfehle ich, die C# -Spezifikation zu lesen; All dieses Verhalten ist eindeutig dokumentiert.

Schließlich klingt es, als ob Sie "boneheaded" Ausnahmen werfen, wie in "hey boneheaded Anrufer, ich habe dir gesagt, dass Sie mir diese Daten nie geben". Das ist großartig, weil es Bugs in Anrufern verhindert. Aber wenn Sie das tun, sollten Sie sicherstellen, dass der Anrufer eine Möglichkeit hat zu wissen, was Sie erwarten! Wenn der Aufrufer basierend auf Ihrer Dokumentation nicht herausfinden kann, ob Sie werfen oder nicht, haben Sie keine boneheaded-Ausnahme gemacht, Sie haben eine ärgerliche Ausnahme gemacht. Details siehe http://blogs.msdn.com/ericlippert/archive/2008/09/10/vexing-exceptions.aspx.

+0

In Bezug auf Ihren ersten Punkt: C# hat jetzt auch Ausnahmefilter; Es ist nicht mehr nur für VB. –

Verwandte Themen