Si j'ai une énumération comme celle-ci:
enum Beer
{
Bud = 10,
Stella = 20,
Unknown
}
Pourquoi ne lance-t-il pas une exception lors de la conversion d'un int
qui est en dehors de ces valeurs en un type de Beer
?
Par exemple, le code suivant ne lève pas d'exception, il renvoie '50' à la console:
int i = 50;
var b = (Beer) i;
Console.WriteLine(b.ToString());
Je trouve cela étrange ... quelqu'un peut-il clarifier?
Réponses:
Tiré de la confusion avec l'analyse d'une énumération
C'était une décision de la part des personnes qui ont créé .NET. Un enum est soutenu par un autre type de valeur (
int
,short
,byte
, etc.), et il peut effectivement avoir une valeur qui est valable pour ces types de valeur.Personnellement, je ne suis pas fan de la façon dont cela fonctionne, j'ai donc créé une série de méthodes utilitaires:
De cette façon, je peux dire:
... ou:
Éditer
Au-delà de l'explication donnée ci-dessus, vous devez vous rendre compte que la version .NET d'Enum suit un modèle plus inspiré du C que celui de Java. Cela permet d'avoir des énumérations "Bit Flag" qui peuvent utiliser des modèles binaires pour déterminer si un "drapeau" particulier est actif dans une valeur enum. Si vous deviez définir toutes les combinaisons possibles d'indicateurs (c'est
MondayAndTuesday
-à- direMondayAndWednesdayAndThursday
), ce serait extrêmement fastidieux. Ainsi, avoir la capacité d'utiliser des valeurs d'énumération non définies peut être très pratique. Cela nécessite juste un peu de travail supplémentaire lorsque vous voulez un comportement rapide sur les types enum qui ne tirent pas parti de ces types d'astuces.la source
Les énumérations sont souvent utilisées comme indicateurs:
La valeur de p est l'entier 3, qui n'est pas une valeur de l'énumération, mais est clairement une valeur valide.
Personnellement, j'aurais préféré voir une solution différente; J'aurais préféré avoir la capacité de faire des types entiers "bit array" et des types "un ensemble de valeurs distinctes" comme deux caractéristiques de langage différentes plutôt que de les fusionner tous les deux en "enum". Mais c'est ce que les concepteurs du langage et du cadre d'origine ont proposé; par conséquent, nous devons autoriser les valeurs non déclarées de l'énumération à être des valeurs légales.
la source
La réponse courte: les concepteurs de langage ont décidé de concevoir le langage de cette façon.
La réponse longue:
Section 6.2.2: Explicit enumeration conversions
de la spécification du langage C # dit:Fondamentalement, l' énumération est traitée comme le type sous-jacent lorsqu'il s'agit d'effectuer une opération de conversion. Par défaut, le type sous-jacent d' une énumération est
Int32
, ce qui signifie que la conversion est traitée exactement comme une conversion enInt32
. Cela signifie que touteint
valeur valide est autorisée.Je soupçonne que cela a été fait principalement pour des raisons de performances. En créant
enum
un type intégral simple et en autorisant toute conversion de type intégral, le CLR n'a pas besoin de faire toutes les vérifications supplémentaires. Cela signifie que l'utilisation d'unenum
n'a pas vraiment de perte de performances par rapport à l'utilisation d'un entier, ce qui contribue à encourager son utilisation.la source
De la documentation :
la source