C#和VB.NET中的转换之间的区别

以下代码在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?

来自MSDN :

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

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

首先:我对此的理解是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#不检查溢出的事实有关。

得到的&H7FFFFFFF And &HFFFF导致UInt16.MaxValue(65535)UInt16从0到65535运行,你试图把它塞进Int16,从-32768到32767运行,你可以看到它不会起作用。 此值可能适合UInt16的事实是巧合,添加两个32位整数并尝试将它们塞入16位整数(短)将经常导致溢出,因此我会说这是一个固有的危险操作。

您是否尝试过使用DirectCast(b, Int16) ? CType与C#强制转换不同。

这篇文章比较了DirectCastCType的性能,并详细介绍了何时应该使用它们。

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(新类型)代替sizeof(类型)

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

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

 ?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 

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

  _ Public Structure int3216  Public i32 As Int32  Public i16high As Int16  Public i16low As Int16 End Structure 

  Dim _i3216 As int3216 _i3216.i32 = a And &HFFFF c = _i3216.i16low 

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

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

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

旧的,VB“正确”的技巧“侧面踩到hex”并再次返回仍然有效!

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

它看起来很漂亮!