0

Can someone help me to understand why If/Then/End If works but IIf doesn't?

I ran my code with this and it works as expected:

For Each BtnObj In Padre.Controls
  With BtnObj
    If nullinator(.Tag) = 0 Then
      .Visible = False
    Else
      .Visible = True
    End If
  End With
Next

Here's my "nullinator" function:

Public Shared Function nullinator(ByVal CheckVal As String) As Integer
    ' Receives a string and returns an integer (zero if Null or Empty or original value)
    If String.IsNullOrEmpty(CheckVal) Then
        Return 0
    Else
        Return CheckVal
    End If
End Function

However, if I run it using this code, nullinator(.Tag) = 0 always equates to be False even if the contents of Tag property is empty. Here's the code:

For Each BtnObj In Padre.Controls
    With BtnObj
        IIf(nullinator(.Tag) = 0, .Visible = False, .Visible = True)
    End With
Next

Oh yes, the "Padre" variable is the container (parent) object.

Any insights why I'm not having success using IIf would be greatly appreciated!

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • 2
    Returning a string when your function sig wants an Integer is not a great idea. – Sam Axe May 22 '17 at 23:25
  • Possible dup https://stackoverflow.com/questions/28377/performance-difference-between-iif-and-if , everything in these answers adddess the differences in one form or another... No need to add another one to the books. – Trevor May 23 '17 at 02:04

2 Answers2

2

IIf returns a value:

.Visible = IIf(nullinator(.Tag) = 0, False, True)

Returns one of two objects, depending on the evaluation of an expression.

https://msdn.microsoft.com/en-us/library/27ydhh0d(v=vs.90).aspx

As for why an Object is returned and taken as paraemeters as opposed to any other data type:

(an object) Holds 32-bit (4-byte) addresses that refer to objects. You can assign any reference type (string, array, class, or interface) to an Object variable. An Object variable can also refer to data of any value type (numeric, Boolean, Char, Date, structure, or enumeration). (emphasis my own)

By allowing the function to take any value type, there is no need for function overloading.

https://msdn.microsoft.com/en-us/library/twcxd6b8(v=vs.90).aspx

Nick is tired
  • 6,860
  • 20
  • 39
  • 51
  • now what I cannot understand is why in hell they used a function iif(boolean, object, object) as object, instead of iif(of T)(boolean, T, T) as T – Pierre May 23 '17 at 08:55
  • @Pierre see edit – Nick is tired May 23 '17 at 09:26
  • 2
    @Pierre - Because the `IIF` function predates generics support in VB. Besides, they replaced it with the `IF` operator which is much better. – Chris Dunaway May 23 '17 at 14:26
  • As an aside to this answer, returning `True` or `False` is redundant anyway. You can just use the result of the comparison: `.Visible = Not (nullinator(.Tag) = 0)` – Chris Dunaway May 23 '17 at 14:29
  • @ChrisDunaway : I hadn't heard of this IF operator... It does not calculate the useless part? That's great!! – Pierre May 23 '17 at 14:44
  • @Pierre - It's like C#'s conditional operator (?:) and it short circuits (unlike the `IIF` function). I don't remember precisely when it was introduced. – Chris Dunaway May 23 '17 at 15:14
  • @ChrisDunaway : thanks, I'll start using it. I had coded a function iff(of T), but obviously both sides were calculated – Pierre May 23 '17 at 15:24
0

... because what you think is an assignment is actually comparison.

The IIF function returns a value. So its going to return the result of .Visible = False or .Visible = True.

To make it work you probably want to remove the comparison and just return True or False.

Sam Axe
  • 33,313
  • 9
  • 55
  • 89