来自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
必须是一个盒装长的,那么为什么编译不会失败呢?
感谢。