J'ai lu quelques articles SO et il semble que la plupart des opérations de base manquent.
public enum LoggingLevel
{
Off = 0,
Error = 1,
Warning = 2,
Info = 3,
Debug = 4,
Trace = 5
};
if (s == "LogLevel")
{
_log.LogLevel = (LoggingLevel)Convert.ToInt32("78");
_log.LogLevel = (LoggingLevel)Enum.Parse(typeof(LoggingLevel), "78");
_log.WriteDebug(_log.LogLevel.ToString());
}
Cela ne provoque aucune exception, il est heureux de stocker 78
. Existe-t-il un moyen de valider une valeur entrant dans une énumération?
Réponses:
Découvrez Enum.IsDefined
Usage:
Voici l'exemple de cette page:
L'exemple affiche la sortie suivante:
la source
LoggingLevel
comme stockage, puis présentez-la comme uneLoggingLevel
valeur d'énumération.IsDefined
ne fonctionne pas pour les membres enum bitwisés.Les solutions ci-dessus ne traitent pas des
[Flags]
situations.Ma solution ci-dessous peut avoir des problèmes de performances (je suis sûr que l'on pourrait optimiser de différentes manières) mais essentiellement, elle prouvera toujours si une valeur d'énumération est valide ou non .
Il repose sur trois hypothèses:
int
, absolument rien d'autre-
L'appel
ToString()
sur une énumération renvoie laint
valeur si aucune énumération (indicateur ou non) ne correspond. Si une valeur d'énumération autorisée correspond, il affichera le nom de la ou des correspondances.Alors:
Avec ces deux règles à l'esprit, nous pouvons supposer que si le .NET Framework fait correctement son travail, tout appel à une
ToString()
méthode d'énumération valide entraînera quelque chose qui a un caractère alphabétique comme premier caractère:On pourrait appeler cela un "hack", mais les avantages sont qu'en se basant sur la propre implémentation de Microsoft
Enum
et sur les normes C #, vous ne vous fiez pas à votre propre code ou contrôles potentiellement bogués. Dans les situations où les performances ne sont pas exceptionnellement critiques, cela permettra d'économiser beaucoup deswitch
déclarations désagréables ou d'autres vérifications!Éditer
Merci à @ChaseMedallion d'avoir souligné que mon implémentation d'origine ne supportait pas les valeurs négatives. Cela a été corrigé et des tests ont été fournis.
Et les tests pour le sauvegarder:
la source
[Flags]
ont des valeurs entières raisonnables.La réponse canonique serait
Enum.IsDefined
, mais c'est a: un peu lent s'il est utilisé dans une boucle serrée, et b: pas utile pour les[Flags]
énumérations.Personnellement, j'arrêterais de m'inquiéter à ce sujet et
switch
, de manière appropriée, de me souvenir:default:
(ou ayez un videdefault:
expliquant pourquoi)default:
Ainsi:
la source
Utilisation:
la source
Utilisez Enum.IsDefined .
la source
Pour faire face,
[Flags]
vous pouvez également utiliser cette solution de C # Cookbook :Tout d'abord, ajoutez une nouvelle
ALL
valeur à votre énumération:Ensuite, vérifiez si la valeur est dans
ALL
:la source
Une façon de faire serait de s'appuyer sur le cast et la conversion d'énumération en chaîne. Lors du transtypage de int en un type Enum, l'int est soit converti en une valeur d'énumération correspondante, soit l'énumération résultante contient simplement int comme valeur si la valeur enum n'est pas définie pour l'int.
Non testé pour les cas extrêmes.
la source
Comme les autres l'ont dit,
Enum.IsDefined
retournefalse
même si vous avez une combinaison valide d'indicateurs de bits pour une énumération décorée avec leFlagsAttribute
.Malheureusement, le seul moyen de créer une méthode retournant true pour les indicateurs de bits valides est un peu long:
Vous pouvez mettre en cache les résultats de
GetCustomAttribute
dans un dictionnaire:Notez que le code ci-dessus utilise la nouvelle
Enum
contrainte surT
laquelle n'est disponible que depuis C # 7.3. Vous devez passer unobject value
dans les anciennes versions et l'appelerGetType()
.la source