2012-02-09 21 views
6

Perché il casting di in un byte in .NET fornisce il seguente output?Conversione di booleano in byte in VB.NET

Codice 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) 

uscita:

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

Perché True (w che viene comunemente indicato come una rappresentazione intera di 1) convertito in 255 quando viene convertito in uno byte?

+0

Mi sembra strano che VB.NET ti permetta anche di lanciare un booleano su un byte. In C# è un cast illegale. – vcsjones

+0

Se esegui un 'DirectCast()' in VB.NET, ti dirà automaticamente che è un cast illegale, ma se usi 'CType()' (che ho mostrato), farà come sopra. Sono interessato a sapere come 'True' che è comunemente noto come' 1', si traduce in '255' sotto il cofano. Un sacco di casting strano sta succedendo qui. – afuzzyllama

+0

Penso che questo sia solo il comportamento del compilatore. Emette IL 'ldc.i4 FF 00 00 00', anche se non riesco a vedere nulla nelle specifiche che dicono il perché. Per casi molto semplici il compilatore sta semplicemente ottimizzando il cast. – vcsjones

risposta

11

Il compilatore VB.NET gestisce come un conve restringimento rsion. Dal 10.0 VB.NET Spec:

conversioni Restringimento sono conversioni che non può essere provato per avere successo sempre, le conversioni che sono noti a perdere possibilmente le informazioni, e le conversioni tra domini di tipo sufficientemente differenti da meritare la notazione restringimento. Le seguenti conversioni sono classificati come conversioni restringimento:

  • Da booleano a Byte, SByte, ushort, Corto, UInteger, Integer, Ulong, Lungo, decimale, singolo o doppio.

Da the docs:

Quando Visual Basic converte i valori dei tipi di dati numerici per booleano, 0 diventa False e tutti gli altri valori diventano realtà. Quando Visual Basic converte i valori booleani in tipi numerici, False diventa 0 e True diventa -1.

I byte non sono firmati, quindi si ottiene 255 invece da Two's Compliment.

4

Un valore booleano di True in .NET viene memorizzato come -1, che a sua volta è 11111111 a causa di Two's Complement

Così Dim x As Boolean = 1 converte 1 a booleano Vero

e Dim y As Byte = x converte true 11111111, che è uguale a 255

(Se invece hai scritto Dim z As Integer = x, z sarebbe = -1)

3

Tutte le versioni storiche di Basic che ho visto che hanno supportato gli operatori booleani bitwise con numeri interi hanno utilizzato "all-bits-set", ovvero -1, come valore per confronti reali. Quindi, se si volesse avere un valore che fosse 9 se a == b, o zero se non, si potrebbe usare l'espressione 9 AND (a=b). Mentre l'operatore ?: presente in C consente a tale comportamento di essere codificato in modo più chiaro, l'uso di -1 per "true" ha più vantaggi pratici degli svantaggi in una lingua senza un tipo booleano discreto.

Mentre vb.net è una lingua propria, piuttosto separata da vb6, c'è molto codice che è stato trasferito da vb6 a vb.rete, e può contare sul fatto che gli operatori di confronto producono tutti i bit-set quando è vero.

0

Se si desidera convertire true a 1 e false-0, utilizzare:

Convert.ToByte(Boolean) 

link alla documentazione Convert.ToByte(boolean).

Altrimenti si ottiene il valore reale -1, 0xFF.