Преобразование Boolean в Integer в 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

Отпечатано следующее:

-1
1

Почему это?

(Просто шутка:) Вы тоже можете получить 0...

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

Ответ 1

То, что вы видите, - это немного устаревший код, показывающий его голову.

В основе дела лежит тип VT_BOOL. Visual Basic 6.0 использовал тип VT_BOOL (AKA VARIANT_BOOL) для своих логических значений. True для VARIANT_BOOL представлен значением VARIANT_TRUE, которое имеет целочисленное значение -1. Во время перехода на .NET было решено, что при использовании подпрограмм преобразования Visual Basic для преобразования логического значения в значение Integer семантика Visual Basic 6.0 будет поддерживаться на возвращаемом значении; это будет -1.

Первое неявное преобразование происходит с помощью строки b = i. Под капотом это делает неявное преобразование от целого к логическому. Любое ненулевое значение считается истинным, поэтому полученное значение истинно.

Однако следующая строка кода выполняет неявное преобразование в целочисленный тип.

i = b

Под капотом используется одна из процедур преобразования Visual Basic (CType или CInt), чтобы преобразовать значение в целое число. Поскольку такая семантика Visual Basic находится в игре, а возвращаемое значение равно -1.

Следующая интересная строка - это строка Convert.ToInt32(). Это использует процедуру преобразования .NET, которая не использует семантику Visual Basic. Вместо этого он возвращает базовое выражение BCL для истинного булевского значения, которое равно 1.

Ответ 2

Некоторые языки считают логическое значение true равным -1, а не 1. Я должен был бы провести исследование, чтобы понять, почему, как я не помню.

В VB6 константа True имеет значение -1.

Однако Convert.ToInt32(Boolean) documented в качестве возвращаемого значения "Число 1, если значение истинно, в противном случае - 0." Таким образом, это то же самое независимо от того, какой язык рамки вы используете.

Изменить: см. вопрос boolean true - положительный 1 или отрицательный 1

Ответ 3

Что касается того, почему -1 используется для True, я считаю, что это потому, что это буквально (NOT 0).

Начните с нуля, переверните все биты, а затем прочитайте его как два дополнения - получится отрицательный.

Итак, поскольку все, что не является False, является True, а False равно 0, (NOT False) представляется -1.

Это может быть просто совпадение, хотя....

Ответ 4

Из документации MSDN Visual Basic:

Преобразования типов

Когда Visual Basic преобразует числовые значения типа данных в Boolean, 0 становится Ложные и все другие значения становятся Правда. Когда Visual Basic конвертирует Логические значения для числовых типов, False становится равным 0, а True - -1.

И для Convert.ToInt32 (значение):

возвращает число 1, если значение истинно; в противном случае 0.

Итак, для вашего кода:

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

Ответ 5

"True" - это отрицание от значения 0 числового типа данных!

Не (0) для не подписанных типов возвращает 1.

Не (0) для подписанных типов возвращает -1.

Я не знаю вашего кода, возможно, ваш код выполняет внутреннее преобразование данных во второй раз.

Ответ 6

Это потому, что в VB.NET значения Boolean равны -1 для true и 0 для false по умолчанию. Я не уверен, почему он печатает как 1 второй раз, хотя...

Ответ 7

Все числовые типы данных могут использоваться как Boolean! Результат зависит от используемого типа данных.

Примеры:

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 !

Целое число подписано, True - целое → -1.

UInteger не подписан, True - UInt → 1.

И так далее...

Фальсифицированное значение очищает старший бит в числовых знаках, и самый низкий в неписанных числах.

Поэтому False - 0 во всех числовых типах данных.

Ответ 8

Это изворотливый ответ, но:

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