Existe-t-il un moyen de passer à travers plusieurs déclarations de cas sans préciser case value:
répéter à plusieurs reprises?
Je sais que cela fonctionne:
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;
}
mais je voudrais faire quelque chose comme ça:
switch (value)
{
case 1,2,3:
// Do something
break;
case 4,5,6:
// Do something
break;
default:
// Do the Default
break;
}
Cette syntaxe à laquelle je pense provient-elle d'un autre langage ou manque-t-il quelque chose?
c#
switch-statement
theo
la source
la source
,
une autre qui n'est partagée avec aucun autre langage de style C. Cela me semblerait beaucoup plus sale.Réponses:
Il n'y a pas de syntaxe en C ++ ni en C # pour la deuxième méthode que vous avez mentionnée.
Il n'y a rien de mal avec votre première méthode. Si toutefois vous avez de très grandes plages, utilisez simplement une série d'instructions if.
la source
Je suppose que cela a déjà été répondu. Cependant, je pense que vous pouvez toujours mélanger les deux options d'une manière syntaxiquement meilleure en faisant:
la source
Cette syntaxe provient de l' instruction Visual Basic Select ... Case :
Vous ne pouvez pas utiliser cette syntaxe en C #. Au lieu de cela, vous devez utiliser la syntaxe de votre premier exemple.
la source
En C # 7 (disponible par défaut dans Visual Studio 2017 / .NET Framework 4.6.2), la commutation basée sur la plage est désormais possible avec l' instruction switch et aiderait à résoudre le problème de l'OP.
Exemple:
Remarques:
(
et)
ne sont pas obligatoires dans lawhen
condition, mais sont utilisées dans cet exemple pour mettre en évidence la ou les comparaisons.var
peut également être utilisé à la place deint
. Par exemple:case var n when n >= 7:
.la source
Vous pouvez laisser de côté la nouvelle ligne qui vous donne:
mais je considère ce mauvais style.
la source
.NET Framework 3.5 a des plages:
Enumerable.Range de MSDN
vous pouvez l'utiliser avec "contains" et l'instruction IF, car comme quelqu'un l'a dit, l'instruction SWITCH utilise l'opérateur "==".
Voici un exemple:
Mais je pense que nous pouvons avoir plus de plaisir: puisque vous n'aurez pas besoin des valeurs de retour et que cette action ne prend pas de paramètres, vous pouvez facilement utiliser des actions!
Le vieil exemple avec cette nouvelle méthode:
Puisque vous passez des actions, pas des valeurs, vous devez omettre les parenthèses, c'est très important. Si vous avez besoin d'une fonction avec des arguments, changez simplement le type de
Action
enAction<ParameterType>
. Si vous avez besoin de valeurs de retour, utilisezFunc<ParameterType, ReturnType>
.En C # 3.0, il n'y a pas d' application partielle facile pour encapsuler le fait que le paramètre case est le même, mais vous créez une petite méthode d'aide (un peu verbeuse, mais).
Voici un exemple de la façon dont la nouvelle déclaration fonctionnelle importée est à mon humble avis plus puissante et élégante que l'ancienne impérative.
la source
int start
etint count
. Vos exemples ne fonctionneront pas exactement comme ils ont été écrits. Vous l'écrivez comme si le deuxième argument étaitint end
. Par exemple -Enumerable.Range(11,20)
entraînerait 20 nombres commençant par 11, et non des nombres de 11 à 20.Enumerable.Range(11,20).Contains(c)
équivaut àfor(int i = 11; i < 21; ++i){ if (i == c) return true; } return false;
Si vous aviez une large plage, cela prendrait beaucoup de temps, tout en utilisant simplement>
et<
serait rapide et à temps constant.MySwitchWithEnumerable
retourvoid
est une conception faible pour cette situation. RAISON: Vous avez converti unif-else
en une série d'instructions indépendantes - qui cache l'intention, c'est-à-dire qu'elles s'excluent mutuellement - une seuleaction
est exécutée. Retour à la placebool
, avec le corpsif (..) { action(); return true; } else return false;
Le site appelant montre alors l'intention:if (MySwitchWithEnumerable(..)) else (MySwitchWithEnumerable(..));
. C'est préférable. Cependant, ce n'est également plus une amélioration significative par rapport à votre version d'origine, pour ce cas simple.Voici la solution complète C # 7 ...
Cela fonctionne aussi avec les cordes ...
la source
Le code ci - dessous ne fonctionnera pas :
La seule façon de procéder est:
Le code que vous recherchez fonctionne en Visual Basic où vous pouvez facilement mettre des plages ... dans l'
none
option de l'switch
instruction ouif else
blocs pratiques, je suggère, à un point très extrême, de créer .dll avec Visual Basic et de l'importer à votre projet C #.Remarque: l'équivalent de commutateur dans Visual Basic est
Select Case
.la source
Une autre option serait d'utiliser une routine. Si les cas 1 à 3 exécutent tous la même logique, encapsulez cette logique dans une routine et appelez-la pour chaque cas. Je sais que cela ne supprime pas réellement les déclarations de cas, mais cela met en œuvre un bon style et maintient la maintenance au minimum .....
[Modifier] Ajout d'une implémentation alternative pour correspondre à la question d'origine ... [/ Modifier]
Alt
la source
Une facette moins connue du commutateur en C # est qu'il repose sur l' opérateur = et comme il peut être remplacé, vous pourriez avoir quelque chose comme ceci:
la source
gcc implémente une extension du langage C pour prendre en charge les plages séquentielles:
Edit : Je viens de remarquer la balise C # sur la question, donc probablement une réponse gcc n'aide pas.
la source
En C # 7, nous avons maintenant la correspondance de motifs afin que vous puissiez faire quelque chose comme:
la source
En fait, je n'aime pas non plus la commande GOTO, mais elle est dans les documents officiels de Microsoft, et voici toutes les syntaxes autorisées.
Si le point final de la liste d'instructions d'une section de commutateur est accessible, une erreur de compilation se produit. C'est ce que l'on appelle la règle de «non-répercussion». L'exemple
est valide car aucune section de commutateur n'a de point de fin accessible. Contrairement à C et C ++, l'exécution d'une section de commutateur n'est pas autorisée à "passer" à la section de commutateur suivante, et l'exemple
entraîne une erreur de compilation. Lorsque l'exécution d'une section de commutateur doit être suivie par l'exécution d'une autre section de commutateur, un cas goto explicite ou une instruction par défaut goto doit être utilisé:
Plusieurs étiquettes sont autorisées dans une section de commutation. L'exemple
Je crois que dans ce cas particulier, le GOTO peut être utilisé, et c'est en fait le seul moyen de passer à travers.
Source: http://msdn.microsoft.com/en-us/library/aa664749%28v=vs.71%29.aspx
la source
goto
peut presque toujours être évité (bien que je ne le considère pas comme "terrible" ici - il remplit un rôle spécifique et structuré). Dans votre exemple, parce que vous avez encapsulé les corps de cas dans des fonctions (une bonne chose), le cas 0 peut devenirCaseZero(); CaseZeroOrOne(); break;
. Nongoto
requis.Beaucoup de travail semble avoir été fait pour trouver des moyens d'obtenir une des syntaxes C # les moins utilisées pour mieux paraître ou mieux fonctionner. Personnellement, je trouve que l'instruction switch vaut rarement la peine d'être utilisée. Je suggère fortement d'analyser les données que vous testez et les résultats finaux que vous recherchez.
Disons par exemple que vous souhaitez tester rapidement des valeurs dans une plage connue pour voir s'il s'agit de nombres premiers. Vous voulez éviter que votre code fasse les calculs inutiles et vous pouvez trouver une liste de nombres premiers dans la plage que vous souhaitez en ligne. Vous pouvez utiliser une instruction switch massive pour comparer chaque valeur à des nombres premiers connus.
Ou vous pouvez simplement créer une carte matricielle de nombres premiers et obtenir des résultats immédiats:
Vous voulez peut-être voir si un caractère dans une chaîne est hexadécimal. Vous pouvez utiliser une instruction switch ungly et quelque peu volumineuse.
Ou vous pouvez utiliser des expressions régulières pour tester le caractère ou utiliser la fonction IndexOf pour rechercher le caractère dans une chaîne de lettres hexadécimales connues:
Supposons que vous souhaitiez effectuer l'une des 3 actions différentes en fonction d'une valeur comprise entre 1 et 24. Je suggère d'utiliser un ensemble d'instructions IF. Et si cela devenait trop complexe (ou si les nombres étaient plus grands, comme 5 actions différentes selon une valeur comprise entre 1 et 90), utilisez une énumération pour définir les actions et créer une carte de tableau des énumérations. La valeur serait ensuite utilisée pour indexer dans la carte du tableau et obtenir l'énumération de l'action souhaitée. Utilisez ensuite un petit ensemble d'instructions IF ou une instruction switch très simple pour traiter la valeur d'énumération résultante.
En outre, la bonne chose à propos d'une carte de tableau qui convertit une plage de valeurs en actions est qu'elle peut être facilement modifiée par le code. Avec du code câblé, vous ne pouvez pas facilement changer de comportement lors de l'exécution, mais avec une carte de tableau, c'est facile.
la source
Juste pour ajouter à la conversation, en utilisant .NET 4.6.2, j'ai également pu faire ce qui suit. J'ai testé le code et cela a fonctionné pour moi.
Vous pouvez également faire plusieurs instructions "OU", comme ci-dessous:
Vous pouvez également vérifier s'il correspond à une valeur dans un tableau:
la source
Si vous avez un très grand nombre de chaînes (ou tout autre type) faisant toutes la même chose, je recommande l'utilisation d'une liste de chaînes combinée avec la propriété string.Contains.
Donc, si vous avez une grosse instruction switch comme ceci:
Vous voudrez peut-être le remplacer par une
if
déclaration comme celle-ci:Cette échelle convient bien à n'importe quel nombre de cas de chaîne.
la source
Je pense que celui-ci est meilleur en C # 7 ou supérieur.
Vous pouvez également vérifier la plage dans le boîtier de commutateur C #: Boîtier de commutateur: puis-je utiliser une plage au lieu d'un seul chiffre Ou si vous voulez comprendre les bases du boîtier de commutateur C #
la source
Pour cela, vous utiliseriez une instruction goto. Tel que:
la source
goto
. Pire, c'est une utilisation complètement inutile degoto
, car la syntaxe originale indiquée par OP fonctionne. La question était de savoir s'il y avait une manière plus concise de donner les cas alternatifs. Comme les gens ont répondu des années avant vous , oui, c'est le cas - si vous êtes prêt à mettre les plusieurs cas sur une seule lignecase 1: case 2:
, et si le style automatique de l'éditeur le permet.