Gibt es eine Möglichkeit, mehrere Fallaussagen durchzugehen, ohne sie case value:
wiederholt anzugeben ?
Ich weiß, dass das funktioniert:
switch (value)
{
case 1:
case 2:
case 3:
// Do some stuff
break;
case 4:
case 5:
case 6:
// Do some different stuff
break;
default:
// Default stuff
break;
}
aber ich würde gerne so etwas machen:
switch (value)
{
case 1,2,3:
// Do something
break;
case 4,5,6:
// Do something
break;
default:
// Do the Default
break;
}
Ist diese Syntax, an die ich denke, aus einer anderen Sprache oder fehlt mir etwas?
c#
switch-statement
Das Ö
quelle
quelle
,
, die mit keiner anderen Sprache im C-Stil geteilt wird. Das würde mir viel schmutziger erscheinen.Antworten:
Es gibt weder in C ++ noch in C # eine Syntax für die zweite Methode, die Sie erwähnt haben.
An Ihrer ersten Methode ist nichts auszusetzen. Wenn Sie jedoch sehr große Bereiche haben, verwenden Sie einfach eine Reihe von if-Anweisungen.
quelle
Ich denke, das wurde bereits beantwortet. Ich denke jedoch, dass Sie beide Optionen immer noch syntaktisch besser mischen können, indem Sie Folgendes tun:
quelle
Diese Syntax stammt aus der Visual Basic Select ... Case-Anweisung :
Sie können diese Syntax nicht in C # verwenden. Stattdessen müssen Sie die Syntax aus Ihrem ersten Beispiel verwenden.
quelle
In C # 7 (standardmäßig in Visual Studio 2017 / .NET Framework 4.6.2 verfügbar) ist eine bereichsbasierte Umschaltung jetzt mit der switch-Anweisung möglich und würde beim OP-Problem helfen.
Beispiel:
Anmerkungen:
(
und)
sind in derwhen
Bedingung nicht erforderlich , werden jedoch in diesem Beispiel verwendet, um die Vergleiche hervorzuheben.var
kann auch anstelle von verwendet werdenint
. Zum Beispiel :case var n when n >= 7:
.quelle
Sie können die neue Zeile weglassen, die Ihnen Folgendes gibt:
aber ich halte diesen schlechten Stil.
quelle
.NET Framework 3.5 hat folgende Bereiche:
Enumerable.Range von MSDN
Sie können es mit "enthält" und der IF-Anweisung verwenden, da die SWITCH-Anweisung, wie jemand sagte, den Operator "==" verwendet.
Hier ein Beispiel:
Aber ich denke, wir können mehr Spaß haben: Da Sie die Rückgabewerte nicht benötigen und diese Aktion keine Parameter akzeptiert, können Sie problemlos Aktionen verwenden!
Das alte Beispiel mit dieser neuen Methode:
Da Sie Aktionen und keine Werte übergeben, sollten Sie die Klammer weglassen. Dies ist sehr wichtig. Wenn Sie eine Funktion mit Argumenten benötigen, ändern Sie einfach den Typ von
Action
inAction<ParameterType>
. Wenn Sie Rückgabewerte benötigen, verwenden SieFunc<ParameterType, ReturnType>
.In C # 3.0 gibt es keine einfache Teilanwendung , um die Tatsache zu kapseln, dass der case-Parameter derselbe ist, aber Sie erstellen eine kleine Hilfsmethode (ein bisschen ausführlich, tho).
Hier ein Beispiel dafür, wie neue funktionale importierte Anweisungen meiner Meinung nach mächtiger und eleganter sind als die alte imperative.
quelle
int start
undint count
. Ihre Beispiele funktionieren nicht so, wie sie geschrieben wurden. Sie schreiben es so, als wäre das zweite Argumentint end
. Zum Beispiel -Enumerable.Range(11,20)
würde zu 20 Zahlen führen, die mit 11 beginnen, und nicht zu Zahlen von 11 bis 20.Enumerable.Range(11,20).Contains(c)
gleichbedeutend ist mitfor(int i = 11; i < 21; ++i){ if (i == c) return true; } return false;
Wenn Sie eine große Reichweite hätten, würde es eine lange Zeit dauern, während Sie nur verwenden,>
und<
wäre schnell und konstant.MySwitchWithEnumerable
Rückkehrvoid
ist ein schwaches Design für diese Situation. GRUND: Sie haben eineif-else
in eine Reihe unabhängiger Anweisungen konvertiert - das verbirgt die Absicht, dass sie sich gegenseitig ausschließen - nur eineaction
wird ausgeführt. Kehren Sie stattdessenbool
mit body zurück.if (..) { action(); return true; } else return false;
Die aufrufende Site zeigt dann die Absicht :if (MySwitchWithEnumerable(..)) else (MySwitchWithEnumerable(..));
. Dies ist vorzuziehen. In diesem einfachen Fall ist dies jedoch keine wesentliche Verbesserung gegenüber Ihrer Originalversion mehr.Hier ist die komplette C # 7-Lösung ...
Es funktioniert auch mit Strings ...
quelle
Der folgende Code funktioniert nicht :
Der einzige Weg, dies zu tun, ist:
Der Code, nach dem Sie suchen, funktioniert in Visual Basic, wo Sie problemlos Bereiche einfügen können. In der
none
Option derswitch
Anweisung oder derif else
Blöcke, die praktisch sind, würde ich vorschlagen, im Extremfall .dll mit Visual Basic zu erstellen und zurück zu importieren zu Ihrem C # -Projekt.Hinweis: Das Switch-Äquivalent in Visual Basic lautet
Select Case
.quelle
Eine andere Möglichkeit wäre die Verwendung einer Routine. Wenn die Fälle 1 bis 3 alle dieselbe Logik ausführen, verpacken Sie diese Logik in eine Routine und rufen Sie sie für jeden Fall auf. Ich weiß, dass dies die case-Anweisungen nicht wirklich beseitigt, aber es implementiert einen guten Stil und hält die Wartung auf ein Minimum .....
[Bearbeiten] Alternative Implementierung hinzugefügt, um der ursprünglichen Frage zu entsprechen ... [/ Bearbeiten]
Alt
quelle
Eine weniger bekannte Facette des Schalters in C # ist, dass er vom Operator abhängt = und da er überschrieben werden kann, könnten Sie Folgendes haben:
quelle
gcc implementiert eine Erweiterung der C-Sprache, um sequentielle Bereiche zu unterstützen:
Bearbeiten : Ich habe gerade das C # -Tag auf der Frage bemerkt, daher hilft vermutlich eine gcc-Antwort nicht weiter.
quelle
In C # 7 haben wir jetzt Pattern Matching, damit Sie Folgendes tun können:
quelle
Eigentlich mag ich den GOTO-Befehl auch nicht, aber er ist in offiziellen Microsoft-Materialien enthalten, und hier sind alle zulässigen Syntaxen.
Wenn der Endpunkt der Anweisungsliste eines Switch-Abschnitts erreichbar ist, tritt ein Fehler bei der Kompilierung auf. Dies ist als "No Fall Through" -Regel bekannt. Das Beispiel
ist gültig, da kein Schalterabschnitt einen erreichbaren Endpunkt hat. Im Gegensatz zu C und C ++ darf die Ausführung eines Switch-Abschnitts nicht zum nächsten Switch-Abschnitt und zum Beispiel "durchfallen"
führt zu einem Fehler bei der Kompilierung. Wenn auf die Ausführung eines Switch-Abschnitts die Ausführung eines anderen Switch-Abschnitts folgen soll, muss ein expliziter goto-Fall oder eine goto-Standardanweisung verwendet werden:
In einem Schalterabschnitt sind mehrere Beschriftungen zulässig. Das Beispiel
Ich glaube, in diesem speziellen Fall kann das GOTO verwendet werden, und es ist tatsächlich der einzige Weg, durchzufallen.
Quelle: http://msdn.microsoft.com/en-us/library/aa664749%28v=vs.71%29.aspx
quelle
goto
fast immer vermieden werden kann (obwohl ich es hier nicht als "schrecklich" betrachte - es erfüllt eine bestimmte, strukturierte Rolle). In Ihrem Beispiel kann Fall 0 werden, da Sie die Fallkörper in Funktionen eingewickelt haben (eine gute Sache)CaseZero(); CaseZeroOrOne(); break;
. Nichtgoto
erforderlich.Es scheint eine Menge Arbeit investiert worden zu sein, um Wege zu finden, wie eine der am wenigsten verwendeten C # -Syntaxen irgendwie besser aussehen oder besser funktionieren kann. Persönlich finde ich, dass die switch-Anweisung selten eine Verwendung wert ist. Ich würde dringend empfehlen, zu analysieren, welche Daten Sie testen und welche Endergebnisse Sie wünschen.
Angenommen, Sie möchten Werte in einem bekannten Bereich schnell testen, um festzustellen, ob es sich um Primzahlen handelt. Sie möchten vermeiden, dass Ihr Code die verschwenderischen Berechnungen durchführt, und Sie können eine Liste von Primzahlen in dem Bereich finden, den Sie online möchten. Sie können eine massive switch-Anweisung verwenden, um jeden Wert mit bekannten Primzahlen zu vergleichen.
Oder Sie können einfach eine Array-Karte mit Primzahlen erstellen und sofort Ergebnisse erzielen:
Vielleicht möchten Sie sehen, ob ein Zeichen in einer Zeichenfolge hexadezimal ist. Sie könnten eine ungly und etwas große switch-Anweisung verwenden.
Oder Sie können entweder reguläre Ausdrücke verwenden, um das Zeichen zu testen, oder die IndexOf-Funktion verwenden, um nach dem Zeichen in einer Zeichenfolge bekannter hexadezimaler Buchstaben zu suchen:
Angenommen, Sie möchten eine von drei verschiedenen Aktionen ausführen, abhängig von einem Wert im Bereich von 1 bis 24. Ich würde vorschlagen, eine Reihe von IF-Anweisungen zu verwenden. Und wenn dies zu komplex wurde (oder die Zahlen größer waren, z. B. 5 verschiedene Aktionen, abhängig von einem Wert im Bereich von 1 bis 90), verwenden Sie eine Aufzählung, um die Aktionen zu definieren und eine Array-Karte der Aufzählungen zu erstellen. Der Wert wird dann verwendet, um in die Array-Map zu indizieren und die Aufzählung der gewünschten Aktion abzurufen. Verwenden Sie dann entweder eine kleine Menge von IF-Anweisungen oder eine sehr einfache switch-Anweisung, um den resultierenden Enum-Wert zu verarbeiten.
Das Schöne an einer Array-Map, die einen Wertebereich in Aktionen konvertiert, ist, dass sie leicht per Code geändert werden kann. Mit fest verdrahtetem Code können Sie das Verhalten zur Laufzeit nicht einfach ändern, aber mit einer Array-Map ist dies einfach.
quelle
Um die Konversation mit .NET 4.6.2 zu erweitern, konnte ich auch Folgendes tun. Ich habe den Code getestet und es hat bei mir funktioniert.
Sie können auch mehrere "ODER" -Anweisungen ausführen, wie unten:
Sie können auch überprüfen, ob es mit einem Wert in einem Array übereinstimmt:
quelle
Wenn Sie eine sehr große Anzahl von Zeichenfolgen (oder einen anderen Typ) haben, die alle dasselbe tun, empfehle ich die Verwendung einer Zeichenfolgenliste in Kombination mit der Eigenschaft string.Contains.
Wenn Sie also eine große switch-Anweisung wie diese haben:
Vielleicht möchten Sie es durch eine
if
Anweisung wie die folgende ersetzen :Diese Skala eignet sich gut für eine beliebige Anzahl von Zeichenfolgenfällen.
quelle
Ich denke, dieser ist besser in C # 7 oder höher.
Sie können den Bereich auch im C # -Schalter prüfen: Schalterfall: Kann ich einen Bereich anstelle einer Zahl verwenden ? Oder wenn Sie die Grundlagen des C # -Schaltergehäuses verstehen möchten
quelle
Dazu würden Sie eine goto-Anweisung verwenden. Sowie:
quelle
goto
. Schlimmer noch, es ist eine völlig unnötige Verwendunggoto
, da die von OP angegebene ursprüngliche Syntax funktioniert. Die Frage war, ob es eine präzisere Möglichkeit gab, die alternativen Fälle anzugeben. Wie die Leute Jahre zuvor geantwortet haben , gibt es ja - wenn Sie bereit sind, die mehreren Fälle in eine Zeile zu setzencase 1: case 2:
, und wenn der automatische Stil des Editors dies zulässt.