Je sais que ce qui suit n'est pas possible car le type de l'énumération doit être un int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
De ma base de données, j'obtiens un champ avec des codes incompréhensibles (les OEM
et CMB
les). Je voudrais faire de ce champ un enum
ou quelque chose d'autre compréhensible. Parce que si la cible est la lisibilité, la solution doit être concise.
Quelles autres options ai-je?
Réponses:
J'aime utiliser des propriétés dans une classe au lieu de méthodes, car elles ressemblent plus à des énumérations.
Voici un exemple pour un enregistreur:
Transmettez des valeurs de chaîne sécurisées en tant que paramètre:
Usage:
la source
ToString
méthode à retournerValue
. Et ensuite fourni des opérateurs de transtypage implicites vers et depuis une chaîne.public static implicit operator String(LogCategory category) { return Value; }
.Vous pouvez également utiliser le modèle d'extension:
Votre classe d'extension
usage:
la source
public static string ToDescriptionString(this Enum ...
ie sans taper explicitement àMyEnum
.Que diriez-vous d'utiliser une classe statique avec des constantes?
la source
GroupTypes
comme type d'argument car c'est une classe statique. C'est le problème que la réponse d'Even Mien résout. Dans ce cas, vous devriez plutôt avoirvoid DoSomething(string groupType)
, ce qui signifie alors que celagroupType
pourrait avoir n'importe quelle valeur de chaîne , même des valeurs que vous n'attendez pas, ce qui signifie que vous devez être préparé pour ces types non valides et décider comment les gérer (par exemple en lançant une exception). Même la réponse de Mien résout cela en limitant le nombre d'entrées valides aux options définies par laLogCategory
classe.Vous pouvez ajouter des attributs aux éléments de l'énumération, puis utiliser la réflexion pour obtenir les valeurs des attributs.
Vous devez utiliser le spécificateur "field" pour appliquer les attributs, comme ceci:
Vous réfléchissez ensuite aux champs statiques du type de l'énumération (dans ce cas, GroupTypes) et obtenez
DescriptionAttribute
la valeur que vous recherchez à l'aide de la réflexion:J'ai choisi de retourner le
DescriptionAttribute
lui-même ci-dessus, dans le cas où vous souhaitez pouvoir déterminer si l'attribut est même appliqué.la source
Vous pouvez le faire très facilement en fait. Utilisez le code suivant.
Ensuite, lorsque vous souhaitez obtenir la valeur de chaîne de chaque élément enum, utilisez simplement la ligne de code suivante.
J'ai utilisé cette méthode avec succès dans le passé, et j'ai également utilisé une classe de constantes pour contenir des constantes de chaîne, les deux fonctionnent assez bien, mais j'ai tendance à préférer cela.
la source
Essayez d'ajouter des constantes à une classe statique. Vous ne vous retrouvez pas avec un type, mais vous aurez des constantes lisibles et organisées:
la source
Créez une deuxième énumération pour votre base de données contenant les éléments suivants:
Maintenant, vous pouvez utiliser Enum.Parse pour récupérer la valeur DBGroupTypes correcte à partir des chaînes "OEM" et "CMB". Vous pouvez ensuite les convertir en int et récupérer les valeurs correctes à partir de la bonne énumération que vous souhaitez utiliser davantage dans votre modèle.
la source
Utilisez une classe.
Edit: Meilleur exemple
la source
Une autre façon de résoudre le problème est d'avoir une énumération et un tableau de chaînes qui mapperont les valeurs d'énumération avec la liste de chaînes:
vous pouvez l'utiliser quelque chose comme ceci:
Cela invitera CMB
AVANTAGES:
LES INCONVÉNIENTS:
la source
Voici la méthode d'extension que j'ai utilisée pour obtenir la valeur d'énumération sous forme de chaîne. Voici d'abord l'énumération.
L'attribut Description provient de System.ComponentModel.
Et voici ma méthode d'extension:
Maintenant, vous pouvez accéder à l'énumération en tant que valeur de chaîne à l'aide du code suivant:
la source
Avez-vous envisagé une table de recherche à l'aide d'un dictionnaire?
Vous pouvez ensuite utiliser GroupTypeLookup.TryGetValue () pour rechercher une chaîne lorsque vous la lisez.
la source
la source
C # ne prend pas en charge les chaînes énumérées, mais pour la plupart des situations, vous pouvez utiliser une liste ou un dictionnaire pour obtenir l'effet souhaité.
Par exemple, pour imprimer les résultats de réussite / échec:
la source
Je voudrais en faire une classe et éviter complètement une énumération. Et puis, avec l'utilisation d'un gestionnaire de type, vous pouvez créer l'objet lorsque vous le récupérez dans la base de données.
C'EST À DIRE:
la source
Je voudrais simplement créer un dictionnaire et utiliser le code comme clé.
Edit: Pour répondre au commentaire sur la recherche inversée (trouver la clé), ce ne serait pas terriblement efficace. Si cela est nécessaire, j'écrirais une nouvelle classe pour le gérer.
la source
Ma première question - Avez-vous accès à la base de données elle-même? Cela devrait être normalisé dans la base de données, idéalement, sinon, toute solution sera sujette à erreur. D'après mon expérience, les champs de données remplis de "OEM" et "CMB" ont tendance à se retrouver avec des choses comme "OEM" et d'autres "données de merde" mélangées au fil du temps .... Si vous pouvez les normaliser, vous pouvez utiliser la clé dans le tableau contenant les éléments comme votre Enum, et vous avez terminé, avec une structure beaucoup plus propre.
Si ce n'est pas disponible, je ferais votre Enum et ferais une classe pour analyser votre chaîne dans l'Enum pour vous. Cela vous donnerait au moins une certaine souplesse dans la gestion des entrées non standard et beaucoup plus de flexibilité pour le piégeage ou la gestion des erreurs que pour toute solution de contournement utilisant Enum.Parse / Reflection / etc. Un dictionnaire fonctionnerait, mais pourrait tomber en panne si vous rencontrez des problèmes de cas, etc.
Je recommanderais d'écrire un cours pour que vous puissiez faire:
Cela préserve la plupart de votre lisibilité sans avoir à modifier la base de données.
la source
Si je comprends bien, vous avez besoin d'une conversion de chaîne en énumération:
Vous pouvez le rendre plus sophistiqué avec des génériques pour le type d'énumération si vous le souhaitez.
la source
Dans VS 2015, vous pouvez utiliser nameof
Usage:
la source
Un petit ajustement à la méthode Glennular Extension, vous pouvez donc utiliser l'extension sur autre chose que sur ENUM;
Ou en utilisant Linq
la source
Suite à la réponse de @Even Mien j'ai essayé d'aller un peu plus loin et de le rendre générique, il me semble que j'y suis presque mais un cas résiste toujours et je peux probablement simplifier un peu mon code.
Je le poste ici si quelqu'un voit comment je pourrais m'améliorer et surtout le faire fonctionner car je ne peux pas l'affecter à partir d'une chaîne
Jusqu'à présent, j'ai les résultats suivants:
Où la magie opère:
Je n'ai qu'à déclarer cela pour mes énumérations:
la source
Nouveau dans .Net Core 3.0 / C # 8.0 (si votre environnement de travail vous permet de mettre à niveau votre projet) est une instruction de commutateur abrégée qui semble quelque peu énumérée. À la fin de la journée, c'est la même vieille déclaration de commutateur ennuyeux que nous utilisons depuis des années.
La seule vraie différence ici est que l'instruction switch a obtenu un nouveau costume.
Vous remarquerez que le code ci-dessus que j'ai copié à partir d' ici utilise en fait une énumération comme paramètre.
Ce n'est pas exactement ce que vous voulez (et croyez-moi, je voulais quelque chose de similaire à ce que l'OP demande depuis longtemps), mais j'ai en fait l'impression que c'est un peu une branche d'olivier de MS. JMO.
J'espère que cela aide quelqu'un!
la source
J'ai utilisé une structure telle que mentionnée dans une réponse précédente, mais j'ai supprimé toute complexité. Pour moi, cela ressemblait plus à la création d'une énumération de chaînes. Il est utilisé de la même manière qu'une énumération est utilisée.
Exemple d'utilisation:
la source
J'ai même implémenté quelques énumérations comme suggéré par @Even (via
class X
etpublic static X
membres), juste pour découvrir plus tard que ces jours-ci, à partir de .Net 4.5, il y a le droitToString()
méthode.Maintenant, je réimplémente tout en énumérant.
la source
C'est une façon de l'utiliser comme paramètre fortement typé ou comme chaîne :
la source
Vous pouvez utiliser deux énumérations. Un pour la base de données et l'autre pour la lisibilité.
Vous avez juste besoin de vous assurer qu'ils restent synchronisés, ce qui semble être un petit coût. Il n'est pas nécessaire de définir les valeurs, il suffit de définir les positions de la même manière, mais la définition des valeurs indique clairement que les deux énumérations sont liées et empêche les erreurs de réorganiser les membres de l'énumération. Et un commentaire permet à l'équipe de maintenance de savoir qu'ils sont liés et doivent être synchronisés.
Pour l'utiliser, il vous suffit de convertir d'abord le code:
Ensuite, si vous voulez le rendre encore plus pratique, vous pouvez ajouter une fonction d'extension qui ne fonctionne que pour ce type d'énumération:
et vous pouvez alors simplement faire:
la source
enum
un changement de valeur prévu dans l'un peut involontairement gâcher l'autre.Je cherchais essentiellement la réponse de réflexion par @ArthurC
Juste pour étendre un peu sa réponse, vous pouvez la rendre encore meilleure en ayant une fonction générique:
Ensuite, vous pouvez simplement envelopper tout ce que vous avez
ou
la source
Tiré de @EvenMien et ajouté dans certains des commentaires. (Aussi pour mon propre cas d'utilisation)
la source
Ajout de cette classe
Ce travail utilise
CallerMemberName
pour minimiser le codageEn utilisant:
Essaye-le:
production:
la source
Basé sur d'autres opinions, c'est ce que je propose. Cette approche évite d'avoir à taper .Value où vous voulez obtenir la valeur constante.
J'ai une classe de base pour toutes les énumérations de chaînes comme celle-ci:
Le JsonConverter est comme ceci:
Et une énumération de chaîne réelle ressemblera à ceci:
Et avec cela, vous pouvez simplement utiliser Color.Red pour sérialiser même en json sans utiliser la propriété Value
la source
Je n'avais besoin de rien de solide comme stocker la chaîne dans des attributs. Je devais juste transformer quelque chose comme
MyEnum.BillEveryWeek
"facture chaque semaine" ouMyEnum.UseLegacySystem
"utiliser le système hérité" - essentiellement diviser l'énumération par son boîtier de chameau en mots individuels en minuscules.MyEnum.UseLegacySystem.UnCamelCase()
sorties "utiliser le système hérité"Si plusieurs drapeaux sont définis, cela le transformera en anglais simple (délimité par des virgules sauf un "et" à la place de la dernière virgule).
la source