Question

Considérez le suivant ::

Object box = 5;
int @int = (int)box;  // int = 5
int? nullableInt = box as int?; // nullableInt = 5;
StringComparison @enum = (StringComparison)box; // enum = OrdinalIgnoreCase
StringComparison? nullableEnum = box as StringComparison?; // nullableEnum = null.

2 choses ::

  1. Pourquoi puis-je Unbox StringComparison? Je suppose que cela est dû au fait qu'il est le type sous-jacent est Int32 mais je trouve toujours bizarre.
  2. Pourquoi nullableEnum ont une valeur nulle?

Si je comprends bien le unboxing ne valide est d'un type de valeur est boxed type de ou à un type Nullable. Si int peut Unbox Enum, alors pourquoi ne pas le même vrai pour les valeurs nullables? De même, si au lieu de 5 je StringComparison.OrdinalIgnoreCase boxed, ce serait que nullableInt serait nulle, mais nullableEnum ne serait pas.

Était-ce utile?

La solution

Strictement parlant, je pense que c'est une bug dans voir la mise en œuvre de le moteur d'exécution, étant donné que la spécification C # dit

  

Unboxing à un type nullable produit la valeur nulle du type nullable si la source opérande est nul, ou le résultat enveloppé de unboxing l'instance d'objet du type sous-jacent du type nullable autrement.

Ainsi, si unboxing à StringComparison fonctionne, unboxing alors Nullable devraient fonctionner aussi. Il est un peu difficile de dire si les deux doivent travailler ou les deux devraient échouer. La spécification dit que

  

Pour une conversion unboxing à un non annulable valeur de type donné pour réussir à l'exécution, la valeur de la source opérande doit être une référence à une valeur boxed de cette non-annulable valeur type.

Vous devez décider si un int est un boxed considéré comme une valeur de type boîte StringComparison parce que le type sous-jacent de StringComparison est int. La spécification poursuit en disant qu'une InvalidCastException est levée si la boîte contient un « objet incompatible ». Un int est certainement « compatible » avec StringComparison, parce que vous pouvez en toute sécurité les copier quatre octets à partir du tas dans votre variable StringComparison.

Autres conseils

Quand vous lancez ENUM ou entier à l'objet, il détient toujours des informations de type. Alors box is StringComparison retournera false. Mais il est permis de jeter tout ou enum int à tout ENUM, donc des œuvres de (StringComparison)box explicites de la distribution. Il est un cas particulier pour les énumérations. Nullable<T>, d'autre part, est juste une classe ordinaire, T ne sont pas traités de quelque façon spécifique lorsque vous lancez ou le type de contrôle. Voilà pourquoi ce code lancera une exception.

        StringComparison? nullableEnum = (StringComparison?)nullableInt;

1) Oui, le type de ENUM sous-jacente est int et qui est pourquoi cela fonctionne de cette façon. Encore plus. Vous pouvez faire ce qui suit:

enum MyEnum
{
    One = 1,
    Two = 2,
}

int i = 3;
MyEnum myEnum = (MyEnum)i; // This works without exceptions.

2) Parce que StringComparison? est en fait Nullable<StringComparison> de type différent. Et opérateur as vérifie uniquement si l'objet est du même type que celui spécifié en tant qu'opérateur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top