Frage

Gibt es eine Möglichkeit durch mehrere case-Anweisungen zu fallen, ohne Angabe case value: wiederholt?

Ich weiß, 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 möchte so etwas tun:

switch (value)
{
   case 1,2,3:
      //Do Something
      break;
   case 4,5,6:
      //Do Something
      break;
   default:
      //Do the Default
      break;
}

Ist diese Syntax ich von einer anderen Sprache denke, oder bin ich etwas fehlt?

War es hilfreich?

Lösung

Es gibt keine Syntax in C ++ noch C # für die zweite Methode, die Sie erwähnt.

Es ist nichts falsch mit dem ersten Verfahren. Wenn Sie jedoch sehr große Bereiche haben, verwenden Sie nur eine Reihe von if-Anweisungen.

Andere Tipps

Ich denke, das bereits beantwortet wurde. Aber ich denke, dass Sie immer noch beide Möglichkeiten in einem syntaktisch besseren Weg mischen können, indem Sie:

switch (value)
{
case 1: case 2: case 3:          
    // Do Something
    break;
case 4: case 5: case 6: 
    // Do Something
    break;
default:
    // Do Something
    break;
}

Diese Syntax ist von dem Visual Basic wählen Sie ... Case-Anweisung :

Dim number As Integer = 8
Select Case number
    Case 1 To 5
        Debug.WriteLine("Between 1 and 5, inclusive")
        ' The following is the only Case clause that evaluates to True.
    Case 6, 7, 8
        Debug.WriteLine("Between 6 and 8, inclusive")
    Case Is < 1
        Debug.WriteLine("Equal to 9 or 10")
    Case Else
        Debug.WriteLine("Not between 1 and 10, inclusive")
End Select

Sie können diese Syntax in C # verwenden. Stattdessen müssen Sie die Syntax von Ihrem ersten Beispiel.

Ein bisschen spät für die ursprüngliche Frage, aber ich bin Entsendung diese Antwort in der Hoffnung, dass jemand eine neuere Version ( C # 7 verwenden - standardmäßig verfügbar in Visual Studio 2017 / .NET Framework 4.6.2 ), wird es hilfreich sein.

C # 7, bereichsbasierte Schalt ist nun möglich, mit der switch-Anweisung und würde sich mit dem Problem des OP helfen.

Beispiel:

int i = 5;

switch (i)
{
    case int n when (n >= 7):
        Console.WriteLine($"I am 7 or above: {n}");
        break;

    case int n when (n >= 4 && n <= 6 ):
        Console.WriteLine($"I am between 4 and 6: {n}");
        break;

    case int n when (n <= 3):
        Console.WriteLine($"I am 3 or less: {n}");
        break;
}

// Output: I am between 4 and 6: 5

Weitere Informationen:

  • Die Klammern ( und ) sind nicht im when Zustand erforderlich, werden aber in diesem Beispiel verwendet, um den Vergleich zu markieren (s).
  • var kann auch anstelle von int verwendet werden. Zum Beispiel:. case var n when n >= 7:

Sie können die Newline auslassen, die Sie gibt:

case 1: case 2: case 3:
   break;

aber ich halte den schlechten Stil.

.NET Framework 3.5 hat bekommt Bereiche:

Enumerable.Range von MSDN

können Sie es mit „enthält“ verwenden und die IF-Anweisung, da wie jemand sagte die SWITCH-Anweisung den „==“ Operator verwendet.

Hier ein Beispiel:

int c = 2;
if(Enumerable.Range(0,10).Contains(c))
    DoThing();
else if(Enumerable.Range(11,20).Contains(c))
    DoAnotherThing();

Aber ich denke, wir können mehr Spaß haben: da Sie nicht die Rückgabewerte benötigen und diese Aktion Parameter nicht nehmen, können Sie leicht Aktionen verwenden

public static void MySwitchWithEnumerable(int switchcase, int startNumber, int endNumber, Action action)
{
    if(Enumerable.Range(startNumber, endNumber).Contains(switchcase))
        action();
}

Das alte Beispiel mit dieser neuen Methode:

MySwitchWithEnumerable(c, 0, 10, DoThing);
MySwitchWithEnumerable(c, 10, 20, DoAnotherThing);

Da Sie Aktionen sind vorbei, nicht Werte, sollten Sie die Klammern weglassen, es ist sehr wichtig. Wenn Sie Funktion mit Argumenten müssen, ändern Sie einfach die Art der Action zu Action<ParameterType>. Wenn Sie Werte benötigen zurückzukehren, verwenden Sie Func<ParameterType, ReturnType>.

In C # 3.0 gibt es keine einfache Teil Anwendung die Tatsache das der Fall Parameter zu kapseln die gleiche, aber Sie ein kleines Hilfsmethode erstellen (ein bisschen ausführlicher, tho).

public static void MySwitchWithEnumerable(int startNumber, int endNumber, Action action){ 
    MySwitchWithEnumerable(3, startNumber, endNumber, action); 
}

Hier ist ein Beispiel dafür, wie neue funktionale importierte Aussage ist IMHO mächtiger und eleganter als die alte unbedingt ein.

@ Jennifer Owens: Sie sind absolut richtig der Code unten wird nicht funktionieren:

case 1 | 3 | 5:
//not working do something

Der einzige Weg, dies zu tun ist:

case 1: case 2: case 3:
// do something
break;

Der Code, den Sie für die Arbeiten auf Visual Basic suchen, wo man leicht Bereiche setzen können ... in keiner Möglichkeit, Schalter oder wenn sonst Blöcke bequem, würde ich vorschlagen, bei sehr extremen Punkt zu, DLL mit Visual Basic machen und importieren, um Ihre c # Projekt zurück.

. Hinweis: Schalter gleichwertig in Visual Basic wählen Fall

Eine andere Möglichkeit wäre eine Routine zu verwenden. Wenn alle Fälle 1-3 die gleiche Logik ausführen dann wickeln diese Logik in einer Routine, und nenne es für jeden Fall. Ich weiß, das eigentlich nicht bekommen die Beseitigung der Fall Aussagen, aber es funktioniert gut Stil umzusetzen und halten Wartung auf ein Minimum .....

[Bearbeiten] hinzugefügt alternative Implementierung ursprüngliche Frage passen ... [/ Edit]

switch (x)
{
   case 1:
      DoSomething();
      break;
   case 2:
      DoSomething();
      break;
   case 3:
      DoSomething();
      break;
   ...
}

private void DoSomething()
{
   ...
}

Alt

switch (x)
{
   case 1:
   case 2:
   case 3:
      DoSomething();
      break;
   ...
}

private void DoSomething()
{
   ...
}

Dies ist die komplette C # 7 Lösung ...

switch (value)
{
   case var s when new[] { 1,2,3 }.Contains(s):
      //Do Something
      break;
   case var s when new[] { 4,5,6 }.Contains(s):
      //Do Something
      break;
   default:
      //Do the Default
      break;
}

Arbeiten mit Strings zu ...

switch (mystring)
{
   case var s when new[] { "Alpha","Beta","Gamma" }.Contains(s):
      //Do Something
      break;
...
}

Eine weniger bekannte Facette von Schalter in C # ist, dass es stützt sich auf die operator = und da es Sie könnte so etwas wie diese haben werden außer Kraft gesetzt werden:


string s = foo();

switch (s) {
  case "abc": /*...*/ break;
  case "def": /*...*/ break;
}

gcc implementiert eine Erweiterung der Programmiersprache C Sequenzbereiche zu unterstützen:

switch (value)
{
   case 1...3:
      //Do Something
      break;
   case 4...6:
      //Do Something
      break;
   default:
      //Do the Default
      break;
}

Bearbeiten :. Bemerkte einfach den C # Tag auf der Frage, so vermutlich eine gcc Antwort nicht helfen

Eigentlich mag ich nicht den Befehl GOTO auch, aber es ist in der offiziellen MS Materialien, hier sind Syntaxen alle erlaubt.

Wenn der Endpunkt der Anweisungsliste eines Schalterabschnittes erreichbar ist, ein Fehler bei der Kompilierung auftritt. Dies wird als „kein Fall durch“ -Regel bekannt. Das Beispiel

switch (i) {
case 0:
   CaseZero();
   break;
case 1:
   CaseOne();
   break;
default:
   CaseOthers();
   break;
}

ist gültig, weil kein Schaltabschnitt einen erreichbaren Endpunkt hat. Im Gegensatz zu C und C ++, die Ausführung eines Schaltabschnitts ist nicht auf den nächsten Schaltabschnitt zu „fallen durch“ erlaubt, und das Beispiel

switch (i) {
case 0:
   CaseZero();
case 1:
   CaseZeroOrOne();
default:
   CaseAny();
}

führt zu einem Fehler bei der Kompilierung. Wenn die Ausführung eines Schaltabschnitt ist durch die Ausführung eines anderen Schaltabschnitt gefolgt werden kann, muss eine explizite goto Fall oder goto default-Anweisung verwendet werden:

switch (i) {
case 0:
   CaseZero();
   goto case 1;
case 1:
   CaseZeroOrOne();
   goto default;
default:
   CaseAny();
   break;
}

Mehrere Etiketten werden in einem Switch-Abschnitt erlaubt. Das Beispiel

switch (i) {
case 0:
   CaseZero();
   break;
case 1:
   CaseOne();
   break;
case 2:
default:
   CaseTwo();
   break;
}

ich in diesem speziellen Fall glauben, kann die GOTO verwendet werden, es ist tatsächlich der einzige Weg, um Durchfall.

Quelle: http: // msdn. microsoft.com/en-us/library/aa664749%28v=vs.71%29.aspx

Eine Menge Arbeit scheint in sein stellen Wege zu finden, einen von C # wenigsten verwendeten Syntaxen erhalten irgendwie besser aussehen oder besser funktionieren. Persönlich finde ich die Anweisung switch selten wert verwenden. Ich würde vorschlagen, stark zu analysieren, welche Daten Sie testen und das Ende Ergebnisse, die Sie wollen.

Nehmen wir zum Beispiel sagen, Sie wollen schnell testen, Werte in einem bekannten Bereich zu sehen, ob sie Primzahlen sind. Sie wollen Ihren Code tun, um die unnützen Berechnungen zu vermeiden, und Sie können eine Liste der Primzahlen im Bereich Sie wollen online finden. Sie könnten eine massive switch-Anweisung verwenden, um jeden Wert zu bekannte Primzahlen miteinander zu vergleichen.

Oder Sie könnten nur eine Reihe Karte von Primzahlen erstellen und sofort Ergebnisse:

    bool[] Primes = new bool[] {
        false, false, true, true, false, true, false,    
        true, false, false, false, true, false, true,
        false,false,false,true,false,true,false};
    private void button1_Click(object sender, EventArgs e) {
        int Value = Convert.ToInt32(textBox1.Text);
        if ((Value >= 0) && (Value < Primes.Length)) {
            bool IsPrime = Primes[Value];
            textBox2.Text = IsPrime.ToString();
        }
    }

Vielleicht möchten Sie sehen, ob ein Zeichen in einer Zeichenkette hexadezimal ist. Sie könnten einen ungly und etwas große switch-Anweisung verwenden.

Oder Sie könnten entweder reguläre Ausdrücke verwenden, um die Zeichen zu testen oder die IndexOf Funktion für die Zeichen in einer Reihe von bekannten hexadezimalen Buchstaben suchen:

        private void textBox2_TextChanged(object sender, EventArgs e) {
        try {
            textBox1.Text = ("0123456789ABCDEFGabcdefg".IndexOf(textBox2.Text[0]) >= 0).ToString();
        } catch {
        }
    }

Lassen Sie uns sagen, Sie eines von 3 verschiedenen Aktionen tun wollen auf einem Wert abhängig, dass der Bereich von 1 bis 24 sein wird, würde ich vorschlagen, eine Reihe von IF-Anweisungen. Und wenn die zu komplex worden (oder die Zahlen größer waren wie 5 verschiedene Aktionen auf einem Wert, abhängig im Bereich von 1 bis 90), dann eine ENUM verwenden, um die Aktionen zu definieren, und ein Array der Karte enums erstellen. Der Wert würde dann auf Index in das Array Karte verwendet werden und die Enum der Aktion Sie wollen. Verwenden Sie dann entweder einen kleinen Satz von IF-Anweisungen oder eine sehr einfache Switch-Anweisung des resultierenden Enum-Wert zu verarbeiten.

Auch das Schöne an einem Array Karte, die eine Reihe von Werten in die Tat umsetzt, ist, dass sie leicht durch Code geändert werden kann. Mit fest verdrahtetem Code, den Sie nicht so leicht können das Verhalten zur Laufzeit ändern, aber mit einer Reihe Karte ist es einfach.

Wenn Sie eine sehr große Menge an Schnur (oder jeden andere Art) Fall all das gleiche tun, empfahl ich die Verwendung einer String-Liste mit der string.Contains Eigenschaft kombiniert werden.

Wenn Sie also eine große switch-Anweisung haben etwa so:

switch (stringValue)
{
    case "cat":
    case "dog":
    case "string3":
    ...
    case "+1000 more string": //Too many string to write a case for all!
        //Do something;
    case "a lonely case"
        //Do something else;
    .
    .
    .
}

Vielleicht möchten Sie es mit einer if-Anweisung wie folgt ersetzt werden:

//Define all the similar "case" string in a List
List<string> listString = new List<string>(){ "cat", "dog", "string3", "+1000 more string"};
//Use string.Contains to find what you are looking for
if (listString.Contains(stringValue))
{
    //Do something;
}
else
{
    //Then go back to a switch statement inside the else for the remaining cases if you really need to
}

Diese Skala gut für eine beliebige Anzahl von String-Fall.

Dazu würden Sie eine goto-Anweisung verwenden. Wie zum Beispiel:

    switch(value){
    case 1:
        goto case 3;
    case 2:
        goto case 3;
    case 3:
        DoCase123();
    //This would work too, but I'm not sure if it's slower
    case 4:
        goto case 5;
    case 5:
        goto case 6;
    case 6:
        goto case 7;
    case 7:
        DoCase4567();
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top