Je veux écrire une fonction qui peut valider une valeur donnée (passée sous forme de chaîne) par rapport aux valeurs possibles d'un enum
. Dans le cas d'une correspondance, il doit renvoyer l'instance enum; sinon, il doit renvoyer une valeur par défaut.
La fonction ne peut pas utiliser en interne try
/ catch
, ce qui exclut l'utilisation Enum.Parse
, qui lève une exception quand un argument non valide est donné.
Je voudrais utiliser quelque chose comme une TryParse
fonction pour implémenter ceci:
public static TEnum ToEnum<TEnum>(this string strEnumValue, TEnum defaultValue)
{
object enumValue;
if (!TryParse (typeof (TEnum), strEnumValue, out enumValue))
{
return defaultValue;
}
return (TEnum) enumValue;
}
Réponses:
Comme d'autres l'ont dit, vous devez mettre en œuvre le vôtre
TryParse
. Simon Mourier fournit une mise en œuvre complète qui s'occupe de tout.Si vous utilisez des énumérations de champs de bits (c'est-à-dire des indicateurs), vous devez également gérer une chaîne comme
"MyEnum.Val1|MyEnum.Val2"
qui est une combinaison de deux valeurs d'énumération. Si vous appelez simplementEnum.IsDefined
avec cette chaîne, il retournera false, même s'il leEnum.Parse
gère correctement.Mettre à jour
Comme mentionné par Lisa et Christian dans les commentaires,
Enum.TryParse
est maintenant disponible pour C # dans .NET4 et plus.Documents MSDN
la source
Enum.IsDefined fera avancer les choses. Ce n'est peut-être pas aussi efficace qu'un TryParse, mais cela fonctionnera sans traitement d'exception.
A noter: une
TryParse
méthode a été ajoutée dans .NET 4.0.la source
GetNames
. En interne, toutes ces méthodes (y comprisParse
) utilisentGetHashEntry
, ce qui fait la réflexion réelle - une fois. Du bon côté, .NET 4.0 a un TryParse, et c'est générique aussi :)Voici une implémentation personnalisée de
EnumTryParse
. Contrairement à d'autres implémentations courantes, il prend également en charge les énumérations marquées avec l'Flags
attribut.la source
Activator.CreateInstance(type)
pour créer la valeur d'énumération par défaut et nonEnum.ToObject(type, 0)
. Juste une question de goût?En fin de compte, vous devez mettre en œuvre ceci autour de
Enum.GetNames
:Notes complémentaires:
Enum.TryParse
est inclus dans .NET 4. Voir ici http://msdn.microsoft.com/library/dd991876(VS.100).aspxEnum.Parse
capture de l'exception levée en cas d'échec. Cela pourrait être plus rapide lorsqu'une correspondance est trouvée, mais sera probablement plus lent sinon. En fonction des données que vous traitez, cela peut ou non être une nette amélioration.EDIT: Je viens de voir une meilleure implémentation à ce sujet, qui met en cache les informations nécessaires: http://damieng.com/blog/2010/10/17/enums-better-syntax-improved-performance-and-tryparse-in-net- 3-5
la source
Flags
attribut.Basé sur .NET 4.5
Exemple de code ci-dessous
Référence: http://www.dotnetperls.com/enum-parse
la source
J'ai une implémentation optimisée que vous pouvez utiliser dans UnconstrainedMelody . En fait, il ne s'agit que de mettre en cache la liste des noms, mais cela se fait d'une manière agréable, fortement typée et contrainte de manière générique :)
la source
...
la source
Il n'y a actuellement aucun Enum.TryParse prêt à l'emploi. Cela a été demandé sur Connect ( toujours pas Enum.TryParse ) et a obtenu une réponse indiquant une éventuelle inclusion dans le prochain framework après .NET 3.5. Vous devrez mettre en œuvre les solutions de contournement suggérées pour le moment.
la source
Le seul moyen d'éviter la gestion des exceptions est d'utiliser la méthode GetNames (), et nous savons tous que les exceptions ne doivent pas être utilisées abusivement pour la logique d'application commune :)
la source
La mise en cache d'une fonction / dictionnaire généré dynamiquement est-elle autorisée?
Comme vous ne connaissez pas (semblez-vous) le type d'énumération à l'avance, la première exécution pourrait générer quelque chose dont les exécutions ultérieures pourraient tirer parti.
Vous pouvez même mettre en cache le résultat de Enum.GetNames ()
Essayez-vous d'optimiser le processeur ou la mémoire? En avez-vous vraiment besoin?
la source
Comme d'autres l'ont déjà dit, si vous n'utilisez pas Try & Catch, vous devez utiliser IsDefined ou GetNames ... Voici quelques exemples ... ils sont fondamentalement tous les mêmes, le premier gérant des énumérations nullables. Je préfère le 2ème car c'est une extension sur des cordes, pas des enums ... mais vous pouvez les mélanger comme vous le souhaitez!
la source
Il n'y a pas de TryParse car le type d'Enum n'est pas connu avant l'exécution. Un TryParse qui suit la même méthodologie que la méthode Date.TryParse lèverait une erreur de conversion implicite sur le paramètre ByRef.
Je suggère de faire quelque chose comme ça:
la source
Try
méthodes dont les résultats peuvent être des types valeur, ou dont le résultatnull
peut être légitime (parDictionary.TryGetValue, which has both such traits), the normal pattern is for a
exemple, la méthode Try` pour renvoyerbool
et transmettre le résultat en tant queout
paramètre. Pour celles qui renvoient des types de classe oùnull
n'est pas un résultat valide, il n'y a aucune difficulté à utiliser unnull
retour pour indiquer l'échec.Jetez un œil à la classe Enum (struct?) Elle-même. Il existe une méthode Parse à ce sujet, mais je ne suis pas sûr d'un tryparse.
la source
Cette méthode convertira un type d'énumération:
Il vérifie le type sous-jacent et obtient le nom par rapport à lui à analyser. Si tout échoue, la valeur par défaut sera renvoyée.
la source