默认情况下,C# 在处理数字时不检查溢出。这包括诸如从int.MaxValue
加到int.MinValue
乘法的换行,以及当你将long
s 转换为int
s 时。要控制这一点,请使用checked
andunchecked
关键字或/checked
编译器选项。
该值1942903641
是您long
被截断为int
. 它来自long
值的 32 个最低有效位,作为二进制补码有符号整数。
使用 时foreach
,重要的是要知道,如果您声明的类型与可枚举的类型不匹配,它会将其视为您已转换为该类型。foreach (int i in myCollection)
编译成类似的东西int i = (int)myEnumerator.Current;
,不是int i = myEnumerator.Current;
。您可以使用它foreach (var i in myCollection)
来避免将来出现此类错误。var
建议在for
andforeach
语句中使用 for 循环变量。
您可以在以下示例中看到各种事情的结果(十六进制输出用于更清楚地显示截断:它们具有相同的结束数字,int
只是缺少一些更有效的数字):
checked
{
Int64 a = 12345678912345;
Console.WriteLine(a.ToString("X"));
Console.WriteLine((a % ((long)uint.MaxValue + 1L)).ToString("X"));
try
{
Console.WriteLine(((int)a).ToString("X")); // throws exception
}
catch (Exception e)
{
Console.WriteLine("It threw! " + e.Message);
}
}
unchecked
{
Int64 a = 12345678912345;
Console.WriteLine(a.ToString("X"));
Console.WriteLine((a % (long)Math.Pow(2, 32)).ToString("X"));
Console.WriteLine(((int)a).ToString("X"));
}
这输出:
B3A73CE5B59
73CE5B59
It threw! Arithmetic operation resulted in an overflow.
B3A73CE5B59
73CE5B59
73CE5B59