在VB.NET中将布尔值转换为字节

6
为什么在.NET中将一个布尔值转换为字节会得到以下输出?
代码片段:
Dim x As Boolean = 1
Dim y As Byte = x    'Implicit conversion here from Boolean to Byte

System.Diagnostics.Debug.Print( _
    "x = " & x.ToString _
    & " y = " & y.ToString _
    & " (bool)(1) = " & CType(1, Boolean).ToString _
    & " (byte)((bool)1) = " & CType((CType(1, Boolean)), Byte).ToString)

输出:

x = 真
y = 255
(bool)(1) = 真
(byte)((bool)1) = 255

当将True(通常被称为1的整数表示)转换为byte时,为什么会变成255?


我觉得很奇怪的是VB.NET甚至允许你将布尔值转换为字节。在C#中,这是一种非法的转换。 - vcsjones
我认为这只是编译器的行为。它发出了IL ldc.i4 FF 00 00 00,尽管我看不到规范中说明原因的任何内容。对于非常简单的情况,编译器只是优化掉了转换。 - vcsjones
你怎么让它发出IL代码?我无法在使用VS2010中的ASP.NET时弄清楚如何做到这一点 =/ - afuzzyllama
1
@vcsjones - 我认为在VB.NET中使用Option Implicit将允许这样的操作。我不是很确定,因为我很少在VB.NET上工作。 - Tim
使用 Option Strict On 来禁用隐式转换。优先使用 DirectCast 而不是 TryCast,因为 DirectCast 只会进行强制转换,而不会进行类型转换。 - MarkJ
显示剩余2条评论
4个回答

13
VB.NET编译器将它处理为缩小转换。引用自VB.NET 10.0规范书中的如下定义:

缩小转换是无法证明始终成功的转换,可能丢失信息的转换,以及跨足够不同类型领域的转换使用缩小符号。以下转换被分类为缩小转换:

  • 从布尔型到Byte、SByte、UShort、Short、UInteger、Integer、ULong、Long、Decimal、Single或Double的转换。
引用自文档的如下内容:

当Visual Basic将数值数据类型值转换为布尔型时,0变为False,所有其他值变为True。当Visual Basic将布尔值转换为数字类型时,False变为0,而True变为-1。

Byte没有符号位,所以您会从二进制补码中得到255。

现在这就说得通了。在我看来,-1 是一个奇怪的选择,但完美地解释了为什么在使用 EF 的旧版数据库中会得到奇怪的 255 值。 - DavidScherer

5

.NET中的布尔值True以-1的形式存储,这是由于二进制补码而导致的11111111。

因此,Dim x As Boolean = 1将1转换为布尔值True。

Dim y As Byte = x将True转换为11111111,等于255。

(如果您写的是Dim z As Integer = x,则z将等于-1)


3
我看到的所有使用整数位运算布尔运算符的Basic版本均使用“全部位设置”即-1作为真比较的值。因此,如果想要在a==b时有一个值为9,否则为零的值,可以使用表达式9 AND (a=b)。虽然C中存在的?:操作符允许更清晰地编写此类行为,但在没有离散布尔类型的语言中,使用-1表示“true”的实际优势大于缺点。
虽然vb.net是一种独立于vb6的语言,但是有很多代码已经从vb6移植到vb.net,并且可能依赖于比较运算符在为真时产生全部位设置的结果。

1
如果您想将true转换为1,并将false转换为0,请使用以下代码:
Convert.ToByte(Boolean) 

链接到文档 Convert.ToByte(boolean)

否则,您会得到实际值-10xFF


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接