Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the cast operation fail in case 1 but succeed in case 2?

Tags:

c#

Case 1 produces a type mismatch exception. Case 2 works as expected. Does anyone have insight into why? Or a better way to have converted from Int32 as an object into an Int16?

Case 1:

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

Case 2:

var i = (Int16)Int32.Parse("1");
like image 925
Greg Bogumil Avatar asked May 19 '16 14:05

Greg Bogumil


3 Answers

The underlying cause is the fact that in C# the explicit cast operator has two different meanings:

  • The representation-preserving meaning is: "I know this object is always of type T, even though the compiler couldn't prove it statically - please let me use it as T instead of something more general".
  • The representation-changing meaning is: "I know this object isn't of type T, but there is a conversion to turn it into T and I'd like that conversion to be performed".

So the reason you're getting two different behaviors is that you are using each of the above different meanings respectively:

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

In other words, unboxing works only if you attempt to unbox to the original type. According to Eric Lippert, the reason is that it was simply too impractical to implement it in a way that it could unbox and convert in a single operation.

like image 54
Theodoros Chatzigiannakis Avatar answered Nov 15 '22 07:11

Theodoros Chatzigiannakis


As Damian correctly commented, I was wrong. The problem wasn't the conversion, the problem lies in the unboxing operation. It only allows unboxing from an object from the same type it was originally boxed from.

int > object > int is okay, int > object > short isn't and so is short > object > int.

This will only work if the int was first converted to a short, like so:int > short > object > short is fine.

This particular case is even used in an unboxing sample on MSDN.

like image 32
Patrick Hofman Avatar answered Nov 15 '22 06:11

Patrick Hofman


In your first case your are trying to unbox an Int32 typed value into a Int16 typed field, which gives you the type-mismatch exception since there is no implicit conversion available to cast from object to Int32.

In your second case you are directly casting an Int32 to an Int16. Since this is a direct cast here you'll get the benefit of implicit type conversion (see this MSDN article for a more detailed explanation).

like image 31
bassfader Avatar answered Nov 15 '22 05:11

bassfader