Stellen Sie sich den folgenden Code vor:
void DoThis()
{
if (!isValid) return;
DoThat();
}
void DoThat() {
Console.WriteLine("DoThat()");
}
Ist es in Ordnung, eine Rückgabe innerhalb einer void-Methode zu verwenden? Hat es eine Leistungsstrafe? Oder es wäre besser, einen Code wie diesen zu schreiben:
void DoThis()
{
if (isValid)
{
DoThat();
}
}
Antworten:
Eine Rückgabe in einer void-Methode ist nicht schlecht. Es ist üblich, Anweisungen zu invertieren
if
, um die Verschachtelung zu verringern .Und weniger Verschachtelung Ihrer Methoden verbessert die Lesbarkeit und Wartbarkeit des Codes.
Wenn Sie eine void-Methode ohne return-Anweisung haben, generiert der Compiler am Ende immer eine ret-Anweisung .
quelle
Es gibt noch einen weiteren wichtigen Grund für die Verwendung von Guards (im Gegensatz zu verschachteltem Code): Wenn ein anderer Programmierer Ihrer Funktion Code hinzufügt, arbeiten diese in einer sichereren Umgebung.
Erwägen:
gegen:
Stellen Sie sich nun vor, ein anderer Programmierer fügt die Zeile hinzu: obj.DoSomethingElse ();
Dies ist natürlich ein vereinfachter Fall, aber der Programmierer hat dem Programm in der ersten Instanz (verschachtelter Code) einen Absturz hinzugefügt. Im zweiten Beispiel (vorzeitiger Ausstieg mit Wachen) ist Ihr Code vor unbeabsichtigter Verwendung einer Nullreferenz geschützt, sobald Sie an der Wache vorbeikommen.
Sicher, ein großartiger Programmierer macht solche Fehler (oft) nicht. Aber Vorbeugen ist besser als Heilen - wir können den Code so schreiben, dass diese potenzielle Fehlerquelle vollständig beseitigt wird. Das Verschachteln erhöht die Komplexität. Daher empfehlen Best Practices, Code umzugestalten, um das Verschachteln zu reduzieren.
quelle
Schlechte Praxis ??? Auf keinen Fall. Tatsächlich ist es immer besser, Validierungen zu behandeln, indem Sie frühestens von der Methode zurückkehren, wenn die Validierungen fehlschlagen. Andernfalls würde es zu einer großen Anzahl verschachtelter Wenns und Sonstiges kommen. Ein vorzeitiges Beenden verbessert die Lesbarkeit des Codes.
Überprüfen Sie auch die Antworten auf eine ähnliche Frage: Soll ich die return / continue-Anweisung anstelle von if-else verwenden?
quelle
Es ist keine schlechte Praxis (aus allen bereits genannten Gründen). Je mehr Renditen eine Methode hat, desto wahrscheinlicher sollte sie in kleinere logische Methoden aufgeteilt werden.
quelle
Das erste Beispiel verwendet eine Guard-Anweisung. Aus Wikipedia :
Ich denke, ein paar Wachen an der Spitze einer Methode zu haben, ist eine vollkommen verständliche Art zu programmieren. Grundsätzlich heißt es: "Führen Sie diese Methode nicht aus, wenn eine dieser Methoden zutrifft."
Im Allgemeinen würde es also so aussehen:
Ich denke, das ist dann viel besser lesbar:
quelle
Es gibt keine Leistungseinbußen, der zweite Code ist jedoch besser lesbar und daher einfacher zu warten.
quelle
In diesem Fall ist Ihr zweites Beispiel besserer Code, aber das hat nichts mit der Rückkehr von einer void-Funktion zu tun, sondern einfach, weil der zweite Code direkter ist. Aber die Rückkehr von einer leeren Funktion ist völlig in Ordnung.
quelle
Es ist vollkommen in Ordnung und keine Leistungseinbußen, aber schreiben Sie niemals eine Wenn-Anweisung ohne Klammern.
Immer
Es ist viel besser lesbar; und Sie werden niemals versehentlich davon ausgehen, dass einige Teile des Codes in dieser Anweisung enthalten sind, wenn dies nicht der Fall ist.
quelle
{
. Dies stimmt{
mit Ihrer}
in derselben Spalte überein, was die Lesbarkeit erheblich verbessert (viel einfacher, entsprechende Klammern zum Öffnen / Schließen zu finden).if
es einfach, visuell zu unterscheiden, welche Anweisungen enge Klammern erfordern, und daherif
ist es sicher, wenn Anweisungen eine einzelne Anweisung steuern. Durch Zurückschieben der offenen Klammer auf die Linie mitif
spart eine Linie vertikalen Raums bei jeder Mehrfachanweisungif
, erfordert jedoch die Verwendung einer ansonsten unnötigen engen Klammer.Ich werde mit all Ihren jungen Whippersnappern in dieser Sache nicht einverstanden sein.
Die Verwendung von Return mitten in einer Methode, ungültig oder auf andere Weise, ist aus Gründen, die der verstorbene Edsger W. Dijkstra vor fast vierzig Jahren ganz klar formuliert hat, sehr schlecht, beginnend mit der bekannten "GOTO Statement Considered Harmful" "und weiter in" Structured Programming "von Dahl, Dijkstra und Hoare.
Die Grundregel lautet, dass jede Kontrollstruktur und jedes Modul genau einen Eintrag und einen Ausgang haben sollte. Eine explizite Rückgabe in der Mitte des Moduls verstößt gegen diese Regel und macht es viel schwieriger, über den Status des Programms nachzudenken, was es wiederum viel schwieriger macht zu sagen, ob das Programm korrekt ist oder nicht (was eine viel stärkere Eigenschaft ist als "ob es zu funktionieren scheint oder nicht").
"GOTO Statement als schädlich" und "Structured Programming" leiteten die Revolution der "Structured Programming" der 1970er Jahre ein. Diese beiden Teile sind die Gründe, warum wir heute if-then-else, while-do und andere explizite Kontrollkonstrukte haben und warum GOTO-Anweisungen in Hochsprachen auf der Liste der gefährdeten Arten stehen. (Meine persönliche Meinung ist, dass sie auf der Liste der ausgestorbenen Arten stehen müssen.)
Es ist erwähnenswert, dass der Message Flow Modulator, die erste militärische Software, die EVER beim ersten Versuch ohne Abweichungen, Verzichtserklärungen oder "Ja, aber" -Sprache bestanden hat, in einer Sprache geschrieben wurde, die es nicht einmal gab eine GOTO-Anweisung.
Erwähnenswert ist auch, dass Nicklaus Wirth die Semantik der RETURN-Anweisung in Oberon-07, der neuesten Version der Oberon-Programmiersprache, geändert hat und sie zu einem nachfolgenden Teil der Deklaration einer typisierten Prozedur (dh einer Funktion) und nicht zu einer ausführbare Anweisung im Hauptteil der Funktion. Seine Erklärung der Änderung sagte , dass er gerade tat , weil die bisherige Form WAR eine Verletzung des Ein-Ausgang Prinzip der strukturierten Programmierung.
quelle
Ausnahme auslösen, anstatt nichts zurückzugeben, wenn das Objekt null ist usw.
Ihre Methode erwartet, dass das Objekt nicht null ist und dies nicht der Fall ist. Sie sollten daher eine Ausnahme auslösen und den Aufrufer damit umgehen lassen.
Aber eine frühzeitige Rückkehr ist sonst keine schlechte Praxis.
quelle