2009-04-13 18 views
29

Prendere il seguente codice:Convertire booleano per intero in VB.NET

Sub Main() 

    Dim i As Integer 
    Dim b As Boolean 

    i = 1 
    b = i 
    i = b 
    Console.WriteLine(i) 

    i = Convert.ToInt32(b) 
    Console.WriteLine(i) 

End Sub 

Questo stampa quanto segue:

-1 
1 

perché è questo?

(Solo uno scherzo :) È possibile ottenere 0 troppo ...

Int32.TryParse("True", i) 
Console.WriteLine(i) 

risposta

43

Quello che stai vedendo è un po 'di codice legacy mostrando la sua testa.

Il nocciolo della questione è il tipo VT_BOOL. Visual Basic 6.0 utilizzava il tipo VT_BOOL (AKA VARIANT_BOOL) per i suoi valori booleani. Vero per un VARIANT_BOOL è rappresentato con il valore VARIANT_TRUE che ha il valore intero -1. Durante la conversione in .NET è stato deciso che quando si utilizzavano le routine di conversione di Visual Basic per convertire un valore booleano in un valore Integer, la semantica di Visual Basic 6.0 veniva mantenuta sul valore restituito; sarebbe -1.

La prima conversione implicita avviene con la linea b = i. Sotto il cofano ciò comporta una conversione implicita da numero intero a valore booleano. Qualsiasi valore diverso da zero è ritenuto vero, quindi il valore risultante è true.

Tuttavia, la seguente riga di codice esegue una conversione implicita su un tipo intero.

Sotto il cofano questo utilizza una delle routine di conversione di Visual Basic (o CTypeCInt) per convertire il valore a un numero intero. Poiché la semantica di Visual Basic è in gioco e il valore restituito è -1.

La riga successiva interessante è la riga Convert.ToInt32(). Ciò sta utilizzando una routine di conversione .NET che non utilizza la semantica di Visual Basic. Invece, restituisce la rappresentazione sottostante BCL per un vero valore booleano che è 1.

+4

Si potrebbe voler aggiungere qualcosa riguardo a WHY VT_BOOL è stato utilizzato, e perché il suo valore è -1. VB 6 aveva solo 1 set di operatori "and" e "or", che eseguivano entrambe le operazioni logiche e bit a bit (la maggior parte delle lingue ha 2 set). Questo ha funzionato rendendo "e" implementato come "&" e il valore letterale predefinito è -1. –

+0

In questo modo "true e x" non è zero ogni volta che "x" è diverso da zero. –

+0

Puoi avere un'idea del "perché" nella mia risposta a una domanda per lo più non correlata qui: https://stackoverflow.com/a/46331671/3043 –

25

Alcune lingue considerano booleano vero di essere -1 invece di 1. avrei dovuto fare ricerche per capire perché, come Non ricordo.

In VB6, la costante True ha il valore -1.

Tuttavia, Convert.ToInt32(Boolean) è documented come restituisce "Il numero 1 se il valore è true, altrimenti 0." In questo modo, è lo stesso indipendentemente dal linguaggio di framework che stai utilizzando.

Edit: Vedere la domanda boolean true -- positive 1 or negative 1

+0

Alcune lingue utilizzano '-1' come' true', perché è '0b11111111', quindi ogni bit è l'opposto della rappresentazione binaria zeri, in modo tale che utilizzando un'operazione NOT bit a bit su uno avrebbe come risultato l'altro. – mbomb007

1

Questo perché in VB.NET, valori booleani sono -1 per una vera e 0 per false per impostazione predefinita. Io non sono sicuro perché viene stampato come 1 la seconda volta, anche se ...

7

Da MSDN documentazione di Visual Basic:

Type Conversions

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

E per Convert.ToInt32(value):

Retuns il numero 1 se il valore è vero; altrimenti, 0.

Così, per il codice:

i = 1 
b = i // b becomes true 
i = b // true = -1 
Console.WriteLine(i) // i is -1 

i = Convert.ToInt32(b) // Convert.ToInt32(true) = 1 
Console.WriteLine(i) // i is 1 
+0

Aggiungi un link per quelle citazioni doc e io upmod. –

10

Per quanto riguarda il motivo per cui -1 è utilizzato per True, credo che sia perché è letteralmente (NOT 0).

Iniziare con zero, capovolgere tutti i bit e quindi leggerlo come complemento a due - ne esce uno negativo.

Quindi, poiché tutto ciò che non è False è Vero e Falso è 0, il (NON Falso) è rappresentato da -1.

Questo può essere solo una coincidenza, anche se ....

+3

Questo è esattamente il motivo per cui VB utilizza -1 per True. :) –

+1

+1. È interessante notare che se "true" è -1, gli stessi operatori possono essere utilizzati per la logica booleana e il mascheramento dei bit interi. È anche interessante notare che la questione se il cortocircuito "e" e "o" sia indipendente dalla domanda se gli operandi "veri" debbano essere forzati a un singolo valore. – supercat

1

Tutti i tipi di dati numerici possono usato come booleano! Il risultato dipende dal tipo di dati utilizzato.

Esempi:

Dim i As Byte ' Byte is non-signed! 
Dim b As Boolean = True 

i = b   ' Set first (lowest) bit of i (non-signed byte) 
' i is now binary 0000 0001 = 1! 


Dim i As SByte ' SByte is signed! 
Dim b As Boolean = True 

i = b   ' Set all bits of i (signed byte) 
' i is now FF (binary 1111 1111 = -1 ! 

Integer è firmato, fedele alla Integer -> -1.

UInteger è non firmato, Fedele alla UInt -> 1.

E così via ...

un valore falso cancella il più alto bit in valori numerici firmati, e più bassa nel numerici non firmati.

Pertanto False è 0 in tutti i tipi di dati numerici.

2

"Vero" è una negazione dal valore 0 di un tipo di dati numerici!

Non (0) per i tipi non firmato restituisce 1.

Non (0) per i tipi firmato restituisce -1.

Non conosco il tuo codice, forse il tuo codice esegue una conversione interna dei dati la seconda volta.

1

Questa è una risposta evasiva, ma:

Dim b As Boolean 
    b = False 
    Dim i As Integer 
    i = IIf(b, 1, 0) 
Problemi correlati