Question

First, two examples:

// This works
int foo = 43;
long lFoo = foo;

// This doesn't
object foo = (int)43;
long? nullFoo = foo as long?; // returns null
long lFoo = (long)foo; // throws InvalidCastException
if (foo.GetType() == typeof(int))
    Console.WriteLine("But foo is an int..."); // This gets written out

Now, my guess as to why the second doesn't work is because of boxing. The purpose behind this code is to implement IComparable. I need some way to coerce an object into either a long or a ulong as appropriate, or if it's neither, than to throw an error. I don't want to have to implement checks for each basic numeric type (byte, int, long, ubyte, ...) I'd rather just catch them in the largest numeric type and deal with it that way. Thoughts from all the smart people here? How can I unbox the object, preferably avoiding reflection, but I suppose if that's the only way... Or should I just not implement the non-generics version of IComparable?

Edit:

This seems to work, but seems like a horrible hack around the problem. Is it just me?

long lFoo = long.Parse(foo.ToString());
Was it helpful?

Solution

object foo  = (int) 43;
long   lFoo = ((IConvertible) foo).ToInt64(null);

OTHER TIPS

When you're casting to a value type you're really forcing an unbox IL operation, which requires that the type you're casting to matches exactly the boxed value; there are no conversions, implicit, or explicit that can happen at the same time.

This usually means that you either need to do a switch using the typecode (or an if/else if using types), or, in your case, go with a check for null followed by Convert.ToInt64(), which should deal with it correctly.

Its not just you, however tryparse does not raise an exception.

object foo = (int)43;
long outVal;
if(long.TryParse(foo.ToString(),out outVal))
{
//take action with correct value of long
}
else
{
//maybe passed you another type of object
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top