6
votes

C # est cette conception "correcte"?

J'ai actuellement le suivant

        if (
           (RunCommand(LogonAsAServiceCommand))
        && (ServicesRunningOrStart())
        && (ServicesStoppedOrHalt())
        && (BashCommand(CreateRuntimeBashCommand))
        && (ServicesStoppedOrHalt())
        && (BashCommand(BootstrapDataBashCommand))
        && (ServicesRunningOrStart())
        )
        {
               // code after "return statements" here
        }


2 commentaires

Totalement la même et une question de style sauf que le premier est plus facile de déboguer (et de définir des points d'arrêt).


Je suis d'accord avec @kirk Woll, lorsqu'il est optimisé, ils doivent être la même chose si le compilateur / gigue est assez intelligent.


5 Réponses :


1
votes

Vous devez vous en tenir à tout ce qui est plus lisible et compréhensible.

Sauf si c'est réel inefficace.


0 commentaires

3
votes

est le premier code d'un ensemble ou de relevés?

if ( 
       (!RunCommand(LogonAsAServiceCommand)) 
    || (!ServicesRunningOrStart()) 
    || (!ServicesStoppedOrHalt()) 
    || (!BashCommand(CreateRuntimeBashCommand)) 
    || (!ServicesStoppedOrHalt()) 
    || (!BashCommand(BootstrapDataBashCommand)) 
    || (!ServicesRunningOrStart()) 


13 commentaires

Si vous le faites comme des déclarations, vous obtenez l'efficacité du retour dès que l'une des conditions est vraie, plutôt que d'attendre de voir s'ils sont tous.


&& et || sont à court-circuiter, il n'y a donc aucun avantage réel à faire cela.


+1 pour la performance et pour corriger la deuxième solution de l'OP.


Comment est-ce court-circuit s'il doit évaluer toutes les conditions (dans et et). De toute évidence, cela dépend si vous exécutez ou excitant tôt. Une fois, j'ai travaillé avec une équipe qui a dit qu'il n'y avait pas de logique dans ou et a fait toute leur logique avec et, et pas. Est-ce que cette préférence, une façon de travailler, peut-être une chose régionale, car ces gars-là étaient au-dessus de la côte et étaient tout à fait déconsidéré ou logique?


@Brunolm: C'est la même chose que la deuxième solution de l'OP. La seule différence est que le contenu des blocs if et d'autre est inversé (pensez la loi de la Morgan).


@Mark Dickinson: C'est à court-circuitement car quand c # voit ! Foo () || ! bar () , il omet exécution bar () si foo () est faux, car cela fait ! foo () True et il s'agit de suffisamment d'informations pour déterminer que toute la condition est vraie (puisque le vrai || x est vraie, quelle que soit la valeur de x).


@Brian: Ce n'est pas la même chose, l'OP utilise && opérateur, qui ne correspond pas à sa logique. @Mark en suggérant ce format ne corrige pas uniquement le PO, mais également la solution la plus efficace sur cette question. Dès que 1 des conditions correspondent à la vraie toutes les autres ne courent pas.


@Brunolm - c'est la même chose. L'OP utilise && , mais ne pas invoquer la sortie. Mark a simplement renversé qu'utiliser || et inversant la sortie de chaque fonction. Voir le commentaire de Brian ci-dessus.


@Brian, oui, je comprends cela, mais les travaux de coupe courte en arrière si l'ensemble du bloc conditionnel est utilisé pour quitter une boucle ou une méthode plutôt que d'exécuter du code. Je ne pense pas que ce soit la même chose, si l'une des conditions dans les miens est vraie, elle short. Si l'une des conditions de l'OPS est fausse. Est-ce vraiment la même chose?


@Mark - Oui, pensez à si RunCommand retourne false . Dans l'exemple OPS, il sera raccourci à cause de faux && . Dans votre exemple, il sera également raccourci à cause de vrai || . C'est juste logiquement renversé.


@Mark: La commande de l'OP est courte en circuit car lorsque c # voit foo () && bar () , il omet d'exécuter bar () si foo () est faux, car cela fait foo () false et cela suffit pour déterminer que toute la condition est vraie (puisque False && x est fausse quelle que soit la valeur de x). Voir mon autre commentaire dans le même format pour l'évaluation de votre propre commande. Notez qu'ils sont fondamentalement les mêmes. De toute façon, il omettra d'exécuter bar () si foo () est faux.


@ Swdevman81, ouais je pense que nous avons couvert les bases. Je voulais juste que les gens soient conscients que le choix de l'endroit où vous court-circuit dépend de la base de code plus large. :)


C'est juste bon sens, vraiment



2
votes

soit bien. Toutefois, à partir d'une perspective de style, je suggère que, étant donné qu'il s'agissait d'une série de Comands, vous pouvez utiliser une liste Liste CODE> pour les conserver et apporter les données de fonction pilotées.

(new Action[] {  func1, func2, .... }).ToList().ForEach(a => a());


3 commentaires

C'est une bonne approche, mais toujours pas très bien débogué. Surtout lorsque vous remplissez la liste avec Lambda sur tout le lieu. Les méthodes normales doivent bien être ok.


convenu sur le commentaire de débogage. Je suis très doté de données dans mon code, mais cela le rend plus unitaire à tester un meilleur titre. Aussi, j'ai tendance à utiliser la journalisation plus que le débogage de l'analyse ces jours-ci


Ce genre de choses débogue beaucoup mieux dans VS2010 :)



4
votes

Quand je regarde la première approche, ma première pensée est que la raison pour laquelle le code a été écrit de cette manière est que les opérations impliquées ont probablement des effets secondaires. Des noms des méthodes, je suppose qu'ils font? Si oui, je vais certainement aller avec la première approche et non la seconde; Je pense que les lecteurs de votre code trouveraient très déroutant de voir une expression courte-circuits étant utilisée pour exécuter des effets secondaires de manière conditionnelle.

S'il n'y a pas d'effets secondaires, non plus; Ils sont tous deux parfaitement lisibles. Si vous constatez qu'il y a plusieurs autres conditions ou que les conditions elles-mêmes varient dans différents scénarios, vous pouvez essayer quelque chose comme: xxx

Je n'irais pas vraiment avec une telle approche votre cas, cependant.


4 commentaires

Qu'entendez-vous par "effets secondaires"?


en.wikipedia.org/wiki/ide_effect_(Computer_science) . Effectivement, ce que je veux dire dans ce cas, c'est que le choix du court-circuit et non pas court-circuit introduit une différence de fonctionnalité observable dans l'état du programme.


+1 pour fournir une bonne règle pour décider entre quelle déclaration sera plus lisible. Eric Lippert a un post sur une fois quelque part sur cette règle dans le contexte de l'opérateur ternaire, mais je n'arrive pas à le trouver.


La discussion d'Eric Lippert, qui n'est effectivement pertinente périphérique: Stackoverflow.com/questions/3909849/...



-1
votes

Si vous utilisez ce code plusieurs fois, je vous suggère de le mettre dans une méthode distincte telle que: xxx pré>

et l'appelant en cas de besoin p>

public class SomeClass
{
  // Constructors etc...
  public void SomeMethod()
  {
     if(HelperClass.ServicesRunning())
     {
        // Your code here...
     }
  }
}


1 commentaires

Eh bien, ce n'était pas exactement cristal clair que c'était votre conception. Mais si c'est ce que vous faites déjà, je ne peux que dire que je suis d'accord avec cette conception. En utilisant LONG && / || Si-énoncés devient facilement désordonné (à mon avis).