C#和VB.Net中相同程序的溢出行为的差异

Nik*_*wal 3 c# vb.net

我使用C#在.Net 3.5中运行了一个程序

try
{
    int i = 2147483647;

    Console.WriteLine((i * 100 / i).ToString());

    Console.ReadLine();
}
catch (Exception)
{                
    throw;
}
Run Code Online (Sandbox Code Playgroud)

当我在C#中运行该程序时,我没有得到异常(它输出"0").但是当我在VB.Net中运行这个程序时,它会导致"Arithmetic operation resulted in an overflow"异常

Try
    Dim i As Integer = 2147483647

    Console.WriteLine((i * 100 / i).ToString())

    Console.ReadLine()
Catch ex As Exception
    Throw
End Try
Run Code Online (Sandbox Code Playgroud)

为什么这两种语言之间的行为不同?

Mic*_*ray 5

或许看看IL会澄清......简化你的代码:

C#:

int i = 2147483647;
int v = (i * 100 / i);
Run Code Online (Sandbox Code Playgroud)

生成以下IL:

IL_0001:  ldc.i4      FF FF FF 7F 
IL_0006:  stloc.0     // i
IL_0007:  ldloc.0     // i
IL_0008:  ldc.i4.s    64 
IL_000A:  mul         
IL_000B:  ldloc.0     // i
IL_000C:  div         
IL_000D:  stloc.1     // v
Run Code Online (Sandbox Code Playgroud)

而VB版本:

Dim i As Integer = 2147483647
Dim v As Integer
v = i * 100 / i
Run Code Online (Sandbox Code Playgroud)

生成这个IL,略有不同:

IL_0001:  ldc.i4      FF FF FF 7F 
IL_0006:  stloc.0     // i
IL_0007:  ldloc.0     // i
IL_0008:  ldc.i4.s    64 
IL_000A:  mul.ovf     
IL_000B:  conv.r8     
IL_000C:  ldloc.0     // i
IL_000D:  conv.r8     
IL_000E:  div         
IL_000F:  call        System.Math.Round
IL_0014:  conv.ovf.i4 
IL_0015:  stloc.1     // v
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,VB正在调用mul.ovf,这是"乘法,并检查溢出",而C#正在调用mul,它不检查溢出.

也许它没有回答你的问题,为什么 C#以单向方式进行,而VB为另一方向进行,但至少它解决了为什么会发生这种情况.:)

编辑:请参阅aquinas的答案以获得"为什么".