Dans .NET Core et .NET> 4, il existe une méthode d'analyse générique :
Enum.TryParse("Active", out StatusEnum myStatus);
Cela inclut également les nouvelles out
variables en ligne de C # 7 , donc cela fait le try-parse, la conversion au type d'énumération explicite et initialise + remplit la myStatus
variable.
Si vous avez accès à C # 7 et au dernier .NET, c'est la meilleure façon.
Réponse originale
Dans .NET, c'est plutôt moche (jusqu'à 4 ou plus):
StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true);
J'ai tendance à simplifier cela avec:
public static T ParseEnum<T>(string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
Ensuite, je peux faire:
StatusEnum MyStatus = EnumUtil.ParseEnum<StatusEnum>("Active");
Une option suggérée dans les commentaires est d'ajouter une extension, ce qui est assez simple:
public static T ToEnum<T>(this string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
StatusEnum MyStatus = "Active".ToEnum<StatusEnum>();
Enfin, vous voudrez peut-être avoir une énumération par défaut à utiliser si la chaîne ne peut pas être analysée:
public static T ToEnum<T>(this string value, T defaultValue)
{
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
T result;
return Enum.TryParse<T>(value, true, out result) ? result : defaultValue;
}
Ce qui en fait l'appel:
StatusEnum MyStatus = "Active".ToEnum(StatusEnum.None);
Cependant, je serais prudent d'ajouter une méthode d'extension comme celle-ci string
car (sans contrôle d'espace de noms), elle apparaîtra sur toutes les instances, string
qu'elles contiennent ou non une énumération (ce 1234.ToString().ToEnum(StatusEnum.None)
serait donc valide mais absurde). Il est souvent préférable d'éviter d'encombrer les classes principales de Microsoft avec des méthodes supplémentaires qui ne s'appliquent que dans des contextes très spécifiques, à moins que toute votre équipe de développement ne comprenne très bien ce que font ces extensions.
Utilisez
Enum.TryParse<T>(String, T)
(≥ .NET 4.0):Il peut être encore simplifié avec l' inline de type de paramètre de C # 7.0 :
la source
Parse
lève des exceptions explicatives pour ce qui n'a pas fonctionné avec la conversion (la valeur étaitnull
, vide ou aucune constante d'énumération correspondante), ce qui est bien mieux queTryParse
la valeur de retour booléenne (qui supprime l'erreur concrète)var result = Enum.TryParse<System.DayOfWeek>("55", out var parsedEnum);
Notez que les performances de
Enum.Parse()
sont horribles, car elles sont implémentées via la réflexion. (Il en va de même pourEnum.ToString
, ce qui va dans l'autre sens.)Si vous devez convertir des chaînes en Enums dans un code sensible aux performances, votre meilleur pari est de créer un
Dictionary<String,YourEnum>
démarrage et de l'utiliser pour effectuer vos conversions.la source
Vous recherchez Enum.Parse .
la source
Vous pouvez maintenant utiliser des méthodes d'extension :
Et vous pouvez les appeler par le code ci-dessous (voici
FilterType
un type enum):la source
Donc, si vous aviez une énumération nommée humeur, cela ressemblerait à ceci:
la source
IL FAUT SE MÉFIER:
Enum.(Try)Parse()
accepte plusieurs arguments séparés par des virgules et les combine avec le binaire «ou»|
. Vous ne pouvez pas désactiver cela et à mon avis, vous ne le voulez presque jamais.Même s'il
Three
n'était pas défini,x
obtiendrait toujours une valeur int3
. C'est encore pire: Enum.Parse () peut vous donner une valeur qui n'est même pas définie pour l'énumération!Je ne voudrais pas ressentir les conséquences des utilisateurs, volontairement ou non, déclenchant ce comportement.
De plus, comme mentionné par d'autres, les performances sont loin d'être idéales pour les énumérations volumineuses, à savoir linéaires dans le nombre de valeurs possibles.
Je suggère ce qui suit:
la source
Enum.(Try)Parse accepts multiple, comma-separated arguments, and combines them with binary 'or'
. Signifie que vous pouvez configurer vos valeurs d'énumération en tant que puissances de 2 et que vous avez un moyen très simple d'analyser plusieurs drapeaux booléens, par exemple. "UseSSL, NoRetries, Sync". En fait, c'est probablement pour cela qu'il a été conçu.Enum.Parse est votre ami:
la source
Vous pouvez étendre la réponse acceptée avec une valeur par défaut pour éviter les exceptions:
Ensuite, vous l'appelez comme:
Si la valeur par défaut n'est pas une énumération, Enum.TryParse échouera et lèvera une exception qui est interceptée.
Après des années d'utilisation de cette fonction dans notre code à de nombreux endroits, il est peut-être bon d'ajouter les informations selon lesquelles cette opération coûte des performances!
la source
defaultValue
et le type de retour de méthode sont tous les deux de typeT
. Si les types sont différents, vous recevrez une erreur de temps de compilation: «ne peut pas convertir de« ConsoleApp1.Size »en« ConsoleApp1.Color »» ou quels que soient vos types.Nous ne pouvions pas supposer une entrée parfaitement valide, et nous sommes allés avec cette variation de la réponse de @ Keith:
la source
la source
Analyse la chaîne en TEnum sans try / catch et sans méthode TryParse () à partir de .NET 4.5
la source
Code super simple utilisant TryParse:
la source
J'aime la solution de la méthode d'extension ..
Voici ci-dessous mon implémentation avec tests.
la source
==================== Un programme complet ====================
la source
J'ai utilisé la classe (version fortement typée d'Enum avec analyse et améliorations des performances). Je l'ai trouvé sur GitHub, et cela devrait également fonctionner pour .NET 3.5. Il a une surcharge de mémoire car il met en mémoire tampon un dictionnaire.
Le blogpost est Enums - Meilleure syntaxe, performances améliorées et TryParse dans NET 3.5 .
Et code: https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/System/EnumT.cs
la source
Pour les performances, cela pourrait aider:
la source
J'ai trouvé qu'ici le cas des valeurs enum qui ont une valeur EnumMember n'a pas été considéré. Alors c'est parti:
Et exemple de cette énumération:
la source
Vous devez utiliser Enum.Parse pour obtenir la valeur d'objet à partir d'Enum, après quoi vous devez changer la valeur d'objet en valeur d'énumération spécifique. La conversion en valeur énumérée peut être effectuée à l'aide de Convert.ChangeType. Veuillez consulter l'extrait de code suivant
la source
Essayez cet exemple:
Dans cet exemple, vous pouvez envoyer chaque chaîne et définir votre
Enum
. Si vousEnum
aviez des données que vous vouliez, renvoyez-les commeEnum
type.la source
newModel
sur chaque ligne, donc si elle contient des tirets, elle ne sera pas remplacée. De plus, vous n'avez pas à vérifier si la chaîne contient quelque chose, vous pouvez simplement appeler deReplace
toute façon:var newModel = model.Replace("-", "").Replace(" ", "");
Je ne sais pas quand cela a été ajouté, mais sur la classe Enum, il y a maintenant un
Parse<TEnum>(stringValue)
Utilisé comme tel avec l'exemple en question:
var MyStatus = Enum.Parse<StatusEnum >("Active")
ou en ignorant le boîtier par:
var MyStatus = Enum.Parse<StatusEnum >("active", true)
Voici les méthodes décompilées utilisées:
la source
la source
la source
Si le nom de la propriété est différent de ce que vous voulez l'appeler (c'est-à-dire les différences de langue), vous pouvez faire comme ceci:
MyType.cs
EnumExtensions.cs
Program.cs
la source