web-dev-qa-db-fra.com

C # casting en nullable?

Au-delà la différence ennuyeuse entre Cast et As

  • si je sais que Apple est un Fruit donc je peux utiliser (Fruit)Apple - et il lève une exception s'il ne l'est pas 
  • as value peut être comparé à null pour voir s'il a réussi [ne lève pas Exception ...]

Cependant, j'ai lu @EricLippert article à ce sujet et il y avait un exemple intéressant sur les types de valeur Nullable: 

short? s = (short?)123;
int? i = s as int?;

cette ne sera pas compiler ... 

Impossible de convertir le type 'short?' à 'int?' via une conversion de référence, une conversion de boxe, une conversion de unboxing, une conversion d'habillage ou une conversion de type null

Bien.

alors pourquoi ceci: 

    short? s = (short?)123;
    int? i = (int?)s;

Est-ce que Compile? (Contre TOUTES les attentes _! Je SAIS que s n'est pas int? - et ça devrait aller BANG mais ça ne va pas ...)

le casting vérifiant ici devrait être beaucoup plus meurtrier que l'ancien exemple (qui est allé Bang)

Je me sens mal de poser des questions sur ce sujet très discuté.

Merci d'avance.

27
Royi Namir

Dans votre premier exemple, l'opérateur as tente d'utiliser l'objet s en tant que int?. Étant donné que int? ne figure nulle part dans la chaîne d'héritage de short?, cette opération échoue.

Dans votre deuxième exemple, vous créez en fait un nouveau int? i avec la valeur de short? s. Il s'agit d'une opération plus généreuse, car il n'est pas nécessaire de conserver l'objet s d'origine sur le côté gauche.

Le point important ici est que as n'est pas autorisé à faire quoi que ce soit qui ne préserve pas l'identité de votre objet. Une distribution explicite peut.

Voici ce que dit la norme C # sur le fonctionnement du formulaire (int?):

6.1.4 Conversions nullables implicites

Conversions implicites prédéfinies qui fonctionnent sur une valeur non nullable Les types peuvent également être utilisés avec les formes nullables de ces types. Pour chacun de l'identité implicite prédéfinie et les conversions numériques qui convertissent d'une valeur non nullable de type S à une valeur non nullable de type T, le Les conversions nullables implicites suivantes existent:

· Une conversion implicite de S? à T ?.

· Une conversion implicite de S en T ?.

Évaluation d'une conversion implicite nullable basée sur un sous-jacent la conversion de S en T se déroule comme suit:

· Si la conversion Nullable provient de S? à T ?:

o Si la valeur source est null (la propriété HasValue est false), le résultat est la valeur nulle du type T ?.

o Sinon, la conversion est évaluée en tant que décompression de S? à S, suivi de la conversion sous-jacente de S en T, suivi de envelopper (§ 4.1.10) de T à T ?.

· Si la conversion nullable est de S en T ?, la conversion est évaluée en tant que conversion sous-jacente de S en T suivie d'un envelopper de T à T ?.

25
sblom

L'exemple:

int? i = (int?)s;

Compilateur, car un acteur dit au compilateur que vous savez quelque chose qu'il ne peut pas déduire, à savoir que s peut être converti en int?.

Vous n'obtiendrez l'exception au moment de l'exécution que si la conversion a échoué.

4
Oded

Je pense que c'est en cas d'échec de as que vous obtiendrez un résultat "valide" null, donc faux positif . Dans le second cas, la conversion est autorisée, car en cas d'échec, une exception est déclenchée.

0
Tigran

La raison est que int? est simplement un raccourci pour System.Nullable<int> (System.Nullable<T> est le type). Le type court définit une conversion explicite en un entier. Cependant, System.Nullable<T> ne possède pas de telle conversion explicite, car T pourrait être un autre type de valeur.

0
Andy