2015-01-20 4 views
1

Я хочу знать, почему следующая строка не ведет себя правильно. как я использовать IIF, хотя, когда условие истинно, то функция возвращает GetMessageIIF не ведет себя правильно

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 
+0

В чем проблема? –

+0

@roryap, поскольку я использую IIF, хотя, когда условие True, функция возвращает getMessage – Afflatus

+0

@Mathemats, что вы имеете в виду? – Afflatus

ответ

2

Вы должны изменить от IIF() в If() , поскольку последний использует короткое замыкание, а первое - нет. С версией IIf() GetMessage() вызывается даже тогда, когда логическое значение имеет значение true, что может вызвать побочные эффекты. При использовании Если(), только правильное возвращаемое значение вычисляется:

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

EDIT: Добавлен пример кода для лучшей наглядности 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 
+0

Спасибо @idle_После того, как у вас возникла проблема, но я хочу знать, почему это явление, которое вы вызвали короткое замыкание. Не могли бы вы немного объяснить об этом? – Afflatus

+0

aa Я получаю это сейчас, потому что я использую ссылочный тип (ссылаясь на тип msg), и поскольку выполняются условия для обеих сторон if и true и false, результат будет таким же. верный? – Afflatus

+1

@Afflatus, я добавил образец кода и скрипку для более упрощенной проблемы с 'IIF()'. Вы должны держаться подальше от него, если используете версию .NET, которая ее поддерживает. Единственный раз, когда вам придется корректировать свой код, является то, что в предложениях 'IIF' возвращались разные типы объектов, такие как String для предложения true и Integer для предложения false. (В этом случае вы можете преобразовать целое число с помощью метода '.ToString()', например) – ps2goat

2

Для clairify @Idle_Mind аргументируя это следующим образом ...

r=IIF(x,y,z) 

- вызов функции. Для того, чтобы вызвать все параметры (x, y AND z), необходимо оценить, прежде чем он войдет в тело функции для оценки.

r=IF(x,y,z) 

директива Компилятор. компоненты вашего кода, которые создают части «y» и «z», что выглядит как вызов функции, не оцениваются до тех пор, пока ПОСЛЕ сравнения не будет выполнено «x». Если эффективно скомпилирован как полный IF ELSE END IF структуры, как показано ниже ...

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

Один аккуратный вещь, чтобы отметить, что всякий раз, когда вы видите текст в VB.Net, который окрашен как «CTYPE» окрашен, его является директивой компилятора вместо традиционной единицы кода.

Смежные вопросы