VB equivalent of C# null coalescing operator - specific case

I am aware that similar questions have been asked before:

  • VB.NET null coalescing operator?
  • Coalesce operator and Conditional operator in VB.NET

But my issue is not addressed there. In C# I can write this:

return myFoo ??= new Foo() 

If myFoo is null, this line will create a new Foo, assign it to myFoo, and return the value of myFoo.

I want to translate this to VB. I can do it in two statements e.g.:

If myFoo Is Nothing Then myFoo = New Foo()
Return myFoo

or even using the two-argument If function:

myFoo = If(myFoo, New Foo())
Return myFoo

I would prefer to do it in one statement. This looks like it ought to be equivalent to the C# version:

Return myFoo = If(myFoo, New Foo())

But it doesn't work because it interprets the = as a comparator, not an assignment.

Is there an elegant solution?


Solution 1:

C-heritage languages (which includes C#) have historically treated assignment as an expression which means that it has a result. Historically, that result is the value that was assigned. This has advantages, which includes allowing more concise multiple assignments and testing results of assignment in conditionals. It also has disadvantages, which include potential confusion of assignment and equality operators in conditionals.

Other languages treat assignment as a statement which means that it does not have a result and cannot be composed into another operation. VB is one of these languages (others include Fortran and Pascal).

Because assignment is a statement in VB, you cannot assign and test in the same operation unless you write your own function to do so. You will have to do your two-line operation, or use the : statement separator to put both statements on one line.

Idle curiosity on VB that relates to language families: pre-.NET, VB had much more in common with Fortran than C. The end block statements follow the same conventions as Fortran, the code editor will recognize EndIf and convert it to End If, the array layout was the same (column-major instead of row-major), and the code editor would recognize the Fortran convention for a double-precision constant e.g. 1.0d0 would be treated as a double 1.0. The last two have been lost with the move to .NET.