VB.NET 代码返回的结果与 C# 代码不同

本文关键字:代码 NET 返回 VB 结果 | 更新日期: 2023-09-27 18:31:49

以下

代码在 C# 中给出结果 "228452386"

UInt32 a;
int k = 0;
a = 0x9E3779B9;
a += (UInt32)(url[k + 0] + (url[k + 1] << 8) + (url[k + 2] << 16) + (url[k + 3] << 24));

运行上述代码后,"a"包含"228452386"。

但是 VB.NET 中的以下相同代码会导致"算术运算导致溢出"。基本上最后一条语句返回值"1868983913",因此生成运行时错误。

Dim a As UInt32
Dim k As Integer = 0
a = &H9E3779B9UI
a += CUInt(AscW(url(k + 0)) + (AscW(url(k + 1)) << 8) + (AscW(url(k + 2)) << 16) + (AscW(url(k + 3)) << 24))

请注意,上述代码中的变量"url"可以是任何字符串,并且对于两个代码都是相同的。

当我在 C# 和 VB.NET 中运行以下语句时,它们都返回相同的值

C#

(UInt32)(url[k + 0] + (url[k + 1] << 8) + (url[k + 2] << 16) + (url[k + 3] << 24))

VB.NET

CUInt(AscW(url(k + 0)) + (AscW(url(k + 1)) << 8) + (AscW(url(k + 2)) << 16) + (AscW(url(k + 3)) << 24))

这两个语句都返回"url"info:microsoft.com"的值"1868983913"。但是当我使用 += ......... 然后 VB.NET 给出错误,而 C# 返回值"228452386"。

VB.NET 代码返回的结果与 C# 代码不同

您有一个溢出,因为添加的两个数字相加的结果大于 UInt 中适合的结果。

结果数字是 33 位数字,UInts 仅适合 32 位。

  • 在 C# 中,最高有效位只是被切掉,保留适合 UInt 的 32 位。(此新值不是将数字相加的实际结果。
  • 在 VB.NET 中,您会收到一个异常,指出该数字不适合。

VB.NET 编译器(或 VS)允许您打开此溢出检查,以便在这种情况下 VB.NET 的行为类似于 C#。

VB.NET 会自动插入溢出测试,而 C# 不会。等效的 C# 代码为:

UInt32 a;
int k = 0;
a = 0x9E3779B9;
checked{
    a += (UInt32)(url[k + 0] + (url[k + 1] << 8) + (url[k + 2] << 16) + (url[k + 3] << 24));
}
编辑

:更改了代码示例以符合编辑的问题。

使用以下

VB.NET 代码:

    a += CUInt(AscW(url(k + 0))) + CUInt((AscW(url(k + 1)) << 8)) + CUInt((AscW(url(k + 2)) << 16)) + CUInt((AscW(url(k + 3)) << 24))

AscW返回一个整数(有符号),您需要的是无符号的。

编辑

这有效:

    Dim a As Int64
    Dim result As UInt32
    Dim k As Integer = 0
    Dim url As String = "info:microsoft.com"
    a = &H9E3779B9UI
    Dim a1 As UInt32 = 0
    Dim a2 As UInt32 = 0
    Dim a3 As UInt32 = 0
    Dim a4 As UInt32 = 0
    a1 = AscW(url(k + 0))
    a2 = AscW(url(k + 1)) << 8
    a3 = AscW(url(k + 2)) << 16
    a4 = AscW(url(k + 3)) << 24
    a = (a + a1 + a2 + a3 + a4) And &HFFFFFFF
    result = Convert.ToUInt32(a)