Конвертировать логическое в целое в VB.NET - PullRequest
33 голосов
/ 14 апреля 2009

Возьмите следующий код:

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)

Ответы [ 8 ]

44 голосов
/ 14 апреля 2009

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

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

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

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

i = b

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

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

29 голосов
/ 14 апреля 2009

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

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

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

Редактировать: см. Вопрос логическое значение true - положительный 1 или отрицательный 1

10 голосов
/ 14 апреля 2009

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

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

Таким образом, поскольку все, что не является ложным, является истинным, а ложным является 0, (НЕ ложное) представляется как -1.

Хотя это может быть просто совпадением ...

7 голосов
/ 14 апреля 2009

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

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

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

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

возвращает число 1, если значение равно true; в противном случае 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
2 голосов
/ 20 ноября 2015

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

    Dim b As Boolean
    b = False
    Dim i As Integer
    i = IIf(b, 1, 0)
2 голосов
/ 05 июля 2011

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

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

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

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

2 голосов
/ 14 апреля 2009

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

1 голос
/ 05 июля 2011

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

Примеры:

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 to Integer -> -1.

UInteger не подписан, True для UInt -> 1.

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

Ложное значение очищает старший бит в числовых значениях со знаком и самый низкий бит в числовых значениях без знака.

Следовательно, False равно 0 во всех числовых типах данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...