VS.NET 2010对C#常数表达式的评估

VS.NET 2010对C#常数表达式的评估,c#,visual-studio,C#,Visual Studio,当我在Visual Studio中尝试C#中的示例表达式时 public int Test() { if (10/2 == 5) throw new Exception(); return 0; } 当我保持表达式10/2==5时,vs.net会自动抛出一个警告“检测到无法访问的代码” 如果我更改表达式10/2==6,IDE会高兴吗?这是怎么发生的 编辑:对不起,问题不完整。它会立即发生,甚至在编译代码之前就发生了 我对每个答复都投了赞成票,并在先进先出的基础上

当我在Visual Studio中尝试C#中的示例表达式时

public int Test()
{
    if (10/2 == 5)
        throw new Exception();
    return 0;
}
当我保持表达式10/2==5时,vs.net会自动抛出一个警告“检测到无法访问的代码”

如果我更改表达式10/2==6,IDE会高兴吗?这是怎么发生的

编辑:对不起,问题不完整。它会立即发生,甚至在编译代码之前就发生了

我对每个答复都投了赞成票,并在先进先出的基础上接受了第一个答复

if (10/2 == 5)
将始终返回true,这意味着

throw new Exception();
将始终执行,并且

return 0;

永远不会到达

在第一种情况下,编译器处理表达式
10/2==5
,该表达式的计算结果为true,因此引发异常,并且
返回0
语句不可到达

在第二种情况下,
10/2==6
的计算结果为false,因此可以访问
return0
语句,因为不会引发异常


为了响应您的编辑:您的代码不必实际编译,编译器才能知道代码行是不可访问的。知道
10/2==5
始终为真是明智之举,不管用户输入什么,这意味着异常将始终被抛出

有人抱怨说

return 0;

永远联系不到。10/2始终等于5。

如果反编译此代码,您将得到:

public int Test()
{
     throw new Exception();
}
我相信,因为这些都是常量值,所以数学运算是在编译时完成的,所以10/2实际上不是10/2,而是5…因此,编译器意识到5==5始终是真的就变得微不足道了。事实上,我相信这些常数会自动转化为真。编译器的目标是优化总是要在编译时重复并运行处理的代码,而不是反复运行相同的处理

因此,基本上,编译器认识到,由于if总是
true
,并且if会导致
返回
(通过
抛出
),因此它会优化它知道永远不会执行的代码。因此,反编译代码会产生上述结果

事实上,如果您执行
10/2==6
,则会发生相反的情况,它被“恒定化”为5==6,并被转换为false。由于if始终为false,因此它优化了if:

public int Test()
{
    int num = 0;
    return num;
}

编译器足够聪明(这是一个非常简单的检查),并确定永远不会到达返回0。这是因为10/2==5将始终为真。根据编译器,以下表达式的计算结果相等

if (10/2 == 5)


编译器之所以能够确定这一点,是因为数字不是可变的。

事实上,他知道他永远不会进来 返回0

他只是警告说,10/2==5以下的整个代码永远不会被解释为10/2始终是5

同样地:

if (true)
{
     ......
}
else 
{
  .....
}

正如其他人所说,编译器可以计算表达式
10/2==5
编译时,因为它是一个常量表达式。它的计算结果为
true
,因此
范围之后的任何代码都是不可读取的。如果更改为
false
,则无法访问
If
中的代码

所以现在考虑这个代码:

public int TestA() 
{ 
    if (10 / 2 == 5) 
        return 1; 
    return 0; 
} 

public int TestB() 
{ 
    if (10 / 2 == 6) 
        return 1; 
    return 0; 
} 
这两种方法都会生成关于无法访问代码的警告

C#编译器的奇怪之处在于,如果无法访问的代码完全由
throw
语句组成,则不会发出关于无法访问的警告


添加:

所以现在编译器是he;Pnobody回答了真正的问题:为什么编译器不抱怨在第二种情况下无法访问异常?@codesparkle我刚才在回答中提到了这一点。
public int TestA() 
{ 
    if (10 / 2 == 5) 
        return 1; 
    return 0; 
} 

public int TestB() 
{ 
    if (10 / 2 == 6) 
        return 1; 
    return 0; 
}