2009-10-14 15 views
13

Ich frage mich, warum C# erfordert, dass ich break in einer switch-Anweisung verwenden, obwohl eine Durchgriffs-Semantik per Definition nicht zulässig ist. Daher könnte der Compiler die break am Ende jedes case-Blocks erzeugen und mir den Ärger ersparen.Warum brauche ich Pause?

Allerdings gibt es ein Szenario (die bereits auf dieser Seite diskutiert wurde), die ich mit, dass einfiel könnte der Grund für die explizite Verwendung von break sein:

switch (foo) { 
    case 0: 
    case 1: 
     bar(); 
     break; 
    default: 
     break; 
} 

Hier wird das Verfahren bar() wird aufgerufen, wenn foo entweder den Wert 0 oder 1 hat.

Diese Option würde im wahrsten Sinne des Wortes brechen, wenn der Compiler würde break Anweisungen selbst generieren. Ist dies der Grund, warum die Pause obligatorisch ist oder gibt es noch andere gute Gründe?

+7

Ich persönlich denke, das war eine schreckliche Designentscheidung des C# -Teams und einer der wenigen Orte, an denen sie versagten. –

+0

@Chris: Ich empfehle Ihnen sehr, den Blog von Eric in der angenommenen Antwort zu lesen. Es behandelt mehrere Dinge, die ich vermute, sind Dinge, die Sie verärgert haben. –

+3

Und wie hättest du es gemacht, Chris? –

Antwort

33

Ich vermute, dass der Grund, warum C# erfordert, dass der Entwickler eine Pause oder Terminal-Anweisung am Ende jedes Falles setzt, der Klarheit dient.

Es vermeidet Neulinge in der Sprache aus der Annahme, dass switch() in C# verhält sich wie Schalter in C oder C++, wo Fall-through-Verhalten auftritt. Nur in den Fällen von benachbarten leeren Fällen treten Durchfälle in C# auf - was relativ offensichtlich ist.

EDIT: Eigentlich in C# Fallout ist immer illegal. Was legal ist, ist jedoch, dass ein einzelner Fall mit zwei oder mehr Etiketten verbunden ist. Eric Lippert writes at length about this Verhalten and how it differs from C/C++ switch statements.

Sie könnten interessiert sein zu lesen this article auf Eric Lipperts Blog.

+0

+1 für den Link zu Eric Lippert, äh, Blog ;-). Ja, es könnte Klarheit sein, die diese Designentscheidung beeinflusst hat. –

+0

Es ermöglicht auch die JIT-Flexibilität, den Code für Optimierungen neu anzuordnen, ohne sich Sorgen zu machen, dass aufgrund von Durchschlägen etwas kaputt geht. –

+0

@ScottDorman - Es gibt kein Durchfallen ... also würde die Reorganisation nichts ändern, wenn die Pause nicht da wäre. Wenn es einen Durchgriff gab und die Neuordnung des Codes ein Problem verursachen könnte, wäre die Pause sowieso nicht erforderlich. – RHSeeger

0

Mein Verständnis der Sache ist, dass es enthalten war, um C++ - Syntax zu entsprechen.

+6

Hm, aber AFAIK C++ benötigt keine break-Anweisung, da C++ - wie C - Case-Blöcke zulässt durchfallen. –

6

Durch Pause optional zu machen, öffnen Sie sich wie diese Fehler auf:

switch (thing_result) 
{ 
    case GOOD_THING: 
     IssueReward(); 
     // UH-OH, missing break! 
    case BAD_THING: 
     IssuePunishment(); 
     break; 
} 

Die Sprache C# Designer versucht haben Programmierer Fallen in den Sprachen vermeiden zu helfen, die vor ihm da waren, in der Regel durch den Programmierer zwingen, expliziter sein (z. B. explizite Verwendung des Schlüsselwortes 'override' oder 'new' zum Implementieren oder Spiegeln virtueller Member).

0

Wenn Sie nicht eine Pause anhängen müssen, ist es ein Problem

switch (number) 
{ 
    case 0: 
    case 1: 
     DoSomething(); 
} 

Was 0, wenn Nummer == passiert? Ist das ein leerer Fall, der nichts tut oder wird DoSomething() ausgeführt?

+1

Sorry, aber das stimmt nicht. Wenn Sie nach dem DoSomething() - Aufruf eine Pause hinzufügen, wäre der C# -Code gültig und für beide Fälle, 0 und 1, würde die DoSomething() -Methode aufgerufen. –

+1

@RHSeeger, du liegst falsch. – Phong

+0

@Phong, ich entfernte meinen Kommentar, weil ein Teil davon korrekt war. Es war richtig, dass die break-Anweisung nur Ausführlichkeit hinzufügt und Verwirrung nicht vermeidet. Aber es war inkorrekt, dass der 0 Fall etwas tut, was der 1 Fall tut, da er den Körper mit dem 1 Fall teilt. – RHSeeger

38

Die Frage setzt eine Lüge voraus und kann daher nicht beantwortet werden. Die Sprache benötigt keine Pause am Ende eines Switch-Abschnitts. Die Sprache erfordert, dass die Anweisungsliste eines Switch-Abschnitts einen unerreichbaren Endpunkt haben muss. "break" ist nur die am häufigsten verwendete Anweisung mit dieser Eigenschaft. Es ist vollkommen legal, einen Switch-Abschnitt mit "return" zu beenden, "gehe zu Case 2;", "new Exception()"; oder "while (true) {}" (oder in einigen Fällen weiter, obwohl das normalerweise eine schlechte Idee ist.)

Der Grund, warum wir eine Anweisungsliste mit einem nicht erreichbaren Endpunkt benötigen, besteht darin, die Regel "Kein Durchfallen" durchzusetzen .

Wenn Ihre Frage besser lautet als "Warum korrigiert der Compiler meinen Fehler nicht automatisch, wenn ich einen Schalterabschnitt mit einer Anweisungsliste mit einem unerreichbaren Endpunkt nicht erzeugen kann, indem ich eine Break-Anweisung in meinem Namen einfüge?" , dann ist die Antwort, dass C# kein "Vermuten Sie, was der Entwickler wahrscheinlich meinte und sich durch" Art von Sprache durchmischen. Einige Sprachen sind - JScript zum Beispiel - aber C# ist nicht.

Wir glauben, dass C# -Programmierer, die Fehler machen, über diese Fehler informiert werden sollen, damit sie sie absichtlich und absichtlich korrigieren können, und dass dies eine gute Sache ist. Unsere Kunden sagen uns, dass sie nicht wollen, dass der Compiler rät, was sie meinen und auf das Beste hoffen. Deshalb macht C# auch keine Vermutung darüber, wo Sie das fehlende Semikolon platzieren sollten, wie es bei JScript der Fall ist, oder es schlägt automatisch fehl, wenn Sie versuchen, eine schreibgeschützte Variable wie JScript zu modifizieren usw.

+4

?? Die angenommene Antwort bezieht sich auf Erics Blog und seine eigene Antwort wird abgelehnt. Wieder abgestimmt. – SolutionYogi

+1

Nun, SolutionYogi, stimmt nicht jeder mit mir überein. Ich habe keinen Grund, mir vorzustellen, dass alle es tun würden; Jeder hat ein Recht auf seine eigene Meinung darüber, warum die Sprache so gestaltet wurde, wie sie war. Ich schätze die Geste, aber wirklich, betonen Sie nicht darüber. :) –

+0

Nun, Eric, ich stimme dir zu 100% zu und ich möchte mit meiner Stimme mitspielen, damit andere auf deine Antwort achten! Und ich betone überhaupt nicht darüber. Ich folge Ihren SO Antworten/Kommentaren religiös, da ich sehr viel von ihnen lerne. Sie sind nicht nur sehr sachkundig, sondern Sie teilen Ihr Wissen durch Ihr tadelloses Schreiben. Ich bin ein großer Fan von dir und wenn du in NJ/NY bist, lass es mich wissen, ich möchte dir Getränke/Abendessen kaufen! :) – SolutionYogi

Verwandte Themen