VB gotcha: when If function isn’t equivalent to an If-Then-Else block
Just got bitten by the following:
Dim takeN As Integer = If(Integer.TryParse(EdTake.Text, takeN), takeN, itemsCount)
I had used that instead of writing in 2 lines:
Dim takeN As Integer
If not Integer.TryParse(EdTake.Text, takeN) then takeN = itemsCount
However, there’s an important difference:
“If” is a function, so its arguments are evaluated at call-time. The “If” signature is:
I guess the default is to pass arguments ByVal (by value) and not ByRef (by reference), although I’d expect the signature to specify it explicitly to avoid confusion. When one passes a literal value (say 15) to TruePart or FalsePart it just gets “boxed” into an Object, whereas if one passes an expression (e.g. “takeN+1” or even just “takeN”) it gets evaluated first, then result is boxed and passed as an Object.
So, whereas one might think (esp. if coming from the ALGOL “Call-By-Name” era) the 1st line to be equivalent to:
Dim takeN As Integer
If Integer.TryParse(EdTake.Text, takeN) then takeN = [RESULT OF TRYPARSE] else takeN = itemsCount
in fact it’s equivalent to:
Dim takeN As Integer
If Integer.TryParse(EdTake.Text, takeN) then takeN = [ANY] else takeN = itemsCount
where ANY is whatever the takeN variable one had defined contains.
I thought the VB compiler was warning when using a variable before having assigned a value to it, but it seems in this case it misses to issue a warning. In fact I just tried:
Public ReadOnly Property Take As Integer
Get
Dim takeN As Integer
Return takeN
End Get
End Property
and it still doesn’t complain. Strange, probably it sets new local variables to 0 by default, but it shouldn’t encourage a programming style that relies on implicit default values – such syntax usually means there’s a mistake in the source code that can lead to a nasty bug.
The moral of the story? Avoid such shorthand expressions and stick to classic keyword-based syntactical structures – after all structured programming had been introduced as an alternative to the many times incomprehensible programs written in functional programming languages (e.g. due to overuse of nested function calls).