ReSharper Trap “Converter para declaração 'return'”
-
06-07-2019 - |
Pergunta
Dada a seguinte rotina:
private static object ParseNumber(string token, FieldDefinition def)
{
if (def.Fraction > 0)
return Double.Parse(token);
else
return Int64.Parse(token);
}
ReSharper me oferece a opção de refazer-lo em uma declaração com o operador ternário:
private static object ParseNumber(string token, FieldDefinition def)
{
return def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token);
}
Quem pode manchar a armadilha?
Solução
Ok, mude para resposta anterior. Porque não há uma conversão implícita de Int64
para Double
(mas não vice-versa), que será o tipo de resultado da expressão. Então, quando você espera obter um Int64
encaixotado, você realmente obter uma Double
box (mas com um valor que veio originalmente de Int64.Parse
).
Apenas no caso de isso não é suficiente clara, vamos mudar todas as declarações return
de tal forma que eles só retornam uma variável. Aqui está o código original:
private static object ParseNumber(string token, FieldDefinition def)
{
if (def.Fraction > 0)
return Double.Parse(token);
else
return Int64.Parse(token);
}
Convert que apropriadamente:
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;
}
}
E agora vamos fazer o mesmo com a versão com o operador condicional:
private static object ParseNumber(string token, FieldDefinition def)
{
return def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token);
}
se torna
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: Conforme solicitado, uma informação pouco mais. O tipo de uma expressão condicional da forma
X ? Y : Z
depende dos tipos de Y
e Z
, que eu vou chamar TY
e TZ
. Existem algumas opções:
-
TY
eTZ
são do mesmo tipo: resultado é que tipo - Há uma conversão implícita de
TY
paraTZ
mas não deTZ
paraTY
:. O resultado é do tipoTZ
ea conversão é usado se o primeiro ramo é usado - Há uma conversão implícita de
TZ
paraTY
mas não deTY
paraTZ
:. O resultado é do tipoTY
ea conversão é usado se o segundo ramo é usado - Há uma conversão implícita em ambas as direções: Erro em tempo de compilação
- Não há conversões de qualquer maneira: Erro em tempo de compilação
Isso ajuda?