2009-03-09 5 views
6

Compte tenu de la routine suivante:ReSharper Trap "Convertir en déclaration« retour"

private static object ParseNumber(string token, FieldDefinition def) 
{ 
    if (def.Fraction > 0) 
    return Double.Parse(token); 
    else 
    return Int64.Parse(token); 
} 

ReSharper me offre la possibilité de factoriser dans une déclaration avec l'opérateur ternaire:

private static object ParseNumber(string token, FieldDefinition def) 
{ 
    return def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token); 
} 

Qui peut repérer le piège?

+0

http://cznp.com/s/7JM –

Répondre

11

Bon, passez à la réponse précédente. Parce qu'il y a une conversion implicite de Int64 à Double (mais pas vice versa), ce sera le type de résultat de l'expression. Donc, quand vous vous attendez à obtenir une boîte Int64, vous obtenez en fait une boîte Double (mais avec une valeur qui venait à l'origine de Int64.Parse). Juste au cas où ce n'est pas assez clair, changeons toutes les instructions return de sorte qu'elles retournent juste une variable. Voici le code d'origine:

private static object ParseNumber(string token, FieldDefinition def) 
{ 
    if (def.Fraction > 0) 
    return Double.Parse(token); 
    else 
    return Int64.Parse(token); 
} 

Convert que de façon appropriée:

private static object ParseNumber(string token, FieldDefinition def) 
{ 
    if (def.Fraction > 0) 
    { 
    double d = Double.Parse(token); 
    object boxed = d; // Result is a boxed Double 
    return boxed; 
    } 
    else 
    { 
    long l = Int64.Parse(token); 
    object boxed = l; // Result is a boxed Int64 
    return boxed; 
    } 
} 

Et maintenant, nous allons faire la même chose pour la version avec l'opérateur conditionnel:

private static object ParseNumber(string token, FieldDefinition def) 
{ 
    return def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token); 
} 

devient

private static object ParseNumber(string token, FieldDefinition def) 
{ 
    // The Int64.Parse branch will implicitly convert to Double 
    double d = def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token); 
    object boxed = d; // *Always* a Double 
    return boxed; 
} 

EDIT: Comme reque sted, un peu plus d'informations. Le type d'une expression conditionnelle de la forme

X ? Y : Z 

dépend des types de Y et Z, que je vais appeler TY et TZ. Il y a quelques options:

  • TY et TZ sont du même type: résultat est ce type
  • Il y a une conversion implicite de TY à TZ mais pas de TZ à TY: le résultat est de type TZ et la la conversion est utilisée si la première branche est utilisée.
  • Il y a une conversion implicite de TZ à TY mais pas de TY à TZ: le résultat est de type TY et la conversion est utilisée si la deuxième branche est utilisée.
  • Il y a une conversion implicite dans les deux sens: erreur de compilation
  • Il n'y a pas les conversions: la compilation erreur

Est-ce que l'aide?

+0

Celui-ci m'a eu avant ... – leppie

+0

Je l'ai posté environ 6 mois en arrière sur CodeProject. En fait, il est effrayant qu'un entier soit implicitement un double, même s'il perd de la précision. – leppie

+0

Pourriez-vous ajouter une phrase ou deux sur la raison pour laquelle la conversion implicite en double se produit?(vraisemblablement une certaine propriété de l'opérateur ternaire/conditionnel) – Miles