2011-05-23 3 views
18

Je dois évaluer plusieurs conditions. Dans mon cas, je dois faire quelque chose comme ceci:Commutateur d'instruction dans une instruction de commutateur?

switch(id) 
{ 
    case 5: 
     // switch some other cases here 
    case 6: 
     // set some value 
    ... 
} 

Est-il bon d'avoir un autre interrupteur en cas 5? Si non, quoi de mieux? Vous avez des déclarations if?

+0

Utilisation d'instructions de commutation est une mauvaise pratique en soi –

+0

tout est bien aussi longtemps que cela fonctionne. – crypted

+9

Int3 - oh mon dieu! – ThePower

Répondre

17

J'appellerais une fonction qui était spécifique au cas 5, alors avoir le cas de commutateur dans cette fonction. Par exemple:

switch(id) 
{ 
    case 5: 
     functionFiveSpecific(id); 
    case 6: 
     // set some value 
    ... 
} 

La fonction spécifique pour le cas 5:

private void functionFiveSpecific(id) 
{ 
    // other switch in here 
} 

Bien que

Il est fortement recommandé d'éviter l'utilisation des états de commutation si possible. Avoir une lecture here.

+0

ce poste ne semble pas suggérer que l'évitement de commutateur non imbriqué est fortement recommandé. Pour l'interrupteur imbriqué, y a-t-il une autre raison particulière pour laquelle éviter le basculement? Sauf raison de performance, ce qui n'est pas si pertinent sur la machine d'aujourd'hui. – liang

+5

* Il est fortement recommandé d'éviter l'utilisation d'instructions switch si possible. * Ne pas propager fud. Quelque chose ayant une limitation n'est pas une raison pour l'éviter pour ce dont il est capable. 'foreach' a une limitation, pourquoi l'utiliser? Heck C# a des limites, pourquoi s'embêter? 'switch' est plus lisible et insignifiant plus rapidement si c'est important. Mais si vous vouliez dire polymorphisme, alors je suis d'accord. – nawfal

1

Je voudrais appeler une fonction et passer dans les cas supplémentaires et dans la fonction faire un cas de commutation sur eux. Rend le code plus propre. Une autre méthode que j'utilise souvent est en effet imbriquée si est

7

La seule chose qui pourrait être mal avec elle est que cela pourrait nuire à la lisibilité:

switch(id) 
{ 
    case 5: 
    { 
     switch (somethingElse) 
     { 
      case 1: 
       // blah... 
     } 
    } 
    case 6: 
     // set some value 
    ... 
} 

Vous pouvez améliorer cela en déplaçant la section imbriquée dans une méthode:

switch(id) 
{ 
    case 5: 
     Foo(); 
     break; 
    case 6: 
     // set some value 
    ... 
} 
5

Les instructions de commutation ne sont pas une mauvaise pratique. Les instructions de commutation imbriquées peuvent être désordonnées à regarder. Peut-être pensez-vous à intégrer l'instruction switch imbriquée dans une autre méthode pour améliorer la clarté.

2

Utiliser le polymorphisme si possible. Cela rendrait votre code beaucoup plus propre.

+2

Pourriez-vous être plus précis et proposer un exemple de code? – shytikov

5

Une meilleure pratique consiste à encapsuler les différents comportements de manière polymophique à l'intérieur de classes différentes et essayer d'éviter les instructions de commutation si possible. Ceci n'est pas toujours possible, et si vous devez utiliser des instructions switch, je ne mettrais pas une autre instruction switch imbriquée (ou une collection d'instructions if) mais aurais probablement un appel de méthode qui contiendrait cette logique.

Si vous postez un peu plus de détails sur ce que vous essayez de faire, nous serons peut-être en mesure d'offrir de meilleures suggestions.

+0

En effet, beaucoup de réponses appropriées pour ce post. Imaginez un code sans instructions if réalisable en utilisant l'un des concepts OOP comme mentionné ici. –

5

Dès que vous commencez à imbriquer votre Cyclomatic complexity commence à augmenter. En fonction de la complexité de vos commutateurs imbriqués, cela peut être amusant à maintenir. Vous voudrez peut-être réfléchir au déplacement du second commutateur imbriqué vers une fonction qui lui est propre.Par exemple

switch (order.Status) 
{ 
    case OrderStatus.New: 
     // Do something to a new order; 
     break; 

    ... 

    case OrderStatus.ReadyToShip 
     // Process Shipping Instructions 
     ShipOrder(order); 
     break; 
} 

et si vous aviez un commutateur en fonction du type d'expédition payé pour

void ShipOrder(Order order) 
{ 
    switch (order.ShippingMethod) 
    { 
    } 
} 

En déplaçant la deuxième instruction switch de la première, il est plus facile à entretenir, et peut également être testé isolément

+0

+1 pour la complexité cyclomatique – crypted

6

Éviter! Essayez de refactoriser votre code pour éliminer les cas de commutation. Les instructions de changement pour les comportements peuvent être refactorisées dans Strategy Pattern.

Strategy Pattern](![Strategy Pattern

+1

+1 pour séparer le comportement polymorphe en stratégies. Malheureusement c'est un surmenage pour des choses simples où vous ne pouvez pas refactoriser votre code car il vient de 'outside' :( –

+3

pouvez-vous fournir un exemple de code simple à votre modèle? Je ne suis pas sûr de comprendre comment traduire des commutateurs imbriqués à ce modèle .. – Dennis