为什么可以编译类型参数的转换“(long)(object)”?

时间:2017-09-22 02:00:09

标签: c#

来自C#5.0语言规范:

  

以上规则不允许直接显式转换   非约束类型参数到非接口类型,可能是   奇怪。这个规则的原因是为了防止混淆和制造   这种转换的语义清晰。例如,考虑一下   以下声明:

class X<T> 
{ 
  public static long F(T t) { 
    return (long)t;        // Error  
  } 
} 
     

如果允许t直接显式转换为int,则为一个   可能很容易期望X<int>.F(7)会返回7L。但是,它   不会,因为标准数字转换只是   在绑定时知道类型是数字的时候考虑。

     

为了使语义清晰,上面的例子必须改为   写得:

class X<T> 
{ 
  public static long F(T t) { 
    return (long)(object)t;   // Ok, but will only work when T is long 
  } 
} 
     

此代码现在将编译,但随后会执行X<int>.F(7)   在运行时抛出异常,因为无法转换boxed int   直接到了很久。

为什么添加(object)会使编译工作?

在第一个示例中,如果我是正确的,(long)中的(long)t表示标准数字转换没有歧义,这要求t的实际类型为数字类型,可以被(long)转换为长。由于无法保证t的实际类型,编译失败。

在第二个例子中,

  • (long)中的(long)(object)t是否意味着取消装箱转换而不会与其他类型的转化产生歧义?

  • (long)中的(long)(object)t是否要求(object)t长盒装?但是不能保证(object)t必须是一个盒装长的,那么为什么编译不会失败呢?

感谢。

0 个答案:

没有答案