【问题标题】:Comparing Integer and Integer? results in Boolean? not Boolean比较整数和整数?结果是布尔值?不是布尔值
【发布时间】:2009-05-28 10:51:10
【问题描述】:

我只是在编写一些代码来比较整数 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'.

虽然解决这个问题对我来说非常简单,但我希望有人能够解释编译器中发生了什么以发出此警告。

【问题讨论】:

    标签: .net vb.net compiler-construction


    【解决方案1】:

    这是可空类型的怪癖之一。 NULL(一般而言)表示“不知道”。比较 known 和 unknown 会得到 unknown(因为您不知道它们是否相同)。

    .NET 中的可空类型也是如此。将Integer? 与Integer 进行比较会得到Boolean?,因为您可能会得到True、False 或“不知道”。

    【讨论】:

    【解决方案2】:

    这是编译器为可空类型生成运算符的方式的不幸结果。您可以使用以下代码解决它:

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

    这里的If对应于C#的null coalesce operator,是一个快捷方式:

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

    【讨论】:

      【解决方案3】:

      您正在尝试将类型(整数)与可为空的类型(整数?)进行比较。

      您需要检查 nullID 的实际值,但不要忘记您需要检查 nullId 是否为 null。

      【讨论】:

        【解决方案4】:

        发生编译器错误是因为 Option Strict On 不允许从 'Boolean?' 进行隐式转换为“布尔”。而您正在尝试分配一个“布尔值”? ('Integer?'='Integer' 的结果)转换为 'Boolean'。

        在语言标准中,隐式转换通常被禁用,以避免意外错误。添加显式转换很容易;在不知道的情况下找到您在代码中放入的隐式转换可能很困难。

        可空类型和普通类型的区别足以避免它们之间的隐式转换。

        【讨论】:

        • 我想你错过了问题的实质,代码处理整数和整数?,报告的错误是布尔值?
        • "整数 = 整数?"结果是“布尔值?”,用户正试图将其分配给“布尔值”。但是,是的,我一开始就错过了那个细节:)
        【解决方案5】:

        Null 的值是“我不知道值是什么”,根据定义,任何操作数之一为 null 的操作都会导致 null。例如。 2 = null 结果为 null,因此 int = int?必须有 null 作为可能的值,而不仅仅是值 true 和 false。布尔?是只有该组值的类型,因此是操作的返回类型。

        唯一允许的隐式转换是那些总是有效的。您可以将 int 隐式转换为 long。但对于 int 来说不是很长(您可以明确地这样做),因为后者可能会导致信息丢失,例如如果数字大于 int.MaxValue。 在这种情况下,您将尝试取消装箱空值,这会导致运行时异常。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-05-05
          • 1970-01-01
          • 2012-11-04
          • 1970-01-01
          • 2014-12-13
          • 2011-03-11
          相关资源
          最近更新 更多