2012-10-27 2 views
3

Il m'est arrivé de parcourir le code source de l'infrastructure .net et de passer à travers l'implémentation de l'opérateur explicite pour l'implémentation struct Nullable. Les captures d'écran ci-dessous montrent l'implémentation de la propriété Value et aussi l'implémentation de l'opérateur explicite. Je comprends également que l'opérateur explicite tente de convertir Nullable à T. Ma question est pourquoi est-il pas que le code suivant n'est pas jeter une exceptionConfusion à propos de l'implémentation de l'opérateur explicite pour Nullable <T> struct

mise en œuvre du cadre

 public T Value { 
     get { 
      if (!HasValue) { 
       ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue); 
      } 
      return value; 
     } 
    } 

public static explicit operator T(Nullable<T> value) { 
     return value.Value; 
    } 

Code Custome

int? i = null; 
int? i2 = (int?)i; //No Error 

int? i = null; 
int i2 = (int)i; //Runtime error 

Il est dit value.Value et, idéalement, puisque HasValue sera faux (puisque j'ai assigné une valeur nulle), il devrait renvoyer une exception d'opération invalide, mais il affecte heureusement la valeur à i2. Cependant, au lieu de (int?) I si nous le changeons en (int), la propriété InvalidOperatorException from Value est levée. Ma pensée était quand value.Value est appelée, elle lèvera une exception parce que cette propriété est accédée et elle fera son travail.

S'il vous plaît préciser sur la même

Merci,

Sai Pavan

Répondre

0

Vous pouvez être dérouté par l'opérateur explicite.

Ce n'est pas un "opérateur explicite", c'est "l'opérateur explicite T". Dans votre cas, cela devient "explicit operator int", car T est int.

L'opérateur expl explicite n'est appelé que si vous convertissez explicitement en un int (l'indice est dans le nom ;-)). Donc, comme cela a été dit, i1 ne nécessite pas de conversion en int et l'opérateur explicite int n'est pas appelé. Donc, compte tenu de ce que vous avez dit laisse dire si j'ai mis int?

2

Parce que vous lancez à int? et non à int

public static explicit operator T(Nullable<T> value) { 
    return value.Value; 
} 

T est int mais vous êtes coulée à int? donc Value n'a jamais été ca lled.

+0

(comme dans le premier cas) il doit appeler le droit de la propriété droit? Dans un tel scénario quand il est appelé, il doit lever l'exception car HasValue sera faux. Pourriez-vous s'il vous plaît laissez-moi savoir comment cela fonctionne dans ce scénario? – usaipavan

+0

@usaipavan HasValue ne sera jamais appelé parce que le nullable est simplement copié sans appeler aucun opérateur explicite car il y a un opérateur défini pour 'T?' (Qui ne fonctionnera pas de toute façon). –

1

Dans le cas de int? i2 = (int?)i; //No Error, la méthode d'opérateur explicite n'est jamais appelée sur i parce que vous imputez à int? et non à .

2
int? i2 = (int?)i; 

est juste une opération de copie directement int?-int?. Aucun opérateur de conversion n'est impliqué. Ceci est une copie à plat du contenu de la mémoire de la variable struct.