简体   繁体   English

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

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

Case 1 produces a type mismatch exception. 情况1产生类型不匹配异常。 Case 2 works as expected. 案例2按预期工作。 Does anyone have insight into why? 有谁有洞察原因? Or a better way to have converted from Int32 as an object into an Int16? 或者从Int32作为对象转换为Int16的更好方法?

Case 1: 情况1:

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

Case 2: 案例2:

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

The underlying cause is the fact that in C# the explicit cast operator has two different meanings: 根本原因是在C#中,显式强制转换运算符有两个不同的含义:

  • 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". 表示保留的含义是:“我知道这个对象总是T类型,即使编译器无法静态证明它 - 请让我用它作为T而不是更通用的东西”。
  • 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". 表示改变的含义是:“我知道这个对象不是 T类型,但有转换将其转换为T并且我希望执行转换”。

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". 你的第一个片段说:“我知道这个object 肯定是一个盒装的Int16 ,我想这样使用它”。 But since it's actually a boxed Int32 , you get a type mismatch exception. 但由于它实际上是一个盒装Int32 ,因此会出现类型不匹配异常。
  • Your second snippet says: "I know that this Int32 is definitely not an Int16 , but I'd like to convert it to one". 你的第二个片段说:“我知道这个Int32 肯定不是 Int16 ,但我想把它转换成一个”。

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. 根据Eric Lippert的说法 ,原因在于,以一种可以在一次操作中拆箱和转换的方式实现它实在是太不切实际了。

As Damian correctly commented, I was wrong. 正如Damian正确评论的那样,我错了。 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 . int > object > int没关系, int > object > short不是,所以是short > object > int

This will only work if the int was first converted to a short, like so: int > short > object > short is fine. 这只有在int首次转换为short时才有效,如下所示: int > short > object > short就可以了。

This particular case is even used in an unboxing sample on MSDN . 甚至在MSDN上拆箱样本中也使用了这种特殊情况。

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 . 在你的第一个情况下,你正试图unbox一个Int32为类型值Int16类型的字段,它给你的类型不匹配异常,因为没有可用的隐式转换,从投objectInt32

In your second case you are directly casting an Int32 to an Int16 . 在第二种情况下,您直接将Int32转换为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 ). 由于这是一个直接implicit type conversion您将获得implicit type conversion的好处( 有关更详细的说明,请参阅此MSDN文章 )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM