为什么在案例1中转换操作失败但在案例2中成功?

时间:2016-05-19 14:03:46

标签: c#

案例1产生类型不匹配异常。案例2按预期工作。有谁有洞察原因?或者更好的方法是将Int32作为对象转换为Int16?

案例1:

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

案例2:

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

3 个答案:

答案 0 :(得分:11)

根本原因在于,在C#中,显式强制转换运算符有两种不同的含义:

  • 表示保留意思是:“我知道这个对象总是T型,即使编译器无法静态证明 - 请让我用它作为T而不是更多一般”。
  • 表示更改的含义是:“我知道这个对象不是类型的T,但是有一个转换将它变成T而我是就像要进行转换一样“。

因此,您获得两种不同行为的原因是您分别使用上述各种含义:

  • 您的第一个片段说:“我知道这个SELECT 肯定是一个盒装的object,我想这样使用它”。但由于它实际上是一个盒装的Int16,因此会出现类型不匹配的异常。
  • 您的第二个片段说:“我知道此Int32 绝对不是 Int32,但我想将其转换为一个”。

换句话说,只有在您尝试取消装箱到原始类型时,取消装箱才有效。 According to Eric Lippert,原因是以一种可以在一次操作中拆箱和转换的方式实现它实在太不切实际。

答案 1 :(得分:3)

正如Damian正确评论的那样,我错了。问题不在于转换,问题在于拆箱操作。 它只允许从最初装箱的相同类型的对象中取消装箱。

var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error:&responseError) if ( urlData != nil) { let res = response as! NSHTTPURLResponse!; NSLog("Response code: %ld", res.statusCode); if (res.statusCode >= 200 && res.statusCode < 300) { var responseData:NSString = NSString(data: urlData!, encoding: NSUTF8StringEncoding)! NSLog("Response ==> %@", responseData); 没问题,int > object > int不是int > object > short

只有在short > object > int首次转换为短片时才会有效:int没问题。

这种特殊情况甚至用于unboxing sample on MSDN

答案 2 :(得分:2)

在第一种情况下,您尝试将unbox Int32类型的值输入Int16类型字段,这会为您提供类型不匹配异常,因为没有可用的隐式转换从object投射到Int32

在第二种情况下,您直接将Int32投射到Int16。由于这是一个直接投射,因此您将获得implicit type conversionsee this MSDN article for a more detailed explanation)的好处。