Wann soll "Try" in C # -Methodennamen verwendet werden?

180

Wir haben mit unseren Mitarbeitern darüber gesprochen, was es bedeutet, wenn der Methodenname mit "Try" beginnt.

Es gab folgende Meinungen:

  • Verwenden Sie "Try", wenn die Methode einen Nullwert zurückgeben kann.
  • Verwenden Sie "Try", wenn die Methode keine Ausnahme auslöst.

Was ist die offizielle Definition? Was sagt "Try" im Methodennamen? Gibt es eine offizielle Richtlinie dazu?

ms007
quelle
83
+1 Leute, die so viel über die Namen ihrer Funktionen nachdenken, suchen tatsächlich nach "dem nächsten Mann". Ich bin mir nicht sicher, warum dies enge Stimmen bekommt (und das kommt von einem Mann, der heute Abend viele von ihnen besetzt hat.)
Jonathon Reinhart
7
@ JonathonReinhart erhielt enge Stimmen, weil "Diese Frage passt derzeit nicht gut zu unserem Q & A-Format. Wir erwarten, dass die Antworten durch Fakten, Referenzen oder spezifisches Fachwissen gestützt werden, aber diese Frage wird wahrscheinlich zu Debatten und Argumenten führen , Umfrage oder erweiterte Diskussion. "
Pranav Hosangadi
16
Es gibt eine offizielle Erklärung von Microsoft, die die Frage beantwortet (siehe meine Antwort). Wie ist das nicht eine Tatsache?
Erik Schierboom
6
@PranavHosangadi wie Erik erwähnte, wird es durch Fakten gestützt. Außerdem gibt es hier viele sehr erfahrene C # -Entwickler, die über spezifisches Fachwissen verfügen , um eine gültige Antwort zu geben. Zur Hölle, Eric Lippert ist der Chefarchitekt der C # -Sprache. Ich denke, Sie können dieses spezifische Fachwissen nennen .
Jonathon Reinhart
4
@ErikSchierboom Dass es die MS-Richtlinie ist, ist Tatsache. Dass die MS-Richtlinie die richtige Richtlinie ist, ist subjektiv und umstritten.
Servy

Antworten:

148

Dies ist als TryParse- Muster bekannt und wurde von Microsoft dokumentiert. Auf der offiziellen MSDN-Seite für Ausnahmen und Leistung heißt es :

Betrachten Sie das TryParse-Muster für Mitglieder, die in allgemeinen Szenarien Ausnahmen auslösen können, um Leistungsprobleme im Zusammenhang mit Ausnahmen zu vermeiden.

Wenn Sie also Code haben, für den ein regulärer Anwendungsfall bedeuten würde, dass er eine Ausnahme auslösen könnte (z. B. das Parsen eines Int), ist das TryParse- Muster sinnvoll.

Erik Schierboom
quelle
2
Ein weiterer nützlicher Link, der dieses Muster dokumentiert (Suche nach TryParse) blogs.msdn.com/b/kcwalina/archive/2005/03/16/396787.aspx
Vivek Maharajh
2
Wenn Sie eine TryParse-Methode haben, sollten Sie grundsätzlich eine Parse-Methode haben, die ausgelöst wird, wenn TryParse false zurückgibt. Umgekehrt, wenn Sie eine Parse-Methode haben, sollten Sie eine TryParse-Methode in Betracht ziehen, die false zurückgibt, wenn Parse werfen würde
3Doubloons
5
+1. Um dies hinzuzufügen, gelten Ausnahmen im Allgemeinen für "außergewöhnliche" Umstände. Wenn Sie etwas tun, das leicht scheitern könnte und das nicht besonders bemerkenswert ist, dann ist die Verwendung dieses Musters idiomatischer als ein Versuch / Fang
Adam Robinson
Benötigte ein solches Muster wirklich Richtlinien von Microsoft? Scheint ziemlich einfach zu sein.
Dave Lawrence
19
Es sind grundlegende Dinge, aber das bedeutet nicht, dass Richtlinien nicht nützlich sind. Grundlegende Dinge richtig zu machen kann ziemlich schwierig sein, wenn Sie die Plattform nicht gut genug kennen.
Erik Schierboom
119

(Korrigiert) Es gibt offizielle Richtlinien, wie Erik vorgeschlagen hat.

Wenn ich TrySomethingMethode sehe , nehme ich es an

  • wirft nicht
  • kehrt zurück bool
  • Wenn ich einen Wert erwarte, wird dieser über den Parameter 'out' zurückgegeben
  • Es gibt eine SomethingMethode, mit der ich jede Ausnahme selbst behandeln kann. (bearbeiten, vorgeschlagen von Jesse Webb)
nothrow
quelle
4
Korrektur - Es hat offizielle Richtlinien. Siehe Eriks Antwort.
Nothrow
8
+1 Aber ich habe auch eine vierte Erwartung: Wenn es eine TryFooMethode gibt, wird es eine ähnliche FooMethode geben, mit der ich alle Ausnahmen selbst behandeln kann. Die Signaturen dieser Methoden sind wahrscheinlich unterschiedlich, sodass ihre Verwendung ohne andere Codeänderungen nicht austauschbar ist.
Jesse Webb
1
@ JesseWebb, danke für den Hinweis. Ich habe Ihren Kommentar zu meiner Antwort hinzugefügt, wenn Sie nichts dagegen haben.
Nothrow
1
"Wirft nicht" scheint mir übergeneralisiert. Beispielsweise löst Int32.TryParse (String, NumberStyles, IFormatProvider, Int32) eine ArgumentException aus, wenn der Stilparameter nicht gefällt.
Jirka Hanika
Ich bin damit einverstanden, dass "nicht werfen" als übergeneralisiert angesehen werden kann, aber ich glaube, die Absicht war zu vermitteln, dass es nicht als Ergebnis der Ausführung und nicht als Ergebnis des Werts der Parameter wirft.
ConfusingBoat
8

Ich denke, Sie sollten verwenden, trywenn Sie fortfahren möchten. Es spielt keine Rolle, ob eine Methode einen Wert zurückgibt oder nicht.

Fall 1: Wenn es gut zurückkehrt, können Sie auf irgendeine Weise fortfahren.

Fall 2: Wenn es nicht zurückkehrt: Es ist immer noch in Ordnung. Sie können auch anders vorgehen.

Und wenn Sie einen Wert als Ausgabe dieser Methode erwarten, verwenden Sie den outParameter.

Beispiel

int value
if (dictionary.TryGetValue("key", out value))
{
    // Proceed in some way
}
else
{
    // Proceed in some other way
}
Ashok Damani
quelle
6

Sie müssen "Try" im Methodennamen verwenden, wenn Sie die Tatsache manifestieren möchten, dass der Methodenaufruf zu einem ungültigen Ergebnis führen kann. Nach dem .NET-Standard ist es übrigens keine Funktion, die eine Ausnahme auslöst, sondern die Funktion, die einen Wert VALIDoder NON_VALIDaus Programmsicht einen Wert zurückgibt .

Am Ende dreht sich alles um die Namenskonvention, die Sie in Ihrer Gruppe verwenden möchten.

Tigran
quelle
5

tryStellen Sie sicher, dass Sie in Ihren Methodennamen aufnehmen, wenn:

  • Sie werfen keine Ausnahme
  • Ihre Methode hat die folgende Signatur: bool TrySomething(input, out yourReturn)

Wenn wir also try-methods verwenden, erhalten wir nur ein boolesches Ergebnis zurück.

Der folgende Code löst also keine Ausnahmen aus:

string input = "blabla";
int number;
if (int.TryParse(input, out number))
{
// wooohooo we got an int!
} else
{
//dooh!
}

Während dieser Code Ausnahmen auslösen kann (und in diesem Fall wird):

string input = "blabla";
int number;
try
{
     number = int.Parse(input); //throws an exception
}
catch (Exception)
{
     //dooh!
}

Die Verwendung von Try-Methoden ist eine sicherere und defensivere Methode zum Codieren. Auch die Ausführung des Code-Snippets Nr. 2 erfordert mehr Leistung, wenn es sich nicht um eine Ganzzahl handelt.

Fabian Bigler
quelle
Ihr Code-Snippet Nr. 2 sollte lauten, int number = int.Parse(input);wenn Sie möchten, dass es in diesem Zusammenhang aussagekräftiger ist.
Pierre Arnaud
@PierreArnaud Danke, geändert!
Fabian Bigler
Ihnen fehlt noch die int number;Deklaration vor dem try-Block und der number = ...Zuordnung.
Pierre Arnaud
@PierreArnaud Danke, ich habe jetzt auch 'int number' eingefügt.
Fabian Bigler
Beachten Sie, dass Sie möglicherweise immer noch Ausnahmen TryLoadFile(path, out file)auslösen, wenn die Ausnahme nicht mit der direkten Aktion zusammenhängt, die wie woah außerhalb des Arbeitsspeichers ausgeführt wird. Der Anrufer würde also keine Fehler für einen schlechten Pfad oder einen verweigerten Zugriff erwarten, sondern eine Ausnahme für die verrückteren Dinge, die ebenfalls schief gehen könnten. Und dokumentieren Sie es.
Luke Puplett
0

Onkel Bob gibt das folgende Beispiel in seinem Buch Clean Code . Wann immer wir erwarten, dass eine Ausnahme ausgelöst wird, können wir das TryPräfix für einen Methodennamen verwenden:

public void sendShutDown()
{
    try{
        tryToShutDown();
    } catch (DeviceShutDownError e) {
        logger.log(e);            
    }
}

Und dann (angepasst):

private void tryToShutDown()
{
    //some code with no error handling, but
    //something might go wrong here
}

Die tryToShutDownMethode führt keine Fehlerbehandlung durch, da dies in der Verantwortung der sendShutDownMethode liegt.

Das TryParseMuster von Microsoft verstößt gegen die Clean Code-Richtlinie, die besagt, dass Ausgabeparameter vermieden werden sollten.

Wenn wir keine neue Version von C # entwickeln, müssen wir uns nicht an alle Microsoft-Richtlinien halten. Manchmal sind sie nicht die Besten.

Glauber
quelle