web-dev-qa-db-fra.com

Changer de cas: puis-je utiliser une plage au lieu d'un seul numéro

Je veux utiliser switch, mais j'ai beaucoup de cas, y a-t-il un raccourci? Jusqu'à présent, la seule solution que je connaisse et que j'essaye est:

switch (number)
{
case 1: something; break;
case 2: other thing; break;
...
case 9: .........; break;
}

J'espère pouvoir faire quelque chose comme:

switch (number)
{
case (1 to 4): do the same for all of them; break;
case (5 to 9): again, same thing for these numbers; break;
}
57
user3022162

Un peu tard dans le jeu pour cette question, mais dans les modifications récentes introduit en C # 7 (disponible par défaut dans Visual Studio 2017/.NET Framework 4.6.2), la commutation par plage est désormais possible avec l'instruction switch.

Exemple:

int i = 63;

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

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

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

Notes:

  • Les parenthèses ( et ) ne sont pas requis dans la condition when, mais sont utilisés dans cet exemple pour mettre en évidence les comparaisons.
  • var peut également être utilisé à la place de int. Par exemple: case var n when n >= 100:.
144
Steve Gomez

Voici une solution meilleure et élégante pour votre énoncé de problème.

int mynumbercheck = 1000;
// Your number to be checked
var myswitch = new Dictionary <Func<int,bool>, Action>
            { 
             { x => x < 10 ,    () => //Do this!...  },  
             { x => x < 100 ,    () => //Do this!...  },
             { x => x < 1000 ,    () => //Do this!...  },
             { x => x < 10000 ,   () => //Do this!... } ,
             { x => x < 100000 ,  () => //Do this!... },
             { x => x < 1000000 ,  () => //Do this!... } 
            };

Appelons maintenant notre commutateur conditionnel

   myswitch.First(sw => sw.Key(mynumbercheck)).Value();

Alternate pour Switch/ifElse

43
Akxaya

Si-else devrait être utilisé dans ce cas, mais si un commutateur est nécessaire pour une raison quelconque, vous pouvez procéder comme indiqué ci-dessous, les premiers cas sans interruption se propagent jusqu'à la première interruption. Comme les réponses précédentes l'ont suggéré, je recommande if-else over switch.

switch (number){
            case 1:
            case 2:
            case 3:
            case 4: //do something;
                    break;
            case 5:
            case 6:
            case 7:
            case 8:
            case 9: //Do some other-thing;
                   break;
        }
8
Gayathri

L'intervalle est constant:

 int range = 5
 int newNumber = number / range;
 switch (newNumber)
 {
      case (0): //number 0 to 4
                break;
      case (1): //number 5 to 9
                break;
      case (2): //number 10 to 14
                break;
      default:  break;
 }

Autrement:

  if else
6
benba

Vous pouvez avoir les plages switch construct "handle" en l'utilisant conjointement avec un List de vos limites.

List<int> bounds = new List<int>() {int.MinValue, 0, 4, 9, 17, 20, int.MaxValue };

switch (bounds.IndexOf(bounds.Last(x => x < j)))
{
    case 0: // <=0
        break;

    case 1: // >= 1 and <=4
        break;
    case 2: // >= 5 and <=9
        break;
    case 3: // >= 10 and <=17
        break;
    case 4: // >= 18 and <=20
        break;

    case 5: // >20
        break;
}

Avec cette approche, les plages peuvent avoir différentes portées.

5
user3598756

J'utiliserais des opérateurs ternaires pour catégoriser vos conditions de commutation.

Alors...

switch( number > 9 ? "High" :
        number > 5 ? "Mid" :
        number > 1 ? "Low" : "Floor")
        {
              case "High":
                    do the thing;
                    break;
               case "Mid":
                    do the other thing;
                    break;
               case "Low":
                    do something else;
                    break;
               case "Floor":
                    do whatever;
                    break;
         }
3
graphicdivine

Comme mentionné if-else serait mieux dans ce cas, où vous manipulerez une plage:

if(number >= 1 && number <= 4)
{
   //do something;
}
else if(number >= 5 && number <= 9)
{
   //do something else;
}
3
henrik

Dans .Net, seul Visual Basic autorise les plages dans les instructions switch, mais en C #, il n’existe pas de syntaxe valide pour cela.

Abordant votre problème spécifique en C #, je le résoudrais ainsi:

if(number >= 1 && number <= 9) // Guard statement
{
    if(number < 5)
    {
        // Case (1 to 4):

        //break;

    }
    else
    {
        // Case (5 to 9):

        //break;

    }

}
else
{
    // Default code goes here

    //break;

}

Pour illustrer cela davantage, imaginons que vous ayez une valeur en pourcentage.

En utilisant votre problème comme modèle, vous souhaiterez peut-être ceci:

switch (percentage)
{
    case (0 to 19):
        break;

    case (20 to 39):
        break;

    case (40 to 69):
        break;

    case (70 to 79):
        break;

    case (80 to 100):
        break;

    default:
        break;

}

Cependant, comme C # n'autorise pas cette syntaxe, voici une solution que C # autorise:

if (percentage >= 0 && percentage <= 100) // Guard statement
{
    if (percentage >= 40)
    {
        if (percentage >= 80)
        {
            // Case (80% to 100%)

            //break;

        }
        else
        {
            if (percentage >= 70)
            {
                // Case (70% to 79%)

                //break;

            }
            else
            {
                // Case (40% to 69%)

                //break;

            }

        }

    }
    else
    {
        if (percentage >= 20)
        {
            // Case (20% to 39%)

            //break;

        }
        else
        {
            // Case (0% to 19%)

            //break;

        }

    }

}
else
{
    // Default code goes here

    //break;

}

Cela peut prendre un peu de temps pour s'y habituer, mais ça va une fois que vous l'avez.

Personnellement, j'accepterais volontiers des déclarations de substitution pour autoriser les plages.

L'avenir des instructions de commutateur C #

Voici quelques idées sur la façon dont les instructions de commutateur peuvent être améliorées:

Version A

switch(value)
{
    case (x => x >= 1 && x <= 4):
    break;

    case (x => x >= 5 && x <= 9):
    break;

    default:
    break;

}

Version B

switch(param1, param2, ...)
{
    case (param1 >= 1 && param1 <= 4):
    break;

    case (param1 >= 5 && param1 <= 9 || param2 != param1):
    break;

    default:
    break;

}
2
Knickerless-Noggins

Si vous utilisez C/C++, il n'y a pas de syntaxe "range". Vous pouvez uniquement lister toutes les valeurs après chaque segment "cas". Langage Ada ou Pascal supporte la syntaxe de plage.

1
SliceSort

Tout d'abord, vous devez spécifier le langage de programmation auquel vous faites référence. Deuxièmement, les instructions switch sont correctement utilisées pour des ensembles fermés d’options concernant la variable commutée, par exemple. énumérations ou chaînes prédéfinies. Dans ce cas, je suggérerais d'utiliser le bon vieux if-else structure.

0
Andrei Nicusan

En C #, les cas de commutation sont essentiellement des dictionnaires sur ce qu'il faut faire ensuite. Puisque vous ne pouvez pas rechercher une plage dans un dictionnaire, le mieux que vous puissiez faire est le cas ... lorsque la déclaration de Steve Gomez a été mentionnée.

0
user3406087