Convertir une chaîne en un enum en C#
Quel est le meilleur moyen de convertir une chaîne de valeur de l'énumération en C#?
J'ai un select HTML balise contenant les valeurs d'une énumération. Lorsque la page est affichée, je veux choisir la valeur (qui sera sous la forme d'une chaîne de caractères) et de le convertir à la valeur de l'énumération.
Dans un monde idéal, je pourrais faire quelque chose comme ceci:
StatusEnum MyStatus = StatusEnum.Parse("Active");
mais ce n'est pas un code valide.
Vous devez vous connecter pour publier un commentaire.
Dans .NET de Base et .NET >4 il y a un générique de la méthode d'analyse:
Cela inclut aussi C#7 nouvelles inline
out
variables, si ce n'est l'essai, l'analyse, la conversion explicite de type enum et initialise+remplit lamyStatus
variable.Si vous avez accès à C#7 et la dernière .NET c'est le meilleur moyen.
Réponse Originale À Cette Question
Dans .NET c'est plutôt moche (jusqu'à 4 ou ci-dessus):
J'ai tendance à simplifier ce avec:
Alors je peux le faire:
Une option proposée dans les commentaires, c'est pour ajouter une extension, qui est assez simple:
Enfin, vous voudrez peut-être avoir un défaut enum à utiliser si la chaîne ne peut pas être analysée:
Qui fait de cet appel:
Cependant, je serais prudent, l'ajout d'une méthode d'extension de ce type à
string
sous (sans l'espace de noms de contrôle), il apparaîtra sur toutes les instances destring
s'ils sont titulaires d'un enum ou pas (donc1234.ToString().ToEnum(StatusEnum.None)
serait valide, mais pas de sens) . Il est souvent préférable d'éviter de l'encombrer de Microsoft de base des classes avec des méthodes supplémentaires qui s'appliquent seulement dans des contextes moins que l'ensemble de votre équipe de développement a une très bonne compréhension de ce que ces extensions ne.TryParse
.object
oustring
que sans un espace de noms de contrôler ce sera la cause de votre méthode d'extension pour être visible sur chaque instance de l'ensemble de votre base de code. Ce n'est pas un problème lorsque la méthode est toujours approprié (par exemple.Trim()
ou.Split()
), mais un enum analyser ne va s'appliquer que lorsque la chaîne est prévu de tenir un enum. Une ou deux méthodes de ce genre sont sans doute très bien, mais vous pouvez vous retrouver avec des charges de confusion sur les grands projets.namespace SomeNameSpace.Extensions.Strings
ne serait pas causer des problèmes?SubString()
s'applique toujours à l'encontre d'une chaîne de caractères, et au moment de l'exécution de vérifier si la chaîne est trop courte pour les indices fournis, maisToEnum
peut ou peut ne pas s'appliquer en fonction de ce que vous mettez dans. Ce n'est pas mauvais ou de blocage en tant que tels, juste quelque chose à être prudent avec.public static T ToEnum<T>(this string value, T defaultValue) where T : struct
where T : struct, IComparable
est nécessaire pour être ajouté à la fin de l'extension de la méthode de définition.if(Enum.TryParse("Active", out StatusEnum myStatus)) { /* use myStatus */ }
Utilisation
Enum.TryParse<T>(String, T)
(≥ .NET 4.0):Il est possible de simplifier encore plus loin avec le C# 7.0 paramètre de type inline:
Parse
jette exposé des exceptions pour ce qui s'est passé avec la conversion (valeur a éténull
, vide ou pas de constante enum), ce qui est nettement mieux queTryParse
s'boolean valeur de retour (qui supprime le béton erreur)Noter que la performance de l'Enum.Parse() est terrible, parce qu'il est mis en œuvre par la réflexion. (La même chose est vraie de l'Enum.ToString, qui va dans l'autre sens.)
Si vous avez besoin de convertir des chaînes en Enums des performances sensibles à code, votre meilleur pari est de créer un
Dictionary<String,YourEnum>
au démarrage et à l'utiliser pour faire vos conversions.Vous êtes à la recherche pour Enum.Analyser.
Vous pouvez utiliser les méthodes d'extension maintenant:
Et vous pouvez les appeler par le code ci-dessous (ici,
FilterType
est un type enum):Donc si vous aviez un enum nommé humeur, il ressemblerait à ceci:
ATTENTION:
Enum.(Try)Parse()
accepte plusieurs, séparés par des virgules, des arguments, et les combine avec des binaires "ou"|
. Vous ne pouvez pas désactiver cette et à mon avis vous presque jamais le souhaitez.Même si
Three
n'a pas été défini,x
voudrais quand même valeur int3
. C'est encore pire: Enum.Parse() peut vous donner une valeur qui n'est pas encore défini pour l'enum!Je ne voudrais pas vivre les conséquences d'utilisateurs, de gré ou de force, le déclenchement de ce comportement.
En outre, comme mentionné par d'autres, les performances sont moins qu'idéales pour les grandes enums, à savoir linéaire en le nombre de valeurs possibles.
Je suggère ce qui suit:
Enum.(Try)Parse accepts multiple, comma-separated arguments, and combines them with binary 'or'
. Signifie que vous pouvez définir vos valeurs enum comme des puissances de 2 et vous avez une façon très simple d'analyser plusieurs boolean drapeaux, par exemple. "UseSSL,NoRetries," Sync". En fait, c'est sans doute ce à quoi il a été conçu.Enum.Analyser est votre ami:
Vous pouvez étendre la accepté de répondre avec une valeur par défaut pour éviter les exceptions:
Puis vous l'appeler comme:
Nous ne pouvions pas assumer parfaitement valable d'entrée, et est allé avec cette variation de @Keith réponse:
Analyse de la chaîne de TEnum sans try/catch et sans TryParse() la méthode de .NET 4.5
Super simple code à l'aide de TryParse:
J'aime la méthode d'extension de la solution..
Ici en dessous de ma mise en œuvre avec des tests.
====================Un Programme Complet====================
J'ai utilisé de la classe (fortement typées version de Enum avec l'analyse et des améliorations de performances). Je l'ai trouvé sur GitHub, et il doit travailler pour .NET 3.5 trop. Il a une certaine surcharge de la mémoire car il tamponne un dictionnaire.
Le blog est Les Enums – Meilleure syntaxe, l'amélioration de la performance et de TryParse NET 3.5.
Et le code:
https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/System/EnumT.cs
Pour la performance, ce qui pourrait aider:
J'ai trouvé que le cas ici avec les valeurs de l'enum qui ont EnumMember valeur n'a pas été considéré. Donc, ici, nous allons:
Et l'exemple de l'enum:
Vous devez utiliser le protocole Enum.Analyser pour obtenir la valeur de l'objet de l'Enum, après cela, vous devez modifier la valeur de l'objet spécifique de la valeur d'enum. Casting à la valeur d'enum peut être par le biais de Convertir.ChangeType. S'il vous plaît avoir un oeil sur l'extrait de code suivant
Essayez cet exemple:
Dans cet exemple, vous pouvez envoyer toutes les chaînes, et de définir votre
Enum
. Si votreEnum
avait des données que vous avez voulu, de retour en tant queEnum
type.newModel
sur chaque ligne, donc si il contient des tirets, il ne sera pas remplacé. Aussi, vous n'avez pas à vérifier si la chaîne contient quoi que ce soit, vous pouvez simplement appelerReplace
de toute façon:var newModel = model.Replace("-", "").Replace(" ", "");