2009-03-02 7 views
10

Wenn ich eine Methode, die etwas zurückgibt, wietry-catch-Blöcke mit dem Rückgabetyp

public DataTable ReturnSomething() 
{ 
    try 
    { 
     //logic here 
    return ds.Tables[0]; 
    } 
    catch (Exception e) 
    { 
     ErrorString=e.Message; 
    } 
} 

Dieser Compiler-Fehler erzeugt, offensichtlich weil catch{} Block nichts zurückliefert.

Also, wenn ich Methoden mit Rückgabewerten habe, verwende ich nicht try-catch-Block, was eine schlechte Praxis ist. Wenn ein Fehler vorliegt, möchte ich eine Fehlerzeichenfolge für diesen Fehler festlegen. Aber dann brauche ich auch einen Rückgabewert. Rat?

+0

"Also wenn ich Methoden mit Rückgabewerten habe, verwende ich keinen try-catch-Block, was eine schlechte Übung ist." Sagt wer? Die meisten Methoden geben Werte zurück, ohne in try-Blöcke eingeschlossen zu werden. –

+0

Geschlagen um 20 Sekunden! Ja, was ich sagen wollte; Wenn es eine Ausnahme gibt - Wenn Sie es nicht erwarten und etwas Nützliches daran tun können, lassen Sie es dem Anrufer platzen. –

+2

Das Schlucken von Ausnahmen ist hier das eigentliche Problem. –

Antwort

27

Speichern Sie Ihre Rückgabewert codiert werden:

public DataTable ReturnSomething() 
{ 
    DataTable returnValue = null; 

    try 
    { 
     //logic here 
     returnValue = ds.Tables[0]; 
    } 
    catch (Exception e) 
    { 
     ErrorString=e.Message; 
    } 

    return returnValue; 
} 
+0

einfach und macht den Job. –

+3

Wie andere bemerkt haben, sollten Sie darüber nachdenken, die Ausnahme auszulösen, anstatt einen ErrorString zu setzen. Wenn Sie eine Ausnahme mit Ihrer eigenen Nachricht wünschen, sollten Sie eine neue Ausnahme mit der ursprünglichen Ausnahme als innere Ausnahme auslösen. Neue ArgumentException werfen ("Meine Nachricht", e); – Svish

+0

Ich stimme Svish und anderen zu; Obwohl ich versucht habe, Ihre Frage zu beantworten, glaube ich nicht, dass es die beste Lösung für Ihr Problem ist. – Simon

14

Sie sollten die Ausnahme in Ihrem catch-Block auslösen/werfen und in der aufrufenden Methode behandeln.

public void invokeFaultyCode() 
{ 
    try 
    { 
     DataTable dt = ReturnSomething(); 
    } 
    catch(Exception e) 
    { 
     // Print the error message, cleanup, whatever 
    }  
} 
public DataTable ReturnSomething() throws Exception 
{ 
    try 
    { 
     //logic here 
    return ds.Tables[0]; 
    } 
    catch (Exception e) 
    { 
     ErrorString=e.Message; 
     throw; 
    } 
} 

PS: Sorry für Syntaxfehler, ich bin ein bisschen rostig auf C#.

+1

Sie möchten vielleicht nur werfen, wie Wurf e den Ausnahmestapel ändern wird. –

+0

Guter Punkt, den Sie hier haben. –

+1

Nur zu beachten; Das Anhängen von 'throws' an eine Methode ist ein Java-Konzept, das in .NET nicht existiert. – Robula

3

Es hängt von Ihrer Anwendung ab. Sie können null, eine leere DataTable oder was auch immer unter Umständen geeignet ist, zurückgeben.

+0

Es hängt ganz von den Umständen ab. Sie sollten immer die Frage stellen "Was bedeutet es, wenn hier eine Ausnahme passiert?" anstatt der gleichen Praxis zu folgen. Ein Grund dafür, einen Exception-Handler zu haben, besteht darin, die Exception zu behandeln. – plinth

5

Sie sollten den Aufrufer mit einem try Catch umwickeln ... alle Ausnahmen, die in der aufgerufenen Routine auftreten, werden zum Aufrufer blasen und Sie können sie dort fangen.

Persönlich denke ich, es ist Overkill, einen Versuch in dieser Routine zu fangen, wie Sie den Anrufer haben sollten, der die Ausnahme behandelt.

Für mein Beispiel würde dies wie folgt ...

in einer temporären Variablen wie diese
private void DoSomething() { 
    try { 
     DataTable dt = ReturnSomething(); 
    } 
    catch (Exception ex) { 
    }  
} 

public DataTable ReturnSomething() { 
    DataTable dt = new DataTable(); 

    // logic here 
    return dt; 
} 
0

denke ich Ihren Code zur gleichen Zeit laufen wird eine ausreichend hohe Ebene des Aufruf-Stacks und es ist mit UI-Code gemischt. Wenn dies wirklich der Fall ist, könnten Sie return null im Catch-Block. Wenn Sie jedoch wiederverwendbaren Code schreiben, sollten Sie ihn so umgestalten, dass er keine UI-Manipulation enthält und die Ausnahme auf einer höheren Ebene im Aufruf-Stack behandelt.

0

Da Sie in Ihrem Beispiel die Ausnahme kacheln (und nicht erneut werfen), geht der äußere Code davon aus, dass alles in Ordnung ist und Sie daher etwas Nützliches zurückgeben sollten.

Wenn Sie die Ausnahme dort abfangen müssen und etwas tun, ist alles in Ordnung, aber wenn es immer noch ein Fehlerfall ist, sollten Sie es auch werfen, oder eine andere Ausnahme, vielleicht mit der, die Sie gerade als InnerException abgefangen haben.

3

ich würde annehmen, dass Sie nach wie vor die Nachricht einstellen, dann null zurück, oder was auch immer die C# entspricht

public DataTable ReturnSomething(){ 
    try { 
     //logic here 
     return ds.Tables[0]; 
    } catch (Exception e) { 
     ErrorString=e.Message; 
     return null; 
    } 
} 
2

Wie wäre es damit:

public DataTable ReturnSomething(out string errorString) 
{ 
    errorString = string.Empty; 
    DataTable dt = new DataTable(); 
    try 
    { 
     //logic here 
    dt = ds.Tables[0]; 
    } 
    catch (Exception e) 
    { 
     errorString = e.Message; 
    } 
    return dt; 
} 
+0

Wird es nicht ein Compilerfehler sein, da errorString ein out ist und es nicht garantiert ist, dass es gesetzt ist? –

+0

yeap, du hast Recht, ich schreibe es einfach in SO-Editor :) Bearbeitung! – Canavar

+0

@ScarletGarden: Ich mache das Gleiche;] –

3

Wenn Sie das "gehen, um den Kopf Wirf keine Ausnahmeroutine "(was ich nicht unbedingt empfehle), du könntest dem TryParse-Ansatz von MS folgen.

Etwas wie:

private string FillDataTable(out DataTable results) 
{ 

    try 
{ 
    results = new DataTable(); //something like this; 
    return String.Empty; 
} 
catch (Exception ex) 
{ 
    results = null; 
return ex.Message; 

} 

}

6

Die Variable error sieht verdächtig nach einem Fehlercode Variable. Es empfiehlt sich, Ausnahmen zu verwenden, um Fehlerinformationen direkt zu übermitteln, anstatt sie in Fehlercodes zu speichern.

Sie machen das gleiche mit Ihrem ErrorString, wie Sie es wären, wenn Sie die Ausnahme einfach vom Aufrufer abfangen lassen: die Verantwortung für die Reaktion auf einen Fehler von der Methode selbst zu entfernen. Das ist ein gutes Ziel. Aber die Verwendung einer Fehlerzeichenfolge bringt Ihnen nichts über die Verwendung einer Ausnahme. In der Tat verlieren Sie Informationen auf diese Weise. Es gibt eine Reihe von Arten von Fehlern, die auftreten können, und viele haben spezielle Ausnahmen, die mit ihnen verbunden sind, mit ihren eigenen speziellen Eigenschaften, um kontextabhängige Informationen über den Fehler zu speichern. Wenn Sie die Nachricht in einem String speichern, verlieren Sie diese Information.

Wenn Ihr Ziel also nicht darin besteht, den Fehlertyp des Aufrufers zu verbergen, können Sie nur gewinnen, indem Sie die Ausnahme durchlassen.

Eine andere Sache zu prüfen ist, ob dies wirklich ein Fehlerszenario ist. Wenn dies der Fall ist, ist es sehr unwahrscheinlich, dass Ihre Aufrufmethode überhaupt den Wert des Rückgabewerts berücksichtigt. In diesem Fall müssen Sie sich keine Sorgen machen, indem Sie einfach die Ausnahme loslassen und nichts zurückgeben. Wenn es nicht wirklich ein Fehlerszenario ist, und der Anrufer wird einfach weitermachen und etwas anderes tun, nun, das muss der Anrufer entscheiden, oder? Es gibt immer noch keinen großen Vorteil, wenn Sie eine Fehlerzeichenfolge und eine Dummy-DataTable oder eine Null zurückgeben und die Ausnahme mit all ihren kontextabhängigen Fehlerinformationen überschreiben.

0

Sie können es wie den folgenden Beispielcode tun.

public DataTable ReturnSomething(out string OutputDesc) 
{ 
    try 
     { 
     //logic here 
     OutputDesc = string.Format("Your Successful Message Here..."); 
     return ds.Tables[0]; 
     } 
     catch (Exception e) 
     { 
     OutputDesc =e.Message; 
     return null; 
     } 

} 
Verwandte Themen