【问题标题】:IIF doesn't behave correctlyIIF 行为不正确
【发布时间】:2015-01-20 02:51:17
【问题描述】:

我想知道为什么以下行的行为不正确。当我使用 IIF 时,虽然当条件为 True 时,函数返回 getMessage

Return CType(IIf(Object.Equals(_newValue, _oldValue), 
             msg, GetMessage(msg)), PooMessage)

但以下几行表现得很好:

If Object.Equals(_newValue, _oldValue) Then
        Return msg
Else
        Return CType(GetMessage(msg), PooMessage)
End If

【问题讨论】:

  • @roryap 因为我使用 IIF,虽然当条件为 True 时,函数返回 getMessage
  • @Mathemats 你是什么意思
  • @Afflatus 您正在将返回的对象与 msg 进行比较,然后在失败时调用 GetMessage。尝试:返回 CType(IIf(Object.Equals(_newValue, _oldValue), msg, GetMessage(msg), PooMessage))
  • @Mathemats 你的那一行甚至无法编译!
  • IIf() vs. If 的可能重复项

标签: vb.net iif


【解决方案1】:

您应该从 IIf() 更改为 If(),因为后者使用短路,而前者没有。在 IIf() 版本中,即使布尔值计算为 true,也会调用 GetMessage(),这可能会导致副作用。使用 If() 时,只计算正确的返回值:

Return CType(If(Object.Equals(_newValue, _oldValue), msg, GetMessage(msg)), PooMessage)

编辑:添加了示例代码,以便更清楚地了解 If() 与 IIF(),以及 dotnetfiddle 示例 小提琴:https://dotnetfiddle.net/vuMPgK

代码:

Imports System
Imports Microsoft.VisualBasic

Public Module Module1
    Public Sub Main()

        Dim didItWork as Boolean = False
        Dim myTestObject as Test = Nothing

        ' works, due to IF(). Only the 'true' value is calculated
        didItWork = If(myTestObject Is Nothing, False, myTestObject.MyValue)

            Console.WriteLine("Did If() work?: " & didItWork.ToString())


            ' does not work, due to IIF().  Both True and False conditions are calculated regardless of the original test condition.
            '  it fails because myTestObject is null, so trying to access one of its properties causes an exception.
            Try
                didItWork = IIF(myTestObject Is Nothing, False, myTestObject.MyValue)
                Console.WriteLine("Did IIF() work?: " & didItWork.ToString())
            Catch ex as Exception
                Console.WriteLIne("Error was thrown from IIF")
            End Try

    End Sub
End Module

Public Class Test
        Public Property MyValue as Boolean = True
End class

【讨论】:

  • 谢谢@idle_Mind,你的问题是对的,但我想知道为什么会发生这种你称之为短路的现象。你能解释一下吗?
  • aah 我现在明白了,因为我使用的是引用类型(指 msg 类型),并且因为 true 和 false 的 if 条件都在执行,结果将是相同的。对吗?
  • @Afflatus,我为IIF() 的更简化问题添加了代码示例和小提琴。只要您使用支持它的 .NET 版本,就应该远离它。唯一需要调整代码的情况是 IIF 子句返回不同的对象类型,例如 true 子句的 String 和 false 子句的 Integer。 (在这种情况下,您可以使用 .ToString() 方法转换整数,例如)
【解决方案2】:

澄清@Idle_Mind 原因如下...

r=IIF(x,y,z) 

是一个函数调用。为了调用它,所有参数 (x, y AND z) 必须在它进入函数体进行评估之前进行评估。

r=IF(x,y,z) 

是一个编译器指令。代码中创建看起来像函数调用的“y”和“z”部分的组件直到在“x”上完成比较之后才会被评估。 If 被有效地编译为完整的 IF ELSE END IF 结构,如下所示...

if x then
    r=y
else
    r=z
end if

需要注意的一点是,每当您在 VB.Net 中看到像“Ctype”一样着色的文本时,它是编译器指令而不是传统的代码单元。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-20
    • 1970-01-01
    • 2012-12-21
    • 2021-04-25
    • 2014-06-28
    相关资源
    最近更新 更多