J'ai remarqué ces deux motifs de vérification d'un drapeau enum:
[Flags] public enum PurchaseType { None = 0, SalePrice = 2, RegularPrice = 4, Clearance = 8, CreditCard = 16 } public void Test() { PurchaseType type = PurchaseType.Clearance; type |= PurchaseType.CreditCard; // Practice 1 if ((type & PurchaseType.Clearance) == PurchaseType.Clearance) { // Clearance item handling } // Practice 2 if ((type & PurchaseType.CreditCard) != 0) { // Credit card item handling } }
4 Réponses :
Je choisirais le premier:
if ((type & PurchaseType.Clearance) == PurchaseType.Clearance) { // Clearance item item handling }
Hmm, je n'aime pas ça beaucoup. Je peux voir la duplication. Si vous avez changé Clearance Code> vers l'un des autres drapeaux, mais j'ai oublié de le faire dans les deux endroits, votre code compilerait, mais cela ne ferait pas ce que vous voulez.
! = 0 code> gagne pour moi.
@DavidHeffernan: d'accord (sur duplicate), mais comme la déclaration explicite claire.
@David: En fait, j'ai fait cette erreur exacte lors de la frappe ma question!
@MOHAMMEDALI sonne comme vous avez votre réponse alors. Au moins sur les deux candidats de la question.
@David: Je ne vois pas une façon d'accepter votre commentaire comme une réponse :).
.NET 4 introduit un HASFLAG code >
méthode qui détermine si un ou plusieurs champs de bits sont définis dans l'instance actuelle, ceci est de loin la meilleure pratique:
Cela semble plus facile à utiliser. J'ai vu ce Connecter le problème concernant performance. Je me demande si cela a été corrigé dans 4.0.
Blog Entrée concernant cette et mauvaise performance. Il semble que ce ne soit pas seulement un simple sucre syntaxique simple. Cette méthode semble employer la réflexion selon ce poste.
Je vois beaucoup de upvotes pour cette réponse et je suis maintenant curieux. Disons qu'il y a eu une pénalité de perfection pour l'utiliser sur les autres. La réadaptabilité gagnerait-elle ici sur la performance?
Vous voulez que nous répondions si la pénalité de performance est significative pour vous? !! Seulement vous pouvez répondre à cela.
@MOHAMMEDALI - Si votre HASFLAG n'est pas une performance cruciale, je serais enclin à faire face à la lisibilité. Cependant, je dois être honnête - jusqu'à ce que je voyais le lien vers l'article de blog, je n'avais pas réalisé qu'il y avait eu un problème potentiel. Maintenant, je regarde dans le réflecteur, je vois qu'il utilise effectivement une réflexion, pour vérifier que les deux types d'énumjetchis correspondent.
Si la performance est un problème, une alternative à la définition de votre code illisible consiste à la consolider dans une méthode code> code> code> pour chaque type d'enum que vous souhaitez comparer. Si vous utilisez un nom ou une signature de méthode différente, vous pouvez même en faire une méthode d'extension, par ex. Public Static Bool HasflagFastfast (ce achetType V, achetéType F) {retour (V & F) == F; } code> et appelé à l'aide de
type.hasflagfastfast (achetType.creditCard); code>
Attention à utiliser ce modèle avec aucun == 0, comme type.hasflag (achetype.none) code> évaluera toujours à true, quand vous voulez probablement dire
type == achetype.none code>
i personnellement préférerait toujours la lisibilité claire de Cependant, sur les deux options de la question, je pense hasflag code>.
! = 0 code> est plus sûr parce qu'il n'a pas de duplication. Si vous utilisez votre alternative, tout est trop facile lorsque la maintenance codant pour changer l'un des indicateurs et oublier de changer l'autre. Et puis vous vous retrouvez avec cette p>
dans le contexte de la performance. Y a-t-il un casting impliqué dans l'utilisation du chèque! = 0?
Comment comparer contre 0 ont-elles des conséquences sur la performance?
La valeur 0 doit-elle être couplée pendant le chèque? Si oui, est-ce un pire que l'autre option de ma question?
Pourquoi un temps de processeur de coûts de distribution pourrait-il? Les moulages entre INTS et ENUMS sont traités au moment de la compilation.
Je vois que les deux options semblent également performantes.
Je préférerais (type & achetType.creditcard)! = 0 code> Parce que si vous souhaitez vérifier plus d'un bit, le côté droit devient lourd. J'ai confiance en des opérations de bits que ce qui précède ne sera vrai que si et seulement si le (s) bit (s) est défini. P>
Mieux pour quoi? Lisibilité? Performance? Phase de la lune? Autre chose?
Je vote pour la pratique 1. Comment testeriez-vous pour
achetType.none code> avec la pratique 2? EDIT: Je suppose que vous pourriez faire (tapez et achetype.none) == 0, mais maintenant, vos chèques ne sont pas vraiment cohérents.
@Tung ER,
Aucun code> n'est pas un drapeau qui peut être testé.
Type & PublierType.none code> est
0 code> pour toutes les valeurs de
Type code>. Vous ne pouvez jamais tester pour
Aucun code> afin qu'il ne soit aucun point préoccupé par la manière de faire ce qui ne peut pas être fait et n'est jamais terminé.
@ODed: la question est ouverte ("laquelle est meilleure et pourquoi") afin que d'autres aspects à considérer comme "performances" et "phase de la lune" puissent être mis en évidence. :)
Cela en fait un Mauvais ajustement I> pour débordement de pile. Veuillez lire le FAQ
@ODED - Le problème avec des personnes contre "sans réponse" "Lequel est le meilleur et pourquoi" questions, est que ce n'est pas toujours clair, il n'est pas propérable quand il est demandé. L'OP aurait pu poser cette question et tout le monde est d'accord "La pratique n est meilleure pour la raison suivante, ne pratiquez pas M". C'est en fait une bonne question. Le fait que la réponse soit réellement "il n'y a pas de raison convaincante de choisir" eux ne nie pas de cette question du tout IMHO. En plus de cela, il a donné lieu à une conversation éclairante autour de la réflexion dans HASFLAG - qui est elle-même aussi v. Utile.
@ODed: Je ne suis pas sûr que je suis d'accord pour dire que c'est un "mauvais ajustement" pour. Je ne vois pas comment ce commentaire dans la FAQ "Des questions pratiquées et ouvertes diminuent l'utilité de notre site et poussent d'autres questions à la page d'accueil". peut être appliqué ici. Faites-vous référence à cette déclaration? Si oui, pensez-vous vraiment que ce commentaire s'applique également à ma question «ouverte»?