Double-casting required to convert from int as object to float

boxing, c#, casting, object

Solution

When you unbox a value type that has been put into an `object` box, you must use the correct cast. The conversion from one numeric type to another is an extra cast that comes after the unboxing.

In your case, however, the second cast is really implicit, so you could simplify a little bit to:

if (result is int)
    return (int)result;
else
    return (float)result;

Why do you have boxed value types in the first place? If you don't know what type is boxed, to unbox you will normally have to check with `is` the way you do.

Note, however, that with (`IConvertible`) types like these built-in numeric types, you can also use the `Convert` class, so:

return Convert.ToSingle(result);

It looks more pretty, but I don't think it's faster. It will probably do the same kind of type checking.

If the `parser` gives only numeric types, and if for some reason you insist on boxing these value types, you might as well box them to `IConvertible`, so that involves changing the return type like this:

private IConvertible parser(string expr) {...}

Then your code could go so:

IConvertible result = parser(expr);  // it's some number boxed in an IConvertible reference type
return result.ToSingle(null);  // instance method in IConvertible

Problem

Here's a weird one I ran into. I've got a function that returns an `object`. In a particular case, I know for sure that object is an `int`, but another function calling this function requires a `float`. The only way I could get this to work was the following: ``` private object parser(string expr) {...} private float parseFloat(string expr) { ... object result = parser(expr); if (result is int) return (float)(int)result; else return (float)result; } ``` Without that type-check, I couldn't get it to work at all, even though I knew the result of the parser function in this case was an `int`. (You could see it in the debugger.) I'd prefer the line to go simply: ``` private float parseFloat(string expr) { ... return (float)parser(expr); } ``` (Type checking is done beforehand, and `parseFloat` should never be called with an expression that will not evaluate to a `float` or `int`.) Is there some reason why it's necessary to double-cast this variable? I obviously don't want to double-cast it in all cases, because if the return from `parser` was a `float`, it would truncate it to `int` first and we don't want that. (And yes, I tried replacing `float` and `int` with `Single` and `Int32`, etc. Didn't make any difference.) I saw this question, but it depends on knowing the type in advance, and the only solution it offers is this double-casting trick, which in my case would truncate `float`s unless I do a type-check first, which also requires an additional local variable to hold the result. Is there any way to avoid that extra step?

Original source

Related problems