我知道这很旧,但我最近需要转换一些未经检查的 C# 代码,我想我会分享我是如何做到的。它是纯 VB 代码,可以根据需要调整范围(而不是项目范围的选项)。
诀窍是创建一个包含一个 Long 字段和两个 Integer 字段的结构。然后使用 StructLayout 和 FieldOffset 属性来创建 long 和两个整数的并集。这些字段可以(应该)是私有的。使用扩展 CType 运算符从 Long 转换为结构,从结构转换为 Integer(使用低整数值)。为 +、-、* 等添加运算符重载……然后!VB中未经检查的算术!
有点......它仍然会溢出,正如 Strilanc 指出的那样,如果 long 值超出 long 的范围。但它适用于许多使用 unchecked 的情况。
这是一个例子:
<StructLayout(LayoutKind.Explicit)>
Public Structure UncheckedInteger
<FieldOffset(0)>
Private longValue As Long
<FieldOffset(0)>
Private intValueLo As Integer
<FieldOffset(4)>
Private intValueHi As Integer
Private Sub New(newLongValue As Long)
longValue = newLongValue
End Sub
Public Overloads Shared Widening Operator CType(value As Long) As UncheckedInteger
Return New UncheckedInteger(value)
End Operator
Public Overloads Shared Widening Operator CType(value As UncheckedInteger) As Long
Return value.longValue
End Operator
Public Overloads Shared Widening Operator CType(value As UncheckedInteger) As Integer
Return value.intValueLo
End Operator
Public Overloads Shared Operator *(x As UncheckedInteger, y As Integer) As UncheckedInteger
Return New UncheckedInteger(x.longValue * y)
End Operator
Public Overloads Shared Operator Xor(x As UncheckedInteger, y As Integer) As UncheckedInteger
Return New UncheckedInteger(x.longValue Xor y)
End Operator
' Any other operator overload you need...
End Structure
在代码中使用如下结构:
Dim x As UncheckedInteger = 2147483647
Dim result As Integer = x * 2 ' This would throw OverflowException using just Integers
Console.WriteLine(result.ToString()) ' -2
在将结果分配给 UncheckedInteger 之前,请注意您的计算不会溢出。您可以使用相同的技术创建 UncheckedShort 和 UncheckedByte 结构。