我有两个代码块,目的是推断编译器分配给var
关键字的类型。
var b = 0x80000000 - 0x1;
Console.WriteLine("b: {0}", b);
Console.WriteLine("b.GetType()={0}", b.GetType());
uint val1 = 0x80000000;
int val2 = 0x1;
var c = val1 - val2;
Console.WriteLine("c: {0}", c);
Console.WriteLine("c.GetType(): {0}", c.GetType());
输出:
b: 2147483647 //Result of UInt32-Int32
//(as compiler assigns datatype in the
//order of int, uint, long and ulong)
b.GetType()=System.UInt32 //OK
c: 2147483647 //Uint32-Int32
c.GetType(): System.Int64 //Not Understood, why not UInt32 ?
如果var b
和var c
具有几乎相同的初始化 - var c
甚至是显式的,那么为什么它会提供意外的数据类型System.Int64?
答案 0 :(得分:3)
因为
var b = 0x80000000 - 0x1;
已经计算好了。通过优化
但是
var val1 = 0x80000000;
var val2 = 0x1;
var c = val1 - val2;
尚未计算。并且编译器猜测以后可能会更改val1
和val2
...
const uint val1 = 0x80000000;
const int val2 = 0x1;
var c = val1 - val2;
c
现在是UInt32
因为编译器会对其进行计算并知道转发。
因为val1
和val2
是常量,编译器知道它们不会被更改。所以不再需要Int64
答案 1 :(得分:1)
问题在于,当您在int
和uint
之间进行操作时,uint
正在转换为带符号的数字。
因此,为了使uint
能够以无符号数存储其所有信息(从0到2 3 - 1),它必须被转换为{{1} (从-2 63 到2 63 - 1),因为long
的范围是从-2 31 到2 31 - 1。
答案 2 :(得分:-1)
编译器自动将类型扩展为64位,因为这是唯一可以保存UInt32
和Int32
之间操作结果的整数。尝试更改为
ulong val1 = 0x80000000;
long val2 = 0x1;
并且您将看到编译错误,因为编译器无法找到保存结果的类型。
Int64
不是b
的推断类型,因为编译器检测到常量落入Int32
范围。尝试
var b = 0x800000000000 - 0x1;
您将看到推断类型long