我有两种测试方法。第一个工作正常。第二个不会抛出异常,但它应该。为什么第二个没有抛出异常?
[TestMethod]
[ExpectedException(typeof(OverflowException))]
public void LongToInt_OverflowWithCheckedBlock()
{
checked
{
int maxValue = 2147483647;
long longValue = (maxValue + 1);
int intValue = (int)longValue;
}
}
[TestMethod]
[ExpectedException(typeof(OverflowException))]
public void LongToInt_OverflowWithCheckedStatement()
{
int maxValue = 2147483647;
long longValue = (maxValue + 1);
int intValue = checked((int)longValue); // No Exception is thrown, why?
}
答案 0 :(得分:25)
第一个抛出的原因和第二个抛出的原因是因为你的比较有点偏差。
check
一切check
从long
转换为int
。 如果您将它们比较如下,它们是相同的,也不会抛出:
private static void MethodA()
{
int maxValue = 2147483647;
long longValue = ( maxValue + 1 );
checked
{
int intValue = ( int ) longValue;
}
}
private static void MethodB()
{
int maxValue = 2147483647;
long longValue = ( maxValue + 1 );
int intValue = checked( ( int ) longValue);
}
原因是因为这一行:int intValue = checked(( int ) longValue);
不是正在抛出的那一行,它的这一行:
long longValue = ( maxValue + 1 );
如果我把检查放在那里,他们都会抛出:
long longValue = checked( maxValue + 1 );
为什么会抛出:
它会抛出,因为( maxValue + 1 )
向int
maxValue
添加1(此处发生例外),之后 将其分配给{{1} },如果您在添加1之前long
cast
到int
,则不会抛出:
long
答案 1 :(得分:8)
正如MSDN document所说,
已检查 关键字用于显式启用溢出检查 积分型算术运算和转换。
第一个测试方法已经在检查 声明的块 中是否存在溢出值。
第二种测试方法只检查溢出值 这行代码。
int intValue = checked((int)longValue); //Checked expression
由于溢出发生在checked
表达式之前,因此CLR已经转换了该值。
而且值为-2147483648
which is legal,因为int范围是
有什么区别?
测试方法1:已检查块
测试方法2:检查表达
答案 2 :(得分:2)
因为您将其转换为long
。未经检查的(maxValue + 1)
会导致-2147483648
中存储long
{{}}},然后转回int
。因此,在最终投放intValue
商店-2147483648
相反,请尝试以下操作,这将导致OverflowException
int intValue = checked(maxValue + 1);
(或)甚至
long longValue = checked((maxValue + 1));