6
votes

Meilleures pratiques: revenant de la méthode dans le cas échéant de l'état du commutateur?

Quelle méthode de renvoi d'un bool à partir d'une instruction de commutation est préférable? Je comprends que cela peut être subjectif, mais je pense qu'il est important que notre profession soit commis sur les meilleures pratiques :).

public bool foo(param)
{
    bool flag = false;

    switch (param)
    {
        case 1:
            if (something)
            {
                flag = true;
            }
            break;
        default:
            break;
     }

    return flag;
}


2 commentaires

Les deux odeurs ... drapeau = true et retour vrai sont nichés 4 niveaux.


Alors M. Salonen, comment allez-vous l'écrire? Si votre réponse est meilleure, je l'accepterai :).


8 Réponses :


6
votes

Je préfère la deuxième méthode.
Il est beaucoup plus adaptable, vous pouvez par exemple ajouter du travail à la fin de la fonction qui dépendra du drapeau

En outre, si vous n'avez qu'un seul cas, vous voudrez peut-être passer à autre chose qu'un commutateur


5 commentaires

Atteindre une instruction Retour ne provoque pas la fonction de retour immédiatement. Le compilateur appellera plutôt automatiquement les destructeurs pour les variables locales. C'est le moyen préféré d'avoir un nettoyage de fin de fonction en C ++.


Si vous avez du travail qui dépend du drapeau, cela pourrait être un signe que votre fonction fait trop.


@Ben voigt, il s'agit d'environ C # qui n'a pas de choses comme destructeurs, et s'il a ( disposer ), il sera appelé automatiquement si l'objet a été enveloppé dans un en utilisant bloc ..


Oups, pensait que cette question a été étiquetée C ++. Avec c #, vous pouvez utiliser essayer / enfin (de lequel à l'aide de est un cas particulier) pour faire fonctionner le code de nettoyage avant le retour.


Cela vient de recevoir un vote qui m'a fait regarder pour la première fois depuis des années. Garçon Oh Boy a changé mes opinions sur des choses comme ça. Je préfère maintenant beaucoup le retour rapide.



1
votes

Tout dépend de ce que je fais. Si je fais le cas et puis j'ai fini, je reviendrai - pourquoi exécuter un code inutile? Si je veux faire plus de travail, alors je fixe un drapeau ou quelque chose. Utilisez le bon outil pour le bon travail.


0 commentaires

15
votes

La différence ici est entre un point de retour unique et plusieurs points de retour.

En règle générale, un seul point de retour d'un seul point de retour a tendance à faire beaucoup de comptabilité (variables temporaires, vérification de ces variables dans des boucles) et peut devenir poilue car la logique devient plus complexe. J'ai vu du code qui passe à des longueurs pour utiliser un tandis que (drapeau) ... drapeau = false; modèle au lieu d'un tandis que (vrai) ... Break; motif, et ce n'est pas amusant de lire.

Je préfère plusieurs points de retour depuis leur retour le plus tôt possible (pas de travail supplémentaire effectué) et ne nécessite aucun local pour aider à garder une trace de la valeur de retour actuelle. En outre, je ne les trouve pas plus difficiles à lire que du code de retour unique.

Il y a une bonne disursion de ceci sur C2 ( SingFunctionExitPoint ).

J'ai trouvé que garder les méthodes aussi "fonctionnelles" que possible est une bonne chose (je dis "fonctionnel" ici parce que je fais généralement C # qui, en dehors de Linq, n'est pas considérée comme fonctionnelle). Par "fonctionnel", je veux dire que j'essaie d'éviter la mutation de l'état autant que possible. L'introduction de plus d'état sous forme de locaux ou de membres rend les choses plus difficiles à comprendre car vous devez maintenant prendre en compte leurs valeurs et que vous devez déterminer la manière dont ces variables peuvent être définies (d'une autre méthode, d'une autre classe, ...) .

En général, l'état est mal, mais parfois c'est un mal nécessaire.

Ce problème particulier a une conversation intéressante ici sur SO comme bien.


1 commentaires

Je suis d'accord avec les multiples points de retour et j'irais aussi loin que si vous devez utiliser des indicateurs pour acheminer le chemin d'exécution, cela pourrait être refacturé dans une méthode qui utilise plusieurs retours à la place.



3
votes

Je préfère le retour anticipé - mais en général, j'essaie vraiment d'éviter le commutateur si possible, sauf si elle choisit entre au plus 3 options. Et j'essaie d'isoler le commutateur autant que possible, de sorte que la méthode avec le commutateur détermine uniquement la partie variable - tout le reste est traitée par le code d'appel.

imo, le rendement rapide est plus facile à lire car je n'ai pas besoin de "lire" plus loin lorsque je rencontre un retour.


1 commentaires

Ils ont tendance à construire des dégâts au fil du temps lorsqu'ils se développent à plus de 3 options avec de nombreux drapeaux (et sifflets) et apportent un code de lecture difficile à lire.



2
votes

Ceci ressemble à un vraiment élaborer un stratagème pour éviter l'opérateur &&. Les expressions booléennes sont coolio: xxx


2 commentaires

Ne pas éclater ta bulle (je pense que les expressions booléennes sont cool aussi :)), mais je pense qu'il est allé avec un exemple vraiment simple ...


@Goblin: Il y a Bubble espoir ici :) tombe dans la classe de si (Mumble) retourne vrai; sinon retourne faux;



2
votes

Compte tenu des deux options, je dis non ni parce qu'ils nichent trop loin - vous devriez appeler une fonction qui retourne un booléen dans vos exemples.

Compte tenu de la question entre un point de retour unique et plusieurs points de retour (et mon point précédent), je prends le point de retour multiple, car vous ne pouvez simplement retourner la valeur de votre fonction pour ce cas.

À titre d'exemple: xxx

finalement, ces instructions de commutation sont refactées dans la méthode appelle des objets (ce qui améliorera les terribles commutateurs de nidification vous donnera). Si vous êtes réel avertissant, vous n'avez peut-être même pas besoin de l'instruction de commutation dans votre usine d'objet (configuration XML, réflexion, base de données, ...).


1 commentaires

D'accord. Les déclarations de commutation sont mieux évitées. Il y a des moyens plus élégants pour accomplir la même chose.



1
votes

Je supprimerais l'instruction de commutation tout à fait:

public bool foo(param)
{
   if(param != 1)
   {
    throw new ArgumentException("Param value=" + param + " is not supported.");
   }

   return MethodForParamEqualOne();
}


0 commentaires

1
votes

En ce qui concerne les retours et le choix des blocs conditionnels, il est peut-être une bonne idée de toujours garder à l'arrière de votre tête, de commenter le code critique. Si vous utilisez

tandis que (vrai) p> blockQuote>

n'ayez pas peur de jeter un p>

// avertissement + raison! p> BlockQuote>

En haut du code de rupture. Habituellement, la plupart des gens vous diront que la plupart des gens vous diront, mais dès que cela deviendra un peu plus froid avec P>

while(true)
{
   ReDraw();
   ReUpdate();       

   //WARNING! Critical breakpoint   <--- Edit , nobody likes a game you can't win :P
   a = CheckForWinGame();
   if (a) 
   { 
      break; 
   }
}


0 commentaires