Сравнивать целое и целое? результаты в логическом? не булево - PullRequest
4 голосов
/ 28 мая 2009

Я просто пишу немного кода, чтобы сравнить id целого числа с id целого числа? например:

Dim id As Integer = 1
Dim nullId As Integer? = Nothing
Dim areEqual As Boolean
areEqual = nullId = id

Когда я пытаюсь скомпилировать код, я получаю ошибку компилятора:

Option Strict On disallows implicit conversions from 'Boolean?' to 'Boolean'.

Хотя мне очень легко обойти это, я надеялся, что кто-то сможет объяснить, что происходит в компиляторе, чтобы выдать это предупреждение.

Ответы [ 5 ]

7 голосов
/ 28 мая 2009

Это один из причуд обнуляемых типов. NULL (в общих чертах) означает «не знаю». Сравнение известного с неизвестного приводит к неизвестному (потому что вы не знаете, совпадают ли они).

То же самое относится и к обнуляемым типам в .NET. Сравнение Integer? с Integer приводит к Boolean?, потому что вы можете получить True, False или "не знаю".

3 голосов
/ 28 мая 2009

Это печальное следствие того, как компилятор генерирует операторы для обнуляемых типов. Вы можете обойти это, используя следующий код:

Dim AreEqual As Boolean = If(nullId, 0) = id

If здесь соответствует пустому оператору объединения C # и является сокращением для:

Dim AreEqual As Boolean = If(nullId.HasValue, nullId.Value, 0) = id
0 голосов
/ 28 мая 2009

Ноль имеет значение «Я не знаю, что это за значение», и по определению любая операция, в которой один из операндов равен нулю, приводит к нулю. Например. 2 = ноль приводит к нулю и, следовательно, полученное значение из int = int? должно иметь нулевое значение в качестве возможного значения, а не просто иметь значения true и false. BOOL? это тип, который имеет только этот набор значений и, следовательно, является типом возврата операции.

Допускаются только неявные приведения, которые будут работать всегда. вы можете неявно привести int к long. но не длинным до int (вы можете сделать это явно), потому что последний может привести к потере информации, например если число больше, чем int.MaxValue. В этом случае вы пытаетесь распаковать нулевое значение, что приведет к исключению во время выполнения.

0 голосов
/ 28 мая 2009

Ошибка компилятора происходит из-за того, что Option Strict On запрещает неявные преобразования из 'Boolean?' в «логическое». И вы пытаетесь присвоить «логическое значение»? (результат 'Integer?' = 'Integer') в 'Boolean'.

Неявные преобразования обычно отключаются в языковых стандартах, чтобы избежать непреднамеренных ошибок. Добавить явное преобразование легко; найти неявное преобразование, которое вы вставили в свой код, не зная, что это может быть сложно.

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

0 голосов
/ 28 мая 2009

Вы пытаетесь сравнить тип (целое число) с обнуляемым типом (целое число?).

Вам нужно проверить фактическое значение nullID, но не забывайте, что вам нужно проверить, что nullId равен нулю.

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