Given the following routine:
private static object ParseNumber(string token, FieldDefinition def)
{
if (def.Fraction > 0)
return Double.Parse(token);
else
return Int64.Parse(token);
}
Resharper offers me the option to refactor it into a statement with the ternary operator:
private static object ParseNumber(string token, FieldDefinition def)
{
return def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token);
}
Who can spot the trap?
Okay, change to previous answer. Because there's an implicit conversion from Int64
to Double
(but not vice versa), that will be the result type of the expression. So when you expect to get a boxed Int64
, you actually get a boxed Double
(but with a value which originally came from Int64.Parse
).
Just in case that's not clear enough, let's change all the return
statements such that they just return a variable. Here's the original code:
private static object ParseNumber(string token, FieldDefinition def)
{
if (def.Fraction > 0)
return Double.Parse(token);
else
return Int64.Parse(token);
}
Convert that appropriately:
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;
}
}
And now let's do the same to the version with the conditional operator:
private static object ParseNumber(string token, FieldDefinition def)
{
return def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token);
}
becomes
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: As requested, a bit more information. The type of a conditional expression of the form
X ? Y : Z
depends on the types of Y
and Z
, which I'll call TY
and TZ
. There are a few options:
TY
and TZ
are the same type: result is that typeTY
to TZ
but not from TZ
to TY
: the result is of type TZ
and the conversion is used if the first branch is used.TZ
to TY
but not from TY
to TZ
: the result is of type TY
and the conversion is used if the second branch is used.Does that help?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With