I have the following code:
int intNumber1 = 100; object intNumber2 = 100; bool areNumberOfTheSameType = intNumber1.GetType() == intNumber2.GetType(); // TRUE bool areEqual = intNumber1.Equals(intNumber2); // TRUE long longNumber1 = (long) intNumber1; // OK long longNumber2 = (long) intNumber2; // InvalidCastException. Why?
Why doesn't the second cast work? I realize that it might be because the object doesn’t have an explicit cast to a long, but if we look at its type on runtime it is System.Int32
.
If I use var
or dynamic
instead of object
, it works.
Any thoughts?
fromInteger :: Num a => Integer -> a. as well as for converting to Integer s: toInteger:: Integral a => a -> Integer.
Casting does not create a new object (at least, not unless new conversion operators have been defined, which is uncommon in non-numeric types, and doesn't apply in your example). It merely instructs the compiler how to "treat" an object.
And since Haskell is not object-oriented, there is no inheritance relationship that required any cast. There simply aren't meaningless object values that needed runtime-checking/casting. For expressing alternatives, you'll have to define a union type, a typeclass or use the Either type.
Cast from int
to long
is interpreted as conversion between the two types.
Cast from object
to int
is interpreted as unboxing a boxed int
.
It is the same syntax, but it says two different things.
In the working cases (int
→long
, object
(boxed int
)→int
), the compiler knows exactly what code to produce. If boxed int
→long
was to work, the compiler would have to somehow figure out which conversion to use, but it doesn't have enough information to do it.
See also this blog post from Eric Lippert.
The object
holds a type int
. But it's considered an object (which is a boxed int) and a boxed value type can generally only be cast to its underlying type (the type that is boxed).
To cast it to another type, you first have to cast it to its underlying type. This works:
long longNumber2 = (long) (int) intNumber2;
The reason that var
works is that the compiler infers the type at compile time. That means, when you use var
, the type of intNumber2
(if you use typeof
) will be int
. Whereas when you use object
, the type will be object
.
Using dynamic
is a whole different process and cannot be compared with var
. Here, the conversion / casting takes place at runtime, using reflection and the DLR library. It will dynamically find the underlying type, find that it has a conversion operator and uses that.
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