Why is the casting operation not performed in case 1, but succeeds in case 2?

Case 1 throws a type mismatch exception. Case 2 works as expected. Does anyone know why? Or is the best way to convert from Int32 as an object to Int16?

Case 1:

var i = (Int16)(object)Int32.Parse("1"); 

Case 2:

 var i = (Int16)Int32.Parse("1"); 
+6
source share
3 answers

The main reason is that in C # the explicit casting operator has two different meanings:

  • A value that preserves the view: "I know that this object is always of type T, although the compiler could not prove it statically - please let me use it as T instead of something more general."
  • Value that changes the view: "I know that this object is not of type T, but there is a transformation to turn it into T, and I would like this conversion to be performed."

So, the reason you get two different behaviors is because you use each of the above values:

  • Your first snippet says, "I know that this object definitely an Int16 box, and I would like to use it as such." But since this is actually an Int32 box, you get a type mismatch exception.
  • Your second snippet says, "I know that this Int32 definitely not Int16 , but I would like to convert it to one."

In other words, unboxing only works if you are trying to unpack the original type. According to Eric Lippert , the reason is that it was simply too impractical to implement it in such a way that it could be unpacked and converted in one operation.

+11
source

As Damian commented correctly, I was wrong. The problem is not the conversion; the problem is the unboxing operation. It only allows you to unpack an object from the same type from which it was originally installed.

int > object > int is fine, int > object > short not and therefore short > object > int .

This will only work if the int was first converted to short, for example: int > short > object > short is fine.

This particular case is even used in the unpacking example on MSDN .

+3
source

In your first case, you are trying to enter an unbox a Int32 entered value into a field of type Int16 , which gives you a mismatch type exception, since there is no implicit conversion available for translating from object to Int32 .

In your second case, you randomly throw Int32 onto Int16 . Since this is a direct translation, you will benefit from the implicit type conversion ( see this MSDN article for a more detailed explanation ).

+2
source

All Articles