2009-03-09 14 views
6

Dada la siguiente rutina:ReSharper Trampa "Convertir a la declaración de 'retorno'"

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

ReSharper me ofrece la opción de refactorizar en un comunicado con el operador ternario:

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

¿Quién puede detectar la trampa?

+0

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

Respuesta

11

Bien, cambie a la respuesta anterior. Debido a que hay una conversión implícita de Int64 a Double (pero no al revés), ese será el tipo de resultado de la expresión. Por lo tanto, cuando espere obtener un recuadro Int64, en realidad obtendrá un recuadro Double (pero con un valor que originalmente provino del Int64.Parse).

En caso de que no sea lo suficientemente claro, cambiemos todas las declaraciones return de modo que simplemente devuelvan una variable. Aquí está el código original:

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

convertir esa manera apropiada:

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; 
    } 
} 

Y ahora vamos a hacer lo mismo para la versión con el operador condicional:

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

convierte

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; 
} 

EDITAR: como reque sted, un poco más de información. El tipo de una expresión condicional de la forma

X ? Y : Z 

depende de los tipos de Y y Z, que me van a llamar TY y TZ. Hay algunas opciones:

  • TY y TZ son del mismo tipo: resultado es que el tipo
  • Hay una conversión implícita de TY a TZ pero no de TZ a TY: el resultado es de tipo TZ y la la conversión se usa si se usa la primera rama.
  • Hay una conversión implícita de TZ a TY pero no de TY a TZ: el resultado es de tipo TY y se utiliza la conversión si se utiliza la segunda rama.
  • Hay una conversión implícita en los dos sentidos: en tiempo de compilación de error
  • No hay conversiones en ambos sentidos: en tiempo de compilación de error

¿Ayuda?

+0

Éste me consiguió antes ... – leppie

+0

Lo publiqué hace unos 6 meses en CodeProject. De hecho, da miedo que un entero sea implícitamente un doble, aunque pierda precisión. – leppie

+0

¿Podría quizás agregar una oración o dos sobre por qué ocurre la conversión implícita al doble?(presumiblemente alguna propiedad del operador ternario/condicional) – Miles

Cuestiones relacionadas