8

以下代码在 C# 中运行良好。

    Int32 a, b;
    Int16 c;

    a = 0x7FFFFFFF;
    b = a & 0xFFFF;
    c = (Int16)b;

但是这段代码在VB.NET中出现 OverflowException 崩溃。

    Dim a, b As Int32
    Dim c As Int16

    a = &H7FFFFFFF
    b = a And &HFFFF
    c = CType(b, Int16)

这两个代码片段在我看来都是一样的。有什么区别?如何将 C# 代码转换为 VB.NET?

4

7 回答 7

11

来自 MSDN

对于引发 OverflowException 的算术、强制转换或转换操作,该操作必须发生在检查的上下文中。默认情况下,检查 Visual Basic 中的算术运算和溢出;在 C# 中,它们不是。如果操作发生在未经检查的上下文中,则通过丢弃任何不适合目标类型的高位位来截断结果。

编辑:如果您要将代码从 C# 移植到 VB.NET,您可能会对它们之间的差异感兴趣。还要比较并明确将编译器设置设置为与 C# 中的默认设置相同(需要时)。

于 2009-12-09T14:19:14.483 回答
8

首先:我对此的理解是 CType(b, Int16) 与 (Int16)b 不同。一种是类型转换(CType),另一种是强制转换。(Int16)b 等同于 DirectCast(b, Int16) 而不是 CType(b, Int16)。

两者之间的区别(如 MSDN 上所述)是只要有有效的转换,CType 就会成功,但是,DirectCast 要求对象的运行时类型相同,因此,您所做的一切在设计时告诉编译器该对象属于该类型,而不是告诉它转换为该类型。

请参阅:http: //msdn.microsoft.com/en-us/library/7k6y2h6x (VS.71).aspx

不过,潜在的问题是您正在尝试将 32 位整数转换为 16 位整数,这是... [我缺少我需要的单词,也许有人可以在这里为我插入] 有损。允许从 16 位转换为 32 位,因为它是无损的,从 32 位转换为 16 位是未定义的。对于它在 C# 中工作的原因,您可以看到@Roman 的答案 - 它与 C# 不检查溢出的事实有关。

UInt16.MaxValue (65535) UInt16中结果的结果值&H7FFFFFFF And &HFFFF从 0 运行到 65535,您试图将其填充到从 -32768 到 32767 的 Int16 中,如您所见,这是行不通的。此外,这个值可能适合 UInt16 的事实是巧合,添加两个 32 位整数并试图将它们塞进一个 16 位整数(短)经常会导致溢出,因此我会说这是一个固有的危险操作。

于 2009-12-09T14:09:21.710 回答
2

你试过使用DirectCast(b, Int16)吗?CType 与 C# 强制转换不同。

是一篇比较 和 的性能的文章,DirectCastCType更详细地说明了何时应该使用两者。

于 2009-12-09T14:08:33.693 回答
1

http://www.cnblogs.com/liujq007/archive/2010/12/04/1896059.html

概括:

对于无符号类型:只需执行 And 运算符,或第二种方法。

Dim a As Byte = CByte(300 And &HFF)

对有符号类型:左移n位,再右移n位,即扩展有符号位。n = (sizeof(type1) - sizeof(type2)) * 8 或 VB:使用 Len(New type) 而不是 sizeof(type)

Dim a As Short = CShort(34042 << 16 >> 16)

您可以从下面的链接中找到详细信息。

于 2010-12-06T07:59:43.437 回答
0
?CType(b, Int16)
Constant expression not representable in type 'Short'.

?b
65535

?directcast(b, Int16)
Value of type 'Integer' cannot be converted to 'Short'.

?int16.TryParse(b.ToString(), c)
False
于 2009-12-09T14:17:56.467 回答
0

您可以使用结构截断这种溢出。

<StructLayout(LayoutKind.Explicit)> _
Public Structure int3216
    <FieldOffset(0)> Public i32 As Int32
    <FieldOffset(0)> Public i16high As Int16
    <FieldOffset(2)> Public i16low As Int16
End Structure

...

  Dim _i3216 As int3216
  _i3216.i32 = a And &HFFFF
  c = _i3216.i16low
于 2010-03-03T04:17:12.997 回答
0

在寻找转换 Short 并在没有溢出错误的情况下获得溢出结果的解决方案时,我遇到了这个问题。我在这里找到了解决方案:

http://bytes.com/topic/visual-basic-net/answers/732622-problems-typecasting-vb-net

大约在页面的一半是这样的:

旧的,VB“正确”的“侧步”到十六进制并再次返回的技巧仍然有效!

Dim unsigned as UInt16 = 40000
Dim signed as Int16 = CShort(Val("&H" & Hex(unsigned)))

它似乎工作得很顺利!

于 2015-09-23T15:36:34.547 回答