Trampa de Resharper "Convertir a declaración de 'retorno'"
-
06-07-2019 - |
Pregunta
Dada la siguiente rutina:
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 refactorizarlo en una declaración 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?
Solución
Bien, cambia 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. Entonces, cuando espera obtener un Int64
en caja, en realidad obtiene un Double
en caja (pero con un valor que originalmente vino de Int64.Parse
) .
En caso de que no sea lo suficientemente claro, cambiemos todas las declaraciones return
de modo que solo 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);
}
Convierta eso apropiadamente:
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 hagamos lo mismo con 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);
}
se convierte en
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: según lo solicitado, un poco más de información. El tipo de una expresión condicional del formulario
X ? Y : Z
depende de los tipos de Y
y Z
, que llamaré TY
y TZ
. Hay algunas opciones:
-
TY
yTZ
son del mismo tipo: el resultado es ese tipo - Hay una conversión implícita de
TY
aTZ
pero no deTZ
aTY
: el resultado es de escribaTZ
y la conversión se usa si se usa la primera rama. - Hay una conversión implícita de
TZ
aTY
pero no deTY
aTZ
: el resultado es de escribaTY
y la conversión se usa si se usa la segunda rama. - Hay una conversión implícita en ambas direcciones: error en tiempo de compilación
- No hay conversiones de ninguna manera: error en tiempo de compilación
¿Eso ayuda?