92 votes

Quelqu'un sait une bonne solution de contournement pour l’absence de contrainte générique enum ?

Ce que je veux faire est quelque chose comme ceci : J’ai des énumérations avec des valeurs comportant un indicateur combinés.

Alors je pourrais faire :

Malheureusement # de génériques où les contraintes n’ont aucune restriction d’enum, seulement class et struct. C# ne voit pas les enums comme structs (même si ils sont des types valeur) donc je ne peux pas ajouter des types d’extension comme ça.

Quelqu'un sait une solution de contournement ?

49voto

Jon Skeet Points 692016

EDIT: C'est maintenant en direct dans la version 0.0.0.2 de UnconstrainedMelody.

(Comme demandé sur mon blog à propos de l'enum de contraintes. J'ai inclus la base des faits ci-dessous pour l'amour d'une réponse unique.)

La meilleure solution est d'attendre pour moi de l'inclure dans UnconstrainedMelody1. C'est une bibliothèque qui prend de code C# avec "faux" contraintes telles que

where T : struct, IEnumConstraint

et il se transforme en

where T : struct, System.Enum

par l'intermédiaire d'un postbuild étape.

Il ne devrait pas être trop dur à écrire IsSet... bien que, de la restauration pour les deux Int64-fondé et de l' UInt64-en fonction des drapeaux pourrait être la partie difficile. (Je sens l'odeur de certaines méthodes d'aide à venir sur, fondamentalement, ce qui me permet de traiter tous les indicateurs enum comme si elle avait un type de base UInt64.)

Que voudriez-vous le comportement de l'être, si vous l'avez appelé

tester.IsSet(MyFlags.A | MyFlags.C)

? Faut-il vérifier que tous les indicateurs spécifiés sont ensemble? Que seraient mes attentes.

Je vais essayer de le faire sur le chemin de la maison ce soir... j'espère avoir un rapide éclair sur utile enum méthodes pour obtenir la bibliothèque jusqu'à un standard utilisable rapidement, puis se détendre un peu.

EDIT: je ne suis pas sûr à propos de IsSet comme un nom, par la manière. Options:

  • Comprend
  • Contient
  • HasFlag (ou HasFlags)
  • IsSet (c'est certainement une option)

Les pensées de bienvenue. Je suis sûr que ça va être un certain temps avant que rien n'est gravé dans la pierre de toute façon...


1 ou soumettre un patch, bien sûr...

16voto

Ronnie Points 3742

Darren, qui pourrait fonctionner si les types sont les énumérations spécifiques - pour les énumérations générales fonctionne, vous devez jeter d’entiers (ints) (ou plus probablement uint) pour faire le calcul booléen :

10voto

SLaks Points 391154

En fait, il est possible, avec un truc moche. Cependant, il ne peut pas être utilisé pour les méthodes d’extension.

Si vous le souhaitez, vous pouvez donner un constructeur privé et une classe héritée abstraite imbriquée publique avec comme `` , pour éviter que des versions héritées pour non-enums.

8voto

Simon Points 11945

Vous pouvez y parvenir en utilisant IL tissage et ExtraConstraints

Vous permet d’écrire ce code

Ce qui obtient compilé

3voto

thecoop Points 23695

Comme je le fais c’est mettre une contrainte struct, puis vérifier que T est un enum à l’exécution. Cela n’élimine pas complètement le problème, mais il réduire un peu

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X