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.
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. –
In questo modo "true e x" non è zero ogni volta che "x" è diverso da zero. –
Puoi avere un'idea del "perché" nella mia risposta a una domanda per lo più non correlata qui: https://stackoverflow.com/a/46331671/3043 –