2012-02-09 22 views
6

¿Por qué un boolean de fundición a byte en .NET da el siguiente resultado?Convirtiendo Boolean a Byte en VB.NET

Código snippit:

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) 

de salida:

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

¿Por qué True (w Lo que comúnmente se conoce como una representación entera de 1) se convierte a 255 cuando se convierte en byte?

+0

Me resulta curioso que VB.NET incluso te permita convertir un booleano en un byte. En C# eso es un elenco ilegal. – vcsjones

+0

Si haces un 'DirectCast()' en VB.NET automáticamente te dirá que es un lanzamiento ilegal, pero si usas 'CType()' (que he mostrado), hará lo que se indica arriba. Me interesa saber cómo 'True', que se conoce comúnmente como' 1', se traduce en '255' debajo del capó. Un montón de casting raro pasando aquí. – afuzzyllama

+0

Creo que este es solo el comportamiento del compilador. Emite el IL 'ldc.i4 FF 00 00 00', aunque no puedo ver nada en la especificación que diga por qué. Para casos muy simples, el compilador solo está optimizando el lanzamiento. – vcsjones

Respuesta

11

El compilador de VB.NET maneja como un conve estrechamiento rsion. Del 10,0 VB.NET Spec:

conversiones de restricción son conversiones que no se puede probar para tener éxito siempre, las conversiones que se sabe que perder, posiblemente, la información y las conversiones a través de dominios de tipos suficientemente diferentes para reducir la notación de mérito. Los siguientes conversiones se clasifican como conversiones de restricción:

  • De booleana para Byte, SByte, ushort, corto, UInteger, Entero, ULONG, Largo, decimal, individual o doble.

De the docs:

Cuando Visual Basic convierte los valores de tipos de datos numéricos a Boole, 0 se convierte en falso y todos los demás valores se convierten en verdaderos. Cuando Visual Basic convierte valores booleanos en tipos numéricos, False se convierte en 0 y True se convierte en -1.

Los bytes no están firmados, por lo que obtienes 255 en lugar de Two's Compliment.

4

Un valor booleano de True en .NET se almacena como -1, que a su vez es 11111111 debido a Two's Complement

Así Dim x As Boolean = 1 convierte 1 a booleano verdadero

y Dim y As Byte = x convierte Fiel a 11111111, que es igual 255

(Si por el contrario usted escribió Dim z As Integer = x, z habría = -1)

3

Todas las versiones históricas de Basic que he visto que han soportado operadores booleanos bit a bit con enteros han usado "all-bits-set", es decir, -1, como el valor para comparaciones verdaderas. Por lo tanto, si uno quisiera tener un valor que fuera 9 si a == b, o cero si no, uno podría usar la expresión 9 AND (a=b). Mientras que el operador ?: presente en C permite que dicho comportamiento se codifique con mayor claridad, el uso de -1 para "verdadero" tiene más ventajas prácticas que desventajas en un lenguaje sin un tipo booleano discreto.

Si bien vb.net es un lenguaje propio, bastante separado de vb6, hay una gran cantidad de código que ha sido portado de vb6 a vb.neto, y puede confiar en el hecho de que los operadores de comparación arrojan todos los bits establecidos cuando es verdadero.

0

Si desea convertir true a 1 y false a 0, utilice:

Convert.ToByte(Boolean) 

Enlace a la documentación Convert.ToByte(boolean).

De lo contrario, obtenga el valor real -1, 0xFF.