今天我遇到了这种奇怪的行为,有人可以解释为什么会这样吗?
var x = -1U; // When using -1UL it complains though.
Console.WriteLine(x.GetType().Name);
Console.WriteLine(x);
输出:
Int64
-1
MSDN说:
如果文字后缀为U或u,则它具有第一种类型,其值可以表示为:uint,ulong。
https://msdn.microsoft.com/en-us/library/aa664674%28v=vs.71%29.aspx
答案 0 :(得分:2)
您在这里所做的是使用unary operator -
和https://msdn.microsoft.com/en-us/library/aa691145(v=vs.71).aspx
对于一元运算符,操作数转换为类型T,其中T是int和long中的第一个,可以完全表示操作数的所有可能值。然后使用类型T的精度执行操作,结果的类型为T.一元 - 运算符不能应用于ulong类型的操作数。
如果我做的话
var x =-1UL;
我收到编译错误Operator '-' cannot be applied to operand of type 'ulong
因为我正在使用一元运算符
而如果我这样做
var x =2UL-1UL;
编译器没有抱怨,因为我现在正在使用binary operator
当你执行var x=-1UL
时,编译器会将其解释为var x=0UL-1UL
,如果说成功将生成-1UL
,但是如果你看一下UL的范围0 and 18446744073709551615
所以-1UL
超出了它的范围,因此编译时错误。同样可以为ushort
完成。
答案 1 :(得分:1)
您的困惑源于您将其解释为数字-1
,后跟后缀U
。它实际上是数字-
的否定1U
。该号码1U
的类型为uint
,如您问题中的引用所示。否定uint
会产生long
。
答案 2 :(得分:0)
在这行代码中,您要求编译器使用隐式类型var
选择类型,然后使用此-
符号为其指定负值:
var x = -1U; // it is converted to simple -1
所以它被编译器转换为-1
,它找到最接近的类型,其范围对应于uint
s范围,并且可以使用负值 - long
Console.WriteLine(x.GetType().Name); // displays long (Int64)
Console.WriteLine(x); // displays -1
如前所述,您可以使用unchecked
关键字让编译知道它不应该执行溢出检查。来自MSDN的引用:
unchecked关键字用于抑制溢出检查 积分型算术运算和转换。
所以这应该编译并运行,x将是ulong
类型:
// UInt64 here
var x = unchecked((ulong)-1);