[2005] Return vs. Exit Sub
I've seen both used to exit a routine after an error, so I can safely assume both statements do the same thing (in terms of handing control back to the caller).
My question is, does anyone prefer one over the other? I've become quite used to using Return, but I can see how Exit Sub might be better for readability, since Return can also be used in a function to send a value back to a caller.
I heard Return is more common across other languages though.
Any thoughts?
Mods feel free to move to general developer if necessary. I just put it here because the topic is specific to VB.Net.
Re: [2005] Return vs. Exit Sub
On the top level they are both the same but if you are in a Sub routine then it depends on your code block as you shouldnt have more then one exit point and using either is "ok".
Return is used to "return a value" which is used in a Function but return with a value is optional which is why it also works in a Sub.
Re: [2005] Return vs. Exit Sub
Personally I use them for consistency, when I write a sub and need to get out a t some point I use exit sub. On the other hand if i'm in a function then I use return (actually have no other choice here thought lol)
Re: [2005] Return vs. Exit Sub
Well you could use Exit Function if you are assigning the function name the return value.
Code:
Public Function Test(ByVal Blah As Integer) As Boolean
'Whatever
If 1 = 2 Then
Test = False
Exit Function
Else
Test = True
Exit Function
End If
End Function
Re: [2005] Return vs. Exit Sub
Quote:
Return is used to "return a value" which is used in a Function but return with a value is optional which is why it also works in a Sub.
Java and C++ I believe both use the return call. Sub's in vb are void's in C++ - that is, functions without a return value anyhow.
It would be interesting to see the MSIL behind both of the calls - but I'd imagine at IL level they'd be exactly the same coding.
Personally I use the return call, but ONLY at the end of a function (usually I will keep a method-level variable updated on the method return value and only return that at the end of the function). Having IF...Then statements and keeping the flow from top to bottom of the method code I find is much easier rather than figuring out why code execution suddenly halts and pops out of a method 1/2 way through it (or a debugging breakpoint line never gets hit due to the same reason).
Re: [2005] Return vs. Exit Sub
Yes, that helps greatly when debugging to follow the standard of only one exit point in a procedure.
Re: [2005] Return vs. Exit Sub
Just off the top of my head, I seem to remember something about returns and optimization.
Re: [2005] Return vs. Exit Sub
Never use Exit Sub or Exit Function. That's easy to remember.
All functions should complete at a Return statement. Many people believe, as do I, that it is preferable to have a single Return statement at the end of the method with all execution paths leading to that line.
Procedures (Subs) can just exit naturally at the End Sub statement. If you want to exit early then you can use a Return statement again, but don't specify a return value. That said, it is again considered preferable by many not to have multiple exit points in a procedure either, but rather to make all execution paths lead to the End Sub line. For instance, rather than doing this:
vb.net Code:
Private Sub DoSomething()
If someCondition Then
Return
End If
'Do something here.
End Sub
it is preferable to do this:
vb.net Code:
Private Sub DoSomething()
If Not someCondition Then
'Do something here.
End If
End Sub
The net result of those two code snippets is the same but the second one provides a single exit point for the method. As methods get more complex that becomes more maintainable.
That said, there are times where forcing a single exit point can make code more complex by creating additional levels of nested If statements. In that case it's worth considering breaking the method up into multiple methods if it's practical. If it's not then providing multiple exit points is acceptable. Remember, the idea of a single exit point is to improve maintainability. If doing so actually hinders maintenance then it defeats the purpose, so that would be the exception to the rule.
Edit: Having read some other posts in the thread now I see that I agree with alex. :thumb:
Re: [2005] Return vs. Exit Sub
Wow, really? :eek: :D Cool!
Dbasnett's post intrigued me there, and I have uncovered this one - however evil, it's good (and a little confusing) that the retun does perform better than an exit, though I haven't found why, but interesting stuff to see!
Quote:
Return
Code that uses the Return statement is optimized better than code using Exit Function, Exit Property, or Exit Sub. For functions use Return with an expression. For Subs and Properties use Return without an expression.
Re: [2005] Return vs. Exit Sub
that is it. what i didn't get:
are End Function / End Sub returns or exits?
Re: [2005] Return vs. Exit Sub
Quote:
Originally Posted by jmcilhinney
Edit: Having read some other posts in the thread now I see that I agree with alex. :thumb:
Quote:
Originally Posted by RobDog888
... you shouldnt have more then one exit point ...
I guess I am transparent today :( :lol:
Re: [2005] Return vs. Exit Sub
Quote:
Originally Posted by RobDog888
Yes, that helps greatly when debugging to follow the standard of only one exit point in a procedure.
But if I have a form with 5 or 6 boxes consisting of combo boxes, textboxes, etc., how can I have only one exit point?
If someone has entered bad data into a field, I need to refocus on that field immediately, there is no need to continue with the validation.
Unless there is something elementary that I have completely missed, I need an exit point every time validation fails.
Re: [2005] Return vs. Exit Sub
If you are doing validation you should really be in a Try...Catch block and in that case you could Exit Try if a validation fails (which in theory would take your single exit point)
Re: [2005] Return vs. Exit Sub
Code:
If validationcheck1 = true
' Carry on processing, perform validation check 2
If validationcheck2 = true then
' another inner statement to continue positive execution routines...
end if
End if
' Code continues at this point if validation check 1 wasn't true...
End Sub
Code:
... you shouldnt have more then one exit point ...
Ohh yeah! Well I'll acknowledge you Rob! - post was there 1st, must admit I missed that the 1st time round - maybe put it in 50pt bold? :D :cool:
Re: [2005] Return vs. Exit Sub
Quote:
Originally Posted by Blakk_Majik
But if I have a form with 5 or 6 boxes consisting of combo boxes, textboxes, etc., how can I have only one exit point?
If someone has entered bad data into a field, I need to refocus on that field immediately, there is no need to continue with the validation.
Unless there is something elementary that I have completely missed, I need an exit point every time validation fails.
You can do it many ways.
Perform the check at the lostfocus event of each control or just validate at the button click that processes them.
Also, use an If Then code block or a Try Catch code block. Either way they dont need to exit from them and just call a process sub upon valid validation otherwise it falls through and exits the sub at the closing procedure line.
:woot: acknowledged :D
Re: [2005] Return vs. Exit Sub
Quote:
Originally Posted by alex_read
Code:
If validationcheck1 = true
' Carry on processing, perform validation check 2
If validationcheck2 = true then
' another inner statement to continue positive execution routines...
end if
End if
' Code continues at this point if validation check 1 wasn't true...
End Sub
This code is fine, but it does not give enough information. If a part of the validation fails, and it just exits the sub, what information will it give? How will the user know that validation check 2 is the one that failed? How will they know what to do so that validation check 2 doesn't fail again?
I suppose I'm thinking about it from a user standpoint. If I put the wrong value in the name textbox, tell me and let me change it. Don't just tell me the app could not verify my input, or throw some exception that the average user will not understand.
Re: [2005] Return vs. Exit Sub
Having declared the following methods:
Code:
Private Sub doReturn(ByVal s As String)
If s = "" Then
Return
End If
Console.WriteLine(s)
End Sub
Private Sub doExitSub(ByVal s As String)
If s = "" Then
Exit Sub
End If
Console.WriteLine(s)
End Sub
We get the following IL:
Code:
.method private instance void doReturn(string s) cil managed
{
// Code size 23 (0x17)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldstr ""
IL_0006: ldc.i4.0
IL_0007: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Operators::CompareString(string,
string,
bool)
IL_000c: ldc.i4.0
IL_000d: bne.un.s IL_0010
IL_000f: ret
IL_0010: ldarg.1
IL_0011: call void [mscorlib]System.Console::WriteLine(string)
IL_0016: ret
} // end of method Form1::doReturn
.method private instance void doExitSub(string s) cil managed
{
// Code size 23 (0x17)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldstr ""
IL_0006: ldc.i4.0
IL_0007: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Operators::CompareString(string,
string,
bool)
IL_000c: ldc.i4.0
IL_000d: bne.un.s IL_0010
IL_000f: ret
IL_0010: ldarg.1
IL_0011: call void [mscorlib]System.Console::WriteLine(string)
IL_0016: ret
} // end of method Form1::doExitSub
So the compiler in both cases jumps conditionally to a label and inserts a return opcode if the jump isn't executed.
Interestingly enough, the method:
Code:
Private Sub doNoReturn(ByVal s As String)
If s = "" Then
Return
Else
Console.WriteLine(s)
End If
End Sub
produces the following IL:
Code:
.method private instance void doNoReturn(string s) cil managed
{
// Code size 23 (0x17)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldstr ""
IL_0006: ldc.i4.0
IL_0007: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Operators::CompareString(string,
string,
bool)
IL_000c: ldc.i4.0
IL_000d: bne.un.s IL_0010
IL_000f: ret
IL_0010: ldarg.1
IL_0011: call void [mscorlib]System.Console::WriteLine(string)
IL_0016: ret
} // end of method Form1::doNoReturn
which is the same as in both previous cases. So I'd say that use of Return, Exit Sub or nested IFs is purely a matter of personal/team preference for methods that don't return a value.
Re: [2005] Return vs. Exit Sub
Well blimey that was a simple sample :D , ok try this then :p
Code:
Dim validityErrorMessageString as string = string.empty
If textbox1.text= string.empty then
validityErrorMessageString = "Textbox Empty!"
If textbox1.text.trim.length < 2 then
validityErrorMessageString = "Text entered was only 1 character"
end if
End if
If validityErrorMessageString = string.empty then
return "All OK!"
Else
return validityErrorMessageString
End If
End Sub
Re: [2005] Return vs. Exit Sub
Fantastic stuff NTG :) , I was far too lazy to do that.
I imagined that would have been the case originally, but was fascinated when I heard mention the methods did perform differently, guess you can't believe everything you read on the net! (that wasn't aimed at dbasnett, rather at getdotnetcode.com ;) who I found that above quote from).
Thanks for clearning that one up and posting the sample, very useful stuff!
Re: [2005] Return vs. Exit Sub
Quote:
Originally Posted by Blakk_Majik
But if I have a form with 5 or 6 boxes consisting of combo boxes, textboxes, etc., how can I have only one exit point?
If someone has entered bad data into a field, I need to refocus on that field immediately, there is no need to continue with the validation.
Unless there is something elementary that I have completely missed, I need an exit point every time validation fails.
Yes, you are missing something fundamental. You should be validating each control in its own Validating event handler. If you want to validate the entire form, say on a Button Click, then you call the form's ValidateChildren method. This will raise each control's Validating event in turn. If any control fails validation, i.e. you set the e.Cancel property to True in the Validating event handler, then validation halts there and that control receives focus. Here's an example of that mechanism in a Login dialogue:
vb.net Code:
Private Sub userNameText_Validating(ByVal sender As Object, _
ByVal e As System.ComponentModel.CancelEventArgs) Handles userNameText.Validating
If Me.userNameText.Text.Trim() = String.Empty Then
MessageBox.Show("Please enter a user name.", _
"Required Field", _
MessageBoxButtons.OK, _
MessageBoxIcon.Warning)
e.Cancel = True
End If
End Sub
Private Sub passwordText_Validating(ByVal sender As Object, _
ByVal e As System.ComponentModel.CancelEventArgs) Handles passwordText.Validating
If Me.passwordText.Text.Trim() = String.Empty Then
MessageBox.Show("Please enter a password.", _
"Required Field", _
MessageBoxButtons.OK, _
MessageBoxIcon.Warning)
e.Cancel = True
End If
End Sub
Private Sub loginButton_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles loginButton.Click
Me.ValidateChildren()
End Sub