it-swarm.com.de

Verwendet noch jemand [goto] in C # und wenn ja, warum?

Ich habe mich gefragt, ob noch jemand die "goto" -Syntax für Schlüsselwörter in C # verwendet und welche möglichen Gründe dafür vorliegen.

Ich neige dazu, Aussagen, die den Leser veranlassen, den Code zu umgehen, als schlechte Praxis anzusehen, frage mich jedoch, ob es glaubwürdige Szenarien für die Verwendung einer solchen Syntax gibt.

Gehe zu Keyword-Definition

95
Brian Scott

Es gibt einige (seltene) Fälle, in denen goto die Lesbarkeit verbessern kann. In der Dokumentation, die Sie verlinkt haben, sind zwei Beispiele aufgeführt:

Eine gebräuchliche Verwendung von goto besteht darin, die Kontrolle auf ein bestimmtes Schalteretikett oder das Standardetikett in einer switch-Anweisung zu übertragen.

Die goto-Anweisung ist auch nützlich, um tief verschachtelte Schleifen zu verlassen.

Hier ist ein Beispiel für Letzteres:

for (...) {
    for (...) {
        ...
        if (something)
            goto end_of_loop;
    }
}

end_of_loop:

Natürlich gibt es auch andere Möglichkeiten, um dieses Problem zu umgehen, z. B. das Umgestalten des Codes in eine Funktion, die Verwendung eines Dummy-Blocks usw. (Details siehe diese Frage ). Als Randnotiz haben die Java Sprachdesigner beschlossen, goto vollständig zu verbieten und stattdessen eine Labeled Break Anweisung einzuführen.

86
Heinzi

Ich erinnere mich an diesen Teil

switch (a)     
{ 
    case 3: 
        b = 7;
        // We want to drop through into case 4, but C# doesn't let us
    case 4: 
        c = 3;
        break; 
    default: 
        b = 2;
        c = 4;
        break; 
}

Auf so etwas

switch (a)     
{
    case 3: 
        b = 7;
        goto case 4;    
    case 4: 
        c = 3;
        break;     
    default: 
        b = 2;
        c = 4;
        break;
}

Siehe This

62
V4Vendetta

Ich benutze es ausgiebig in Eduasync , um die Art von Code anzuzeigen, die der Compiler für Sie generiert, wenn Sie in C # 5 asynchrone Methoden verwenden. Dasselbe sehen Sie in Iteratorblöcken.

Im "normalen" Code kann ich mich nicht erinnern, wann ich ihn das letzte Mal benutzt habe ...

22
Jon Skeet

goto ist großartig, um aus vielen Schleifen auszubrechen, in denen break nicht gut funktioniert (etwa bei Fehlerbedingungen), und wie Kragen sagte, wird goto vom Compiler verwendet, um switch-Anweisungen und einige andere Dinge zu generieren.

8
Jesus Ramos

Ich erinnere mich nicht, jemals goto benutzt zu haben. Aber vielleicht es verbessert die Absicht einer Endlosschleife, die Sie wirklich nie beenden möchten (kein break, aber Sie können immer noch return oder throw):

forever: {
  // ...
  goto forever;
}

Andererseits sollte eine einfache while (true) ausreichen ...

Außerdem können Sie could in einer Situation verwenden, in der die erste Iteration einer Schleife in der Mitte der Schleife beginnen soll: Schauen Sie sich hier für ein Beispiel an.

6
Jordão

Der Compiler verwendet goto -Anweisungen in verschiedenen generierten Codeteilen, z. B. in generierten Iteratorblocktypen (generiert bei Verwendung von yield return keyword - Ich bin mir ziemlich sicher, dass die generierten XML-Serialisierungstypen auch irgendwo ein paar goto -Anweisungen enthalten.

Weitere Informationen darüber, warum/wie der C # -Compiler dies handhabt, finden Sie unter Implementierungsdetails für Iteratorblöcke: automatisch generierte Statusmaschinen .

Anders als bei generiertem Code gibt es keinen guten Grund, eine goto -Anweisung in normalem Code zu verwenden - dies erschwert das Verständnis des Codes und macht ihn daher fehleranfälliger. Andererseits kann die Verwendung von goto -Anweisungen in diesem generierten Code den Generierungsprozess vereinfachen und ist normalerweise in Ordnung, da niemand den generierten Code lesen (oder ändern) wird und keine Gefahr besteht, dass Fehler gemacht werden, weil a Maschine macht das Schreiben.

Siehe Go-to-Anweisung, die als schädlich eingestuft wird für ein Argument gegen goto sowie ein klassisches Stück Programmiergeschichte.

5
Justin

Der Prozessor implementiert mindestens eine Sprunganweisung , und ich bin sicher, dass viele Anweisungen diese in ihrer Implementierung oder Interpretation verwenden.

Eines der guten Dinge bei der Verwendung einer dritten oder vierten Generation ist dass diese physischen Details von uns weg abstrahiert werden. Während wir uns des Gesetzes der undichten Abstraktion bewusst sein sollten , denke ich, dass wir auch unsere Werkzeuge so verwenden sollten, wie sie sind beabsichtigt (es tut uns leid). Wenn ich Code schreiben würde und ein goto eine gute Idee wäre, wäre es an der Zeit, eine Umgestaltung vorzunehmen. Der Zweck einer strukturierten Sprache ist es, diese "Sprünge" zu vermeiden und einen logischen Ablauf in unserem Engineering zu erzeugen.

Ich sollte die Verwendung von break vermeiden, aber ich kann den Leistungsvorteil nicht übersehen. Wenn ich jedoch verschachtelte Schleifen habe, die gegenseitig break benötigen, ist es Zeit, eine Umgestaltung durchzuführen.

Wenn jemand eine Verwendung von goto vorschlagen kann, die besser erscheint als ein Refactoring, werde ich meine Antwort gerne zurückziehen.

Ich hoffe, ich bin nicht schuldig, hier zum " Fahrradschuppen " zu eilen. Wie Kragen sagt, ist das, was gut genug für Dijkstra ist, gut genug für mich.

2
Jodrell