web-dev-qa-db-fra.com

Pourquoi C # a-t-il une pause s'il n'est pas facultatif?

Lorsque je crée une instruction switch dans VS2008 C # comme ceci (artificiel):

switch (state) {
    case '1':
        state = '2';
    case '2':
        state = '1';
}

il se plaint que je ne suis pas autorisé à passer à travers:

Le contrôle ne peut pas passer d'une étiquette de cas ('cas' 1 '(0x31):') à une autre

Si vous n'êtes pas autorisé à passer, alors quel est le but de l'instruction break? Pourquoi les concepteurs de langage ne l'ont-ils pas simplement laissé de côté et sauté automatiquement à la fin de l'instruction switch au lieu de nous forcer à insérer une construction inutile?

91
paxdiablo

De la bouche du cheval (MSDN) Pourquoi l'instruction switch C # est-elle conçue pour ne pas permettre la chute, mais nécessite quand même une pause? .

Citant les bits saillants, c'est pourquoi ils ne permettent pas la chute:

Ce comportement de passage implicite est souvent utilisé pour réduire la quantité de code nécessaire et n'est souvent pas un problème la première fois que le code est écrit. Cependant, alors que le code passe de la phase de développement initiale à une phase de maintenance, le code ci-dessus peut entraîner des erreurs subtiles très difficiles à déboguer. Ces erreurs résultent de l'erreur très courante du développeur en ajoutant un cas, mais en oubliant de mettre une pause à la fin du bloc.

En C #, l'instruction switch requiert qu'un contrôle de flux explicite se produise à la fin d'un cas, soit un break, un goto, un return ou un throw. Si le développeur souhaite une sémantique de repli, elle peut être obtenue par un goto explicite à la fin d'une déclaration de cas.

Et c'est pourquoi ce n'est pas automatique:

En raison des règles C # exigeant que le contrôle de flux explicite se produise à la fin d'un bloc de cas (le plus souvent une interruption), de nombreuses personnes se demandent pourquoi le comportement n'a tout simplement pas été modifié de telle sorte que la transition ne se produise pas. Autrement dit, ne faites pas de pause nécessaire, changez simplement la sémantique de switch pour ne pas avoir d'interruption pour les cas. La raison pour laquelle cela n'a pas été fait était que les développeurs très habitués au C++ n'auraient pas de mal à comprendre ce que faisait une instruction switch.

73
Alex K.

Fondamentalement pour le rendre plus familier aux développeurs C/C++/Java. Personnellement, je pense que c'était une erreur, mais c'est le raisonnement.

J'aurais préféré un blocage forcé:

case '1':
{
}

En plus de toute autre chose, cela aurait évité les situations de portée variable étranges pour le commutateur/boîtier. Vous pouvez toujours avoir plusieurs étiquettes de cas, bien sûr:

case '0':
case '1':
{
}

Il pourrait également être agréable de pouvoir répertorier plusieurs cas plus simplement:

case '0', '1':
{
}

Oh, et un léger choix sur votre description de la langue existante: vous n'avez pas ayez pour faire une pause. C'est juste que la fin de l'affaire doit être inaccessible. Vous pouvez également avoir throw, goto ou return. Il y en a peut-être d'autres que j'ai ratés aussi :)

87
Jon Skeet

Vous êtes autorisé à passer, mais vous devez le faire explicitement avec le mot clé goto:

switch (state) {
    case '1':
        state = '2';
        goto case '2';
    case '2':
        state = '1';
        break;
}

Vous pouvez break ou gotoen C #, mais ce que vous ne pouvez pas faire n'est pas d'indiquer ce que vous voulez, car c'est une source potentielle de bogues difficiles à repérer.

Il est beaucoup plus facile de repérer que votre code indique goto quand vous vouliez break (ou vice versa) que de repérer que vous avez oublié d'ajouter non plus.

Cela peut sembler stupide, mais de nombreuses recherches fatiguées de deux heures sur la cause d'un bogue C++ se terminent par une soudaine prise de conscience que vous avez oublié d'ajouter un break et que votre code tombe tout le temps. C # évite cela en vous forçant à indiquer ce que vous voulez.

43
Chris

Si vous n'avez pas de code dans le cas 1, vous êtes autorisé à passer, vous pouvez donc dire que "tous ces cas partagent ce morceau de code"

12
simendsjo