Modifier : Commentaires en bas de page. Aussi, este .
Voilà ce qui me perturbe un peu. Si je comprends bien, si j'ai un enum comme celui-ci...
enum Animal
{
Dog,
Cat
}
...ce que j'ai fait essentiellement est de définir une type de valeur appelé Animal
avec deux valeurs définies, Dog
y Cat
. Ce type dérive de la type de référence System.Enum
(ce que les types de valeur ne peuvent normalement pas faire - du moins pas en C# - mais qui est autorisé dans ce cas), et dispose d'une fonction permettant de faire des allers-retours vers/depuis int
valeurs.
Si la façon dont j'ai décrit le type d'enum ci-dessus était vraie, alors je m'attendrais à ce que le code suivant lève une erreur de type InvalidCastException
:
public class Program
{
public static void Main(string[] args)
{
// Box it.
object animal = Animal.Dog;
// Unbox it. How are these both successful?
int i = (int)animal;
Enum e = (Enum)animal;
// Prints "0".
Console.WriteLine(i);
// Prints "Dog".
Console.WriteLine(e);
}
}
Normalement, vous ne pouvez pas débloquer un type de valeur de System.Object
comme autre chose que son type exact . Comment cela est-il possible ? C'est comme si le Animal
type est un int
(pas seulement convertible a int
) et est un Enum
(pas seulement convertible a Enum
) en même temps. S'agit-il d'un héritage multiple ? Est-ce que System.Enum
héritent en quelque sorte de System.Int32
(ce que je n'aurais pas cru possible) ?
Modifier : Ça ne peut être ni l'un ni l'autre. Le code suivant le démontre (je pense) de manière concluante :
object animal = Animal.Dog;
Console.WriteLine(animal is Enum);
Console.WriteLine(animal is int);
Les sorties ci-dessus :
True
False
Les deux sites la documentation MSDN sur les énumérations et la spécification C# utilisent le terme "type sous-jacent", mais je ne sais pas ce que cela signifie et je n'ai jamais entendu ce terme utilisé en référence à autre chose que des enums. Que signifie "type sous-jacent" en réalité moyenne ?
Alors, est-ce que c'est encore un autre qui bénéficie d'un traitement spécial de la part du CLR ?
Je parie que c'est le cas... mais une réponse/explication serait la bienvenue.
Mise à jour : Damien_Le_incrédule a fourni la référence pour répondre réellement à cette question. L'explication se trouve dans la Partition II de la spécification CLI, dans la section sur les enums :
À des fins de liaison (par exemple, pour localiser une définition de méthode à partir de la référence de la méthode utilisée pour l'appeler) les enums doivent être distincts de leur type sous-jacent. Pour toutes les autres fins, y compris la vérification et l'exécution l'exécution du code, un enum sans boîte s'interconvertit librement avec son type sous-jacent . Les enums peuvent être mis en boîte à un type d'instance boxé correspondant correspondant, mais ce type est pas le même que le type encadré du type sous-jacent sous-jacent, de sorte que la mise en boîte ne perd pas le type original de l'enum.
Modifier (encore ? !) : Attends, en fait, je ne sais pas si j'ai bien lu la première fois. Peut-être que cela n'explique pas à 100% le comportement de déballage spécialisé lui-même (bien que je laisse la réponse de Damien comme acceptée, car elle a apporté beaucoup de lumière sur cette question). Je vais continuer à chercher dans ce domaine...
Une autre édition : Homme, alors La réponse de yodaj007 m'a jeté dans une autre boucle. D'une certaine manière, un enum n'est pas exactement le même qu'un int
; pourtant un int
peut être assigné à une variable enum sans casting ? Buh ?
Je pense que tout cela est finalement éclairé par Réponse de Hans c'est pourquoi je l'ai accepté. (Désolé, Damien !)