35

In order to return a value from a VB.NET function one can assign a value to the "Functions Name" or use "return value."

I sometimes see these inter-mixed in the same function. Personally, I prefer the return.

My question is, what is the internal difference, if any, between the two?

8 Answers 8

60

The difference is that they DO DIFFERENT THINGS!

'Return value' does 2 things:
1. It sets the function return value at that point 2. It immediately exits the function

No further code in the function executes!

'Functionname = value' does 1 thing: 1. It sets the function return value at that point

Other code in the function continues to execute This enables additional logic to refine or override the function return value

Huge difference folks. Remember it's not all about state, it's also about flow.

Sign up to request clarification or add additional context in comments.

3 Comments

He didnt ask about that. He asked about using a return value (not statement) or assigning the value to the function name.
He actually asked at "My question is, what is the internal difference, if any, between the two?
@StingyJack - You interpret the question to be about "using a return value (not statement)". I'm not sure what that means, but I do suspect that the consensus here is that "return" in the phrase "return value" from the question does indeed refer to the return statement and "value" refers to it's argument. In your other comment to me, you referred me to stackoverflow.com/a/451149/16391, which clearly compares assigning FunctionName to using the return statement, using a trivial example. As said above, the IL will be different using any non-trivial example.
22

Let's take a look... Oddly the "functionName =" generates less IL?

Code:

Public Function Test() As String
    Test = "Test"
End Function


Public Function Test2() As String
    Return "Test"
End Function

IL:

.method public static string Test() cil managed
{
    .maxstack 1
    .locals init (
        [0] string Test)
    L_0000: nop 
    L_0001: ldstr "Test"
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: ret 
}

.method public static string Test2() cil managed
{
    .maxstack 1
    .locals init (
        [0] string Test2)
    L_0000: nop 
    L_0001: ldstr "Test"
    L_0006: stloc.0 
    L_0007: br.s L_0009
    L_0009: ldloc.0 
    L_000a: ret 
}

8 Comments

Interesting: the implicit return saved one instruction.
Nice post. Why is the branch to L_0009 necessary? Perhaps it is there simply because the return is not optimized away?
Return is compatible with C# is more readable for more programmers and it sounds better
Rulas, your comment is irrelevant and unjustified, please read all responses and comments before commenting.
It should be noted that this is only in debug mode (thus, irrelevant)! In release mode, the same code is generated.
|
17

There is probably no difference. IIRC, the compiler generated IL converts them both into Return statements unless there is additional usage of a _returnValue variable.

The readability of the FunctionName assignment is poor in my opinion, and an example of a bad VB6 habit. I prefer the _returnValue (NOT RETVAL) variable method also.

6 Comments

The answer below is a better answer
@Jonathan - The answers on SO questions are not always ordered the same way. Can you link to the post instead?
This answer is plain wrong. The IL does not convert the assignment of the function name to a return statement, because the assignment does not cause the function to return at that time. The value of the assignment returns only when the return statement is called without an argument, or at "end function".
@MichaelKrebs - Are you sure? Compiling in release mode shows the same things in trivial examples. See stackoverflow.com/a/451149/16391 for another example.
@StingyJack - Yes, I'm sure. The IL is only the same in trivial examples, and only in release mode. Any code in a function that follows a FunctionName assignment will be executed, and any code in a function that follows a Return call will not. That is a huge difference in behavior that always shows up as differences in the IL, in both release and debug mode, if there is even one more line of code following. It is also highly relevant to the question, "what is the internal difference, if any, between the two?"
|
7

Doing the following is only provided for Visual Basic 6.0 developers to easily port code over:

Public Function MyFunction() As String
    MyFunction = "Hello"
End Function

I would definitely not recommend keeping doing it if your project includes anyone who hasn't worked with Visual Basic 6.0, as this syntax will be confusing.

5 Comments

I was scratching my head as well... Balancing.
My question is what is about the internal differences between the two, not preferences or best practices.
Some explanation as to why you would recommend the one thing over the other would be good, though.
The post also appeared agressive and offensive with the "you" wording. Especially when, given that context, it contradicts my post.
Removed last bit as it wasn't needed, thanks for pointing it out, thats what I get for writing when I first wake up! :)
2

When Tools/Options/Text Editor/All Languages/Code Lens is activated, the Reference Count shows above each Sub, Function, or Property statement.

"Return Value" seems better than "assigning a value to the Functions Name". In the latter case, "Code Lens" produces an inflated Reference Count.

' Code Lens reports "0 references" here for Sub Rosa().
Public Sub Rosa()
    Diagnostics.Debug.WriteLine(Test())
    Diagnostics.Debug.WriteLine(Test2())
End Sub

' Code Lens reports "2 references" here for Function Test().
Public Function Test() As String
    Test = "Test"       ' Code Lens counts this as a reference.
End Function

' Code Lens reports "1 reference" here for Function Test2().
Public Function Test2() As String
    Dim strTest2 as String = "Test"
    Return strTest2     ' Code Lens does NOT count this as a reference.
End Function

1 Comment

The point about the inflated reference count is worth considering in my opinion.
1

99 times out of 100 I'll use "return value".

Every once in a while I'll have a function where the other type not only allows me to save a variable declaration, but do it in a way that actually significantly clarifies the function. Usually this happens when I would want to name the return value the same as the function anyway, and often these are recursive functions; something about that construct lends it to the implicit return variable. However, that scenario is extremely rare. I don't know if I have any functions using implicit return variables at all in my current project.

Comments

0

Having read that the Return Value syntax was the One True .NET Way Of Doing Things I thought "OK, we'll do it that way then". Then I wrote a function which I knew, hand on heart KNEW, returned either a value from a Return statement or alternatively an Exception under all circumstances, and still got a compiler warning that the function "doesn't return a value on all paths".

Thankfully I came across the Stack Overflow question How can I make this function not generate a “doesn't return a value on all paths” warning? which explained why; adding a default value assignment to the procedure name at the head of the function prevented the warning in my case as well.

Consequently, even though I'll continue to use the Return Value syntax simply for the sake of syntax consistency, I'll also be assigning a default value to the function name just to prevent the possibility of cluttering up the compile process with bogus warnings.

Comments

0

its quite handy when working with 3rd party factories(_hsf), you can avoid declaring return variables

Public Function CreateExtremum(iShape As INFITF.Reference, iDir1 As HybridShapeTypeLib.HybridShapeDirection, iSide1 As Integer, iDir2 As HybridShapeTypeLib.HybridShapeDirection, iSide2 As Integer, iDir3 As HybridShapeTypeLib.HybridShapeDirection, iSide3 As Integer) As HybridShapeTypeLib.HybridShapeExtremum
    CreateExtremum = _hsf.AddNewExtremum(iShape, iDir1, iSide1)
    CreateExtremum.Direction2 = iDir2
    CreateExtremum.ExtremumType2 = iSide2
    CreateExtremum.Direction3 = iDir3
    CreateExtremum.ExtremumType3 = iSide3
    CreateExtremum.Compute()
End Function

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.