1

Does cleanliness trump performance here:

Version 1:

Function MyFunc(ByVal param as String) As String
    Dim returnValue as String
    If param Is Nothing Then
        returnValue = "foo"
    Else
        returnValue = param
    return returnValue

Version 2:

Function MyFunc(ByVal param as String) As String
    return If(param,"foo")

Version 1 deals directly with unboxed Strings. Version 2 deals with all boxed Objects. [If() takes a TestExpression as Object, a FalsePart as Object and returns an Object]

[can't add comments]
COMMENT: ja72, fixed my naming.
COMMENT: Marc, so you would go with Version 2?

anon
  • 11
  • 2
  • 3
    There is no such things as a boxed/unboxed string - boxing only applies to value types accessed as `object`. String is reference-type, but also - there **is** no `object` there. Finally, does VB not have a null-coalescing operator? in C# that would be just `return param ?? "foo";` – Marc Gravell Feb 08 '11 at 20:13
  • 2
    @Marc Gravel +1. VB.Net has ??, you are looking at it. If(obj1,obj2). :) – Tedd Hansen Feb 08 '11 at 20:20
  • See http://stackoverflow.com/questions/4619593/is-the-null-coalesce-operator-thread-safe -- it's for C#, but should be insightful (see first reply). You can also do the same to inspect the VB.NET IL. –  Feb 08 '11 at 21:00
  • See http://stackoverflow.com/questions/4915716/instantiating-a-variable-if-null -- also C#, but more good IL –  Feb 08 '11 at 21:23
  • @anon: is "If" built in to Visual Basic? Can you provide a link? – John Saunders Feb 08 '11 at 22:20
  • If(): http://msdn.microsoft.com/en-us/library/bb513985.aspx – Bennor McCarthy Feb 08 '11 at 22:58

5 Answers5

7

I think clarity trumps anything.

The If(obj1,obj2) function is the null coalescing operator of VB.NET. It functions the same as obj1 ?? obj2 in C#. As such, everyone should know what it means, and it should be used where conciseness is important.

Although the If/Else statement is clean, simple, and obvious, in this particular case, I would favor the If function.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • 1
    I'm with you. I'de rather read longer stuff than stopping everytime to wonder what this mean. – David Brunelle Feb 08 '11 at 20:11
  • Yes, keep the code readable and leave the optimization to the compiler. Use a profiler and revisit the code if it turns out it eats CPU. – Tedd Hansen Feb 08 '11 at 20:23
  • (In C#) I consider the ?? form more "clear" most of the time. Perhaps it's the difference in a visual queue. However, if I did use VB.NET, I would likely add the *if operator* to my repertoire of tools (as well as the 3-argument *ternary if operator*). It's hardly a "tricky operation", even if it does use a silly overloaded name. It's 2011 -- sort of a shame all if/then constructs aren't expressions :-) [It is an operator because the compiler can and will emit suitable IL instead of invoking a function with the given name.] –  Feb 08 '11 at 20:27
  • 3
    @John Saunders: I disagree. There's a world of difference between writing cryptic code, and using a simple and concise language construct that people using the language should be expected to know (which the null coalescing operator is). – Bennor McCarthy Feb 08 '11 at 20:30
  • @Bennor: I said nothing about the null coalescing operator. – John Saunders Feb 08 '11 at 22:20
  • `If(x, y)` *is* VB.NET's null coalescing operator. You referred to it as "that 'If' function". Have a look at pst's comment on ja72's answer. – Bennor McCarthy Feb 08 '11 at 22:53
  • @Bennor: sorry, thought `If` was something user-written. In that case, I'm deleting my answer. If it's a standard pattern in the language, then it should be clear enough. – John Saunders Feb 08 '11 at 22:55
  • Maybe just change the answer to reflect that - no one else has really mentioned it in an answer. – Bennor McCarthy Feb 08 '11 at 22:57
  • @Bennor: ok. Glad I waited for you to see the comment. – John Saunders Feb 08 '11 at 23:00
3

The compiler would optimize these two to the same code or nearly the same depending on the optimization level (See project properties).

Write two methods this way, compile them and use Reflector to look into the VB.Net decompiled code (or even MSIL) and you will see that there is very little (some billionth of a second) or none difference in exectuion.

Compiler optimizations generally handle normal patterns that allows you to write if-statements and loops in different ways. For instance in .Net for, foreach, while, do, etc do not actually exist. They are language specific features that are compiled down to goto-statement logic in the assembly level. Use Reflector to look at a few of these and you'll learn a lot! :)

Note that it is possible to write bad code that the compiler can't optimize to its "best state", and it is even possible to do better than the compiler. Understanding .Net assembly and MSIL means understanding the compiler better.

Tedd Hansen
  • 12,074
  • 14
  • 61
  • 97
  • There is actually a subtle difference in C# and I imagine it is similar in VB, although I have not looked at the IL -- some IL in this answer would make it really good. In C# the IL for the ?? operator performs a *copy* of test-value first. This ensures that *even across threads* `x ?? "not-null"` will *never return null* (not that it should be a replacement for proper thread-safety) –  Feb 08 '11 at 20:57
  • This might be interesting: http://stackoverflow.com/questions/4619593/is-the-null-coalesce-operator-thread-safe It also shows the IL, which is why I think it's actually a decent SO bit on the subject -- even if for C#. Hmm, but with the ability to optimize, I don't know... –  Feb 08 '11 at 20:59
  • if Strict in On and If() returns Object type, wouldn't you have to cast to string before returning? – eych Feb 09 '11 at 15:12
2

Really? I don't think this function is going to be a bottleneck in any application, and so just go with brevity/clarity.

I would recommend:

Public Function TXV(ByVal param As String) As String
    Return If(param Is Nothing, "foo", param)
End Function

and make sure the function returns a string (to keep type safety). BTW, why is your Function called MySub ? Shouldn't it be MyFunc ?

John Alexiou
  • 28,472
  • 11
  • 77
  • 133
  • 2
    It's not a function, even though it looks like one! `Iff` is a function. `If(a,b)` and `If(a,b,c)` are operators and compile to direct IL -- no function call. It just *looks* like a function. A +1 for the clarity comment though. –  Feb 08 '11 at 21:02
  • My bad. Initially I posted with `Iff()` and then changed it without altering the comments. – John Alexiou Feb 09 '11 at 00:14
1

I believe that these two implementations are nearly the same, I would use the second one because it's shorter.

Davide Piras
  • 43,984
  • 10
  • 98
  • 147
0

Since I come from a C background, I would opt for the ternary operator most times where it is clear what is happening - in a case like this where there is repetition and it can be idiomatic. Similarly in T-SQL where you can use COALESCE(a, b, c, d, e) to avoid having a bunch of conditionals and simply take the first non-null value - this is idiomatic and easily read.

Beware that the old IIf function is different from the new If operator, so while the new one properly handles side-effects and short-circuits, it's only one character away from a completely different behavior which people have long been wary of.

http://secretgeek.net/iif_function.asp

http://visualbasic.about.com/od/usingvbnet/a/ifop.htm

I don't think it's going to matter in terms of performance, because the optimizer is pretty good about these kind of transforms.

Cade Roux
  • 88,164
  • 40
  • 182
  • 265