Domanda

C'è un modo per cadere attraverso le molteplici casi di dichiarazioni, senza indicazione case value: più volte?

So che questo funziona:

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;
}

ma mi piacerebbe fare qualcosa di simile a questo:

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

È questa sintassi sto pensando da un lingua diversa, o mi manca qualcosa?

È stato utile?

Soluzione

Non c'è la sintassi del C++, né il C# per il secondo metodo che hai citato.

Non c'è niente di sbagliato con il primo metodo.Se, tuttavia, avete molto grandi portate, basta usare una serie di istruzioni if.

Altri suggerimenti

Credo che questo è stato già risposto.Tuttavia, penso che si possa ancora mix di entrambe le opzioni in una sintatticamente di meglio da fare:

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

Questa sintassi è da Visual Basic Istruzione Istruzione Select...Case:

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

Non è possibile utilizzare questa sintassi in C#.Invece, è necessario utilizzare la sintassi, il primo esempio.

Un po ' in ritardo per la domanda, ma sto postando questa risposta, nella speranza che qualcuno utilizza una versione più recente (C# 7 -- disponibile per impostazione predefinita in Visual Studio 2017/.NET Framework 4.6.2), sarà utile.

In C# 7, basato sull'intervallo di commutazione è ora possibile con l' istruzione switch e sarebbe di aiuto con l'OP del problema.

Esempio:

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

Note:

  • Le parentesi ( e ) non sono richieste nel when condizione, ma in questo esempio vengono utilizzati per evidenziare il confronto(s).
  • var può anche essere utilizzato in sostituzione di int.Per esempio: case var n when n >= 7:.

Si può lasciare fuori il carattere di nuova riga che ti dà:

case 1: case 2: case 3:
   break;

ma ritengo che un cattivo stile.

.NET Framework 3.5 ha intervalli:

Enumerabile.Gamma da MSDN

si può utilizzare con "contiene" e SE la dichiarazione, poiché, come ha detto qualcuno l'istruzione SWITCH utilizza l'operatore"==".

Qui un esempio:

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

Ma credo che possiamo avere più divertimento:visto che non sono necessari i valori di ritorno e questa azione non prende parametri, si può facilmente utilizzare le azioni!

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

Il vecchio esempio con questo nuovo metodo:

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

Dal momento che si sta passando azioni, non i valori, si deve omettere le parentesi, è molto importante.Se avete bisogno di una funzione con argomenti, basta cambiare il tipo di Action per Action<ParameterType>.Se avete bisogno di restituire i valori, utilizzare Func<ParameterType, ReturnType>.

In C# 3.0 non è facile Applicazione Parziale per incapsulare il fatto che il caso parametro è lo stesso, ma si crea un metodo di supporto (un po ' prolisso, tho).

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

Qui un esempio di come le nuove funzionale importati istruzione sono IMHO più potente e più elegante rispetto al vecchio imperativo uno.

@ Jennifer Owens:hai assolutamente ragione il seguente codice non funziona:

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

L'unico modo per farlo è:

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

Il codice che si sta cercando per lavori di visual basic in cui si può facilmente mettere le gamme...in nessuna opzione di switch o se altri blocchi convenienti, vi consiglio di a buon punto estremo, fare .dll con visual basic e importare di nuovo al vostro progetto c#.

Nota:interruttore equivalente in visual basic è select case.

Un'altra opzione sarebbe quella di utilizzare una routine.Se i casi 1-3 tutti eseguire la stessa logica, quindi avvolgere la logica in una routine e di chiamata per ogni caso.So che questo in realtà non sbarazzarsi del caso, di istruzioni, ma non implementare buon stile e mantenere al minimo la manutenzione.....

[Edit] Aggiunto implementazione alternativa per abbinare la domanda originale...[/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()
{
   ...
}

Qui è il completo C#7 soluzione...

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;
}

Funziona con corde troppo...

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

Uno meno conosciuto sfaccettatura di interruttore in C# è che si basa sul operatore= e dal momento che può essere sovrascritto si potrebbe avere qualcosa di simile a questo:


string s = foo();

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

gcc implementa un'estensione del linguaggio C per il supporto sequenziale intervalli:

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

Modifica:Appena notato il C# tag sulla questione, quindi, presumibilmente, un gcc risposta non aiuta.

In realtà non mi piace il comando GOTO troppo, ma è ufficiale MS materiali, qui sono tutti ammessi sintassi.

Se il punto finale dell'elenco di istruzione di un interruttore sezione è raggiungibile, un errore in fase di compilazione si verifica.Questo è noto come la "caduta attraverso" la regola.L'esempio

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

è valido perché non passare la sezione è raggiungibile punto finale.A differenza di C e C++, l'esecuzione di un interruttore di sezione non è consentito "fall through" per la prossima interruttore di sezione, e l'esempio

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

risultati in un errore di compilazione.Quando l'esecuzione di un interruttore di sezione, deve essere seguita dall'esecuzione di un'altra sezione, un esplicito goto caso o vai a default dichiarazione deve essere utilizzato:

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

Più etichette sono consentiti in un interruttore di sezione.L'esempio

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

Credo che in questo caso particolare, il GOTO può essere usato, è in realtà l'unico modo per fallthrough.

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

Un sacco di lavoro sembra essere stato messo in ricerca di modi per ottenere uno di C# almeno sintassi utilizzata per, in qualche modo, un aspetto migliore, o lavorare meglio.Personalmente trovo l'istruzione switch è raramente vale la pena utilizzare.Vorrei vivamente di analizzare i dati che si sono test e i risultati che si vogliono.

Diciamo per esempio che si desidera rapidamente i valori di prova in un determinato campo per vedere se sono numeri primi.Si vuole evitare di avere il vostro codice di fare inutili calcoli e non è possibile trovare un elenco di numeri primi nell'intervallo che si desidera online.Si potrebbe utilizzare una massiccia istruzione switch per confrontare ogni valore è noto che i numeri primi.

Oppure si potrebbe creare un array mappa dei primi e ottenere risultati immediati:

    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();
        }
    }

Forse si vuole verificare se un carattere in una stringa esadecimale.Si potrebbe utilizzare un ungly e un po ' di grandi dimensioni istruzione switch.

Oppure si potrebbe utilizzare espressioni regolari per verificare il char o IndexOf funzione per la ricerca di un carattere in una stringa di noto esadecimale lettere:

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

Diciamo che si desidera eseguire una delle 3 azioni diverse in base a un valore che va da 1 a 24.Vorrei suggerire l'utilizzo di un set di istruzioni IF.E se è diventato troppo complesso (O i numeri erano più grandi, come le 5 azioni diverse in base a un valore compreso nell'intervallo da 1 a 90) e poi utilizzare un enum per definire le azioni e creare un array mappa delle enumerazioni.Il valore dovrebbe quindi essere utilizzato per l'indice nell'array mappa e ottenere l'enumerazione di azione che si desidera.Quindi utilizzare un piccolo set di istruzioni IF o una semplice istruzione switch per elaborare il conseguente valore di enumerazione.

Inoltre, il bello di un array mappa che converte un intervallo di valori in azioni è che può essere facilmente modificato da codice.Con cavo codice non è possibile modificare facilmente il comportamento in fase di runtime, ma con una matrice mappa è facile.

Se si dispone di una grande quantità di stringa (o di qualsiasi altro tipo) Caso tutti a fare la stessa cosa, mi consiglia l'utilizzo di un Elenco di stringhe combinato con la stringa.Contiene proprietà.

Quindi, se si dispone di una grande istruzione switch in questo modo:

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;
    .
    .
    .
}

Si potrebbe desiderare di sostituire con un'istruzione if simile a questo:

//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
}

Questo si adatta bene per qualsiasi numero di stringa caso.

Per questo, utilizzare un'istruzione goto.Ad esempio:

    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();
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top