C#内联检查语句不起作用

The*_*eIT 16 c# casting exception-handling

我有两种测试方法.第一个工作正常.第二个不会抛出异常,但它应该.为什么第二个不抛出异常?

[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?
}
Run Code Online (Sandbox Code Playgroud)

Epi*_*Kip 25

第一个抛出的原因和第二个抛出的原因是因为你的比较有点偏差.

  • 在第一种方法你check一切
  • 在第二种方法中,你只能check从中投射longint.

如果你比较下面他们是相同的,他们都不会抛出:

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);
}
Run Code Online (Sandbox Code Playgroud)

原因是因为这一行:int intValue = checked(( int ) longValue);不是正在抛出的那一行,它的这一行:

long longValue = ( maxValue + 1 );
Run Code Online (Sandbox Code Playgroud)

如果我把检查放在那里,他们都会抛出:

long longValue = checked( maxValue + 1 );
Run Code Online (Sandbox Code Playgroud)

为什么它会抛出:

它抛出,因为( maxValue + 1 )是增加1到int所谓的maxValue(在这里发生的例外),并在此之后将其分配给一个long,如果你castint一个long做加1的时候,才不会抛出:

long longValue = ( (long) maxValue + 1 );
Run Code Online (Sandbox Code Playgroud)


Jer*_*ruz 8

正如MSDN文件所说,

检查关键字用来明确启用溢出检查整型算术运算和转换.

第一个测试方法已经在检查声明的块中是否存在溢出值.

在此输入图像描述

第二种测试方法仅检查此行代码的溢出值.

int intValue = checked((int)longValue); //Checked expression

在此输入图像描述

由于溢出发生在checked表达式之前,因此CLR已经转换了该值.而且这个值-2147483648 是合法的,因为int范围是 在此输入图像描述

有什么不同?

测试方法1:检查块

测试方法2:检查表达式