我不明白为什么下面的代码编译.
public void Overflow() { Int16 s = 32767; s = (Int16) (s + 1); }
在编译时,显然(s 1)不是Int16,因为我们知道s的价值.
而CLR允许投射到:
>到自己的类型
>或任何基础类型(因为它是安全的)
由于Int32不是Int16,Int16不是Int32的基本类型.
问题:为什么编译器不会失败上面的转换?你可以从CLR和编译器的角度来看看吗?
谢谢
解决方法
表达式s 1的类型是Int32 – 在执行加法之前,两个操作数都将转换为Int32.所以你的代码相当于:
public void Overflow() { Int16 s = 32767; s = (Int16) ((Int32) s + (Int32) 1); }
所以溢出只会在显式转换中发生.
或者换句话说:因为语言规范这样说.你应该描述一个:
>为什么你认为编译器违反了语言规范
>您提出的语言规范的确切变化
编辑:只是为了使事情真的很清楚(根据你的意见),编译器不会允许这样做:
s = s + 1;
当s是Int16时,无论s的值可能被认为是什么.没有Int16运算符(Int16,Int16)运算符 – 如C#4规范的7.8.4节所示,整数加法运算符是:
int operator +(int x,int y); uint operator +(uint x,uint y); long operator +(long x,long y); ulong operator +(ulong x,ulong y);