Click here to Skip to main content
12,888,493 members (47,843 online)
Click here to Skip to main content
Add your own
alternative version

Stats

111.8K views
19 bookmarked
Posted 9 Mar 2006

Functions VS Subroutines and By Val Vs By Ref in VB.NET

, 9 Mar 2006
Rate this:
Please Sign up or sign in to vote.
Functions VS Subroutines and By Val Vs by Ref in VB.NET
<!-- Article Starts - DO NOT ADD HTML/BODY START TAGS-->

Introduction

Functions VS Subroutines and By Val Vs by Ref in VB.NET<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p>

<o:p> 

The purpose of this article is to clear the minds of the developers on Methods in VB.net who are reading this article.<o:p>

<o:p> 

While doing Code review for client, I found out there are various Subroutines which has reference types (Like textboxes, Array Lists) as BY Val Parameters.<o:p>

There were functions which doesn’t had a return type<o:p>

Functions which doesn’t return anything.<o:p>

<o:p> 

I hope that after reading this article, Readers will have a better understanding of Methods, Functions, and Subroutines in VB.NET.<o:p>

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>METHODS:

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Methods contain the executable statements of a program.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>There are two types of methods: subroutines and functions.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>For purpose of this article I will be sticking to Subroutines and functions and By Val and by ref Parameters.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>More about other method types such as Shared, Non shared, External, Overridable Methods can be found http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbls7/html/vblrfvbspec7_1_6_2.asp

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Functions and subroutines are the most basic building block you can use to organize your code.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Ideally, each function or subroutine will perform a distinct, logical task.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>By breaking your code down into procedures, you not only simplify your life, but you also make it easier to organize your code into classes and step into the world of object-oriented programming.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Functions are very similar to subroutines—their syntax is nearly identical, and they can both perform the same actions. Functions, however, return a value to the code that called it.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>But Most of us stop thinking after this. At least I did.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Returning a value is not the only difference between a Function and Subroutine.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Interesting …Hmmm…..read further.<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> 

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>I am going to use ILDASM to show that the Vb.net Subroutines are more efficient and performance beneficial than VB.net functions.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>I made an ASP.net project with Vb.net.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Here are two methods I made (one Subroutine and one Function)

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>    Public Sub TESTSUB ()

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>   End Sub

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>   Public Function TESTFUC()

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>   End Function

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>And for those of you who are C# fans, here is a sample C# function.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>public void TestCSharp()

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>{

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>}

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Now look at their MSIL (Please read http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpconmsildisassemblerildasmexe.asp , if you are new to ILDASM and MSIL)

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>.method public instance void  TESTSUB() cil managed

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>{

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  // Code size       3 (0x3)

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  .maxstack  8

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0000:  nop

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0001:  nop

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0002:  ret

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>} // end of method WebForm1::TESTSUB

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>.method public instance object  TESTFUC() cil managed

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>{

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  // Code size       3 (0x3)

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  .maxstack  1

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  .locals init ([0] object TESTFUC)

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0000:  nop

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0001:  ldloc.0

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0002:  ret

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>} // end of method WebForm1::TESTFUC

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>.method public hidebysig instance void  TestCSharp () cil managed

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>{

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  // Code size       2 (0x2)

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  .maxstack  0

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0000:  nop

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0001:  ret

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>} // end of method Class1:: TestCSharp

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Look at these MSIL instructions, C# has the cleanest implementation of a void method; the size of the evaluation stack is 0 and there is nothing except a mandatory nop, followed by return.<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> 

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>VB.NET sub is next, but mysteriously it has a .maxstack 8 statement at the top, what are they thinking?? Although that does not mean the run time evaluation stack is 8, the statement is used only for static analyzer by the verifier during the assembly loading phase. I would be glad if any of you can help me understanding why the Sub has a .maxstack 8.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>VB.NET function with no explicit return type is the ugliest. To preserve generosity, the all mighty object is used as the base type so that even if you return an arraylist of arraylists of arraylists of... is fine.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>So I reached to following conclusion (Please correct me if you feel something is incorrect)

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>1. VB.Net Subroutine is faster than Function

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>2. You should never use a Function without a return type, it won’t give you a compilation error but it hinders the performance.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Now lets<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> explore Byval and Byref

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Now let’s Move on to have a closer look at By Val and By Ref parameters. If you are interested in other parameter types well read this

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>When you pass a variable By Val a new instance of the variable is created and given to the routine being called.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Any changes made to the value of this variable have no effect on the value of the original variable that was passed in.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>If you instead pass in a variable ByRef, any changes you make to this variable also change its value outside the routine

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Lets go more deep……

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>In VB 6, if the parameters to a function or subroutine were not explicitly prefaced with the ByVal or ByRef keywords, arguments were passed to that routine by reference, and modifications made to the argument in the function or subroutine were reflected in the variable's value once control returned to the calling routine.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>In VB .NET, on the other hand, if the ByRef or By Val keyword is not used in a parameter, the argument is passed to the routine by value, and modifications made to the argument in the function or subroutine are discarded once control returns to the calling program.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>There is some confusion regarding which one is faster.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Some books say By Val is much better because ByRef is higher overhead because the data must be copied to the sub or function and then copied back once the sub or function completes.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>This is Incorrect. To prove this. Lets again take help of ILDASM.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>    Public Sub TEST_SUB_BY_VAL(ByVal i As Integer)

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>    End Sub

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>    Public Sub TEST_SUB_BY_REF(ByRef i As Integer)

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>    End Sub

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>MSIL is like this

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>.method public instance void  TEST_SUB_BY_VAL(int32 i) cil managed

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>{

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  // Code size       3 (0x3)

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  .maxstack  8

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0000:  nop

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0001:  nop

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0002:  ret

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>} // end of method WebForm1::TEST_SUB_BY_VAL

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>.method public instance void  TEST_SUB_BY_REF(int32& i) cil managed

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>{

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  // Code size       3 (0x3)

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  .maxstack  8

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0000:  nop

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0001:  nop

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>  IL_0002:  ret

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>} // end of method WebForm1::TEST_SUB_BY_REF

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>The statement “ByVal is much better because ByRef is higher overhead because the data must be copied to the sub or function and then copied back once the sub or function completes.” is somewhat true in case of .NET V 1.0.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>In .NET V1.1, The address of the ByRef variable(s) are copied at the call to the subprogram.  Then the subprogram uses/modifies the variable that is in one, and only location, in memory.  At the exit from the subprogram there is no copying back of the ByRef parameters.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>So to reiterate…

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>When to USE BY VAL

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>By Val (by value) means that the called routine uses the value purely for input, to start a "one way" conversation. If A calls B (ByVal x), x becomes a temporary variable in B, using what A passed as a starting value. When B ends, so does x (and any changes made to it).

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>ByRef (by reference) means that the argument is a reference to the actual calling variable. If A calls B (ByRef x), B can change x and the changes are reflected in A. So, MySub4 (ByRef) changes g; MySub5 (ByVal) does not.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Using ByVal allows programmers to treat routines as "black boxes" that don't need to be opened. Parameters passed this way are "safe". If you don't plan to change the value of a parameter in your routine, you should use ByVal. It allows you to keep a smaller scope, and it saves maintenance time later when you have to read a routine to see if it affects the calling routine.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>If you need to send a value back to the outer routine, consider using a Function instead of a Sub with ByRef.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>When to Use ByRef?

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>There are some cases where ByRef is preferable. First, reference variable types (e.g. Forms, Textboxes, etc.) can't be processed with the ByVal model. ByVal t As Textbox doesn't cause a syntax error, but it gets processed as if ByRef was used (changes to t affect the actual textbox, not an in-memory copy). Specifying ByRef is clearer in this case. Arrays are also always treated as ByRef.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2> <FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>I am not a guru in Dotnet, This is my first article.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Any suggestion, Correction or feedback is most welcomed.

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Thanks and regards,

<FONT face=Verdana,Arial,Helvetica,Geneva,Sans-Serif size=2>Raj

devgeekraj@gmail.com

 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Dev Geek Raj
India India
Rituraj Singh is working as a Technical consultant for a company in Mumbai, India.

He writes, Drinks, eats and sleep code. At His company in INDIA, he writes code in Asp.NET (Both VB and C#).

He is also involved in AJAX approach and has implement that successfully in various projects

He has also worked on automation of Daily Builds using CC.NET, NUNIT, NDOC, and NAnt.

He was fortunate enough to work on two types of Source Safe systems VSS (with Source offsite) and subversion .

He love to read tech articles and Play around with new Technologies.

He hardly gets any free time ,But when He does ,He loves to play chess with his brother,watch Movies and Hangout with friends.

If you have any Queries in above technologies, he would be more than happy to help you.
The best way to get a hold of him is via email .

devgeekraj@gmail.com


You may also be interested in...

Comments and Discussions

 
GeneralPerformance Differences with Subroutines, Functions, ByVal, and ByRef Pin
SomeBeach22-Oct-08 6:01
memberSomeBeach22-Oct-08 6:01 
QuestionWhat Microsoft has to say Pin
Dan Pupek16-May-06 10:07
memberDan Pupek16-May-06 10:07 
GeneralNice article Pin
SURREN10-Mar-06 0:31
memberSURREN10-Mar-06 0:31 
GeneralRe: Nice article Pin
shaul_ahuva10-Mar-06 2:19
membershaul_ahuva10-Mar-06 2:19 
GeneralRe: Nice article Pin
Dev Geek Raj10-Mar-06 2:55
memberDev Geek Raj10-Mar-06 2:55 
Generalbyval / byref difference Pin
Steve Hansen10-Mar-06 0:18
memberSteve Hansen10-Mar-06 0:18 
GeneralRe: byval / byref difference Pin
Dev Geek Raj10-Mar-06 1:41
memberDev Geek Raj10-Mar-06 1:41 
AnswerRe: byval / byref difference Pin
Steve Hansen10-Mar-06 1:54
memberSteve Hansen10-Mar-06 1:54 
GeneralRe: byval / byref difference Pin
Dev Geek Raj10-Mar-06 2:33
memberDev Geek Raj10-Mar-06 2:33 
Questionadvanced ... ? Pin
v2.09-Mar-06 23:05
memberv2.09-Mar-06 23:05 
AnswerRe: advanced ... ? Pin
Dev Geek Raj10-Mar-06 0:39
memberDev Geek Raj10-Mar-06 0:39 
GeneralRe: advanced ... ? Pin
v2.010-Mar-06 0:41
memberv2.010-Mar-06 0:41 
AnswerRe: advanced ... ? Pin
ilikc0de12-Jun-06 12:51
memberilikc0de12-Jun-06 12:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170424.1 | Last Updated 10 Mar 2006
Article Copyright 2006 by Dev Geek Raj
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid