IIF 行为不正确
IIF doesn't behave correctly
我想知道为什么下面一行的行为不正确。当我使用 IIF 时,虽然当条件为真时,函数 returns 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
你应该把IIf()改成If(),因为后者使用了短路,而前者没有。对于 IIf() 版本,即使布尔值计算结果为真,也会调用 GetMessage(),这可能会导致副作用。使用 If() 时,只会评估正确的 return 值:
Return CType(If(Object.Equals(_newValue, _oldValue), msg, GetMessage(msg)), PooMessage)
编辑:添加示例代码以更清楚地了解 If() 与 IIF(),以及 dotnetfiddle 示例
Fiddle: 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原因如下...
r=IIF(x,y,z)
是一个函数调用。为了调用它,所有参数(x、y 和 z)必须在进入函数体进行评估之前进行评估。
r=IF(x,y,z)
是一个编译器指令。代码中创建 "y" 和 "z" 部分的 看起来像函数调用 的组件在对 [=29= 进行比较后才会被评估].如果被有效编译为完整的 IF ELSE END IF 结构,如下所示...
if x then
r=y
else
r=z
end if
需要注意的一点是,每当您在 VB.Net 中看到颜色类似于 "Ctype" 的文本时,它就是一个编译器指令,而不是传统的代码单元。
我想知道为什么下面一行的行为不正确。当我使用 IIF 时,虽然当条件为真时,函数 returns 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
你应该把IIf()改成If(),因为后者使用了短路,而前者没有。对于 IIf() 版本,即使布尔值计算结果为真,也会调用 GetMessage(),这可能会导致副作用。使用 If() 时,只会评估正确的 return 值:
Return CType(If(Object.Equals(_newValue, _oldValue), msg, GetMessage(msg)), PooMessage)
编辑:添加示例代码以更清楚地了解 If() 与 IIF(),以及 dotnetfiddle 示例 Fiddle: 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原因如下...
r=IIF(x,y,z)
是一个函数调用。为了调用它,所有参数(x、y 和 z)必须在进入函数体进行评估之前进行评估。
r=IF(x,y,z)
是一个编译器指令。代码中创建 "y" 和 "z" 部分的 看起来像函数调用 的组件在对 [=29= 进行比较后才会被评估].如果被有效编译为完整的 IF ELSE END IF 结构,如下所示...
if x then
r=y
else
r=z
end if
需要注意的一点是,每当您在 VB.Net 中看到颜色类似于 "Ctype" 的文本时,它就是一个编译器指令,而不是传统的代码单元。