Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中的强制转换与VB.NET之间的差异_C#_.net_Vb.net_Casting_Overflow - Fatal编程技术网

C#中的强制转换与VB.NET之间的差异

C#中的强制转换与VB.NET之间的差异,c#,.net,vb.net,casting,overflow,C#,.net,Vb.net,Casting,Overflow,以下代码在C#中运行良好 但此代码在中出现OverflowException时崩溃 这两个代码片段在我看来都是一样的。有什么区别?如何将C代码转换为VB.NET?您是否尝试过使用DirectCast(b,Int16)?CType与C#cast不同 这篇文章比较了DirectCast和CType的性能,并更详细地讨论了何时应该使用两者。首先:我的理解是,CType(b,Int16)与(Int16)b不同。一个是类型转换(CType),另一个是强制转换。(Int16)b等同于DirectCast(b

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

但此代码在中出现OverflowException时崩溃


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

您是否尝试过使用
DirectCast(b,Int16)
?CType与C#cast不同


这篇文章比较了
DirectCast
CType
的性能,并更详细地讨论了何时应该使用两者。

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

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

见:

但潜在的问题是,您试图将32位整数转换为16位整数,这是。。。[我找不到我需要的单词,也许有人可以帮我在这里插入]有损。允许从16位转换为32位,因为它是无损的,从32位转换为16位是未定义的。关于为什么它在C#中工作,你可以看到@Roman的答案——它与C#不检查溢出的事实有关

&H7FFFFFFF和&HFFFF
的结果值产生UInt16。最大值(65535)UInt16从0运行到65535,您试图将其填充到从-32768运行到32767的Int16中,正如您所看到的,这是行不通的。此外,这个值可能适合UInt16这一事实是巧合的,添加两个32位整数并尝试将它们填充到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
对于要抛出OverflowException的算术、强制转换或转换操作,该操作必须发生在选中的上下文中默认情况下,选中Visual Basic中的算术运算和溢出;在C#中,它们不是。如果操作发生在未检查的上下文中,则通过丢弃不适合目标类型的任何高阶位来截断结果

编辑:
如果您打算将代码从C#移植到VB.NET,您可能会感兴趣。还可以比较并显式设置为与C#中的默认设置相同(如果需要)。

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

<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

总结:

对于无符号类型:只需执行And运算符或2st方法

Dim a As Byte = CByte(300 And &HFF)
到有符号类型:左移n位,然后右移n位,即扩展有符号位。n=(sizeof(type1)-sizeof(type2))*8或VB:使用Len(新类型)代替sizeof(type)

Dim a As Short=CShort(34042>16)

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

我在寻找转换短路并获得溢出结果而不出现溢出错误的解决方案时遇到了这个问题。我在这里找到了一个解决方案:

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

古老的VB“正确”技巧,将“侧步”转换为十六进制和 再来一次仍然有效


它看起来很灵巧

如果运行C代码,则不会导致溢出。它只是将65535(Int32)转换为-1(Int16)MarkJ:这正是MSDN中所说的——在C中,算术运算不被检查,也不会发生溢出。在VB.NET中,默认情况下会选中它们,因此我们会得到异常。好的,当我看到我自己为VB.NET创建的某种“未选中”关键字时。我不是移植代码,我只是在寻找这个问题的解决方案,SoMoS:这个问题有一个很好的公认答案。我把它翻译成VB.NET,并作为新答案发布。它工作时没有溢出。看,这是当时可用的最佳答案,这个答案引导我提出了这个问题。
DirectCast(b,Int16)
导致编译错误
类型为“Integer”的值不能转换为“Short”。
关于为什么它在C中工作,并在VB中引发异常,请看下面我的答案。正如您所看到的,我屏蔽了Int32的上半部分,因此我始终有一个有效的Int16值。Int32和&H0000FFFF=Int16。
<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
Dim a As Byte = CByte(300 And &HFF)
Dim a As Short = CShort(34042 << 16 >> 16)
Dim unsigned as UInt16 = 40000
Dim signed as Int16 = CShort(Val("&H" & Hex(unsigned)))