Page 1 of 2 12 LastLast
Results 1 to 15 of 25
  1. #1
    3 Star Lounger
    Join Date
    Jul 2001
    Posts
    283
    Thanks
    0
    Thanked 0 Times in 0 Posts

    byVal vs. byRef (VB.NET)

    Can someone explain to me in what kind of real world situation that we need to use ByRef in passing an argument? I understand that ByRef changes the content of the argument when it is passed back to the calling procedure. I need an explanation on why we want (or not want) to do that.

    Thanks

  2. #2
    Plutonium Lounger
    Join Date
    Nov 2001
    Posts
    10,550
    Thanks
    0
    Thanked 7 Times in 7 Posts

    Re: byVal vs. byRef (VB.NET)

    You can use ByRef to allow a function to return more than one result.

    For example I had some code that parsed strings. It returned the current "segment" of the string and a pointer to the starting point in the string for the next iteration. One of these was the return value of the function and the other was returned in a ByRef argument.

    StuartR

  3. #3
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: byVal vs. byRef (VB.NET)

    I'm not a .NET user, but I've written thousands of lines (sigh) of VB 6 code and I have hardly ever used a ByVal argument. Arguments are ByRef by default and I understand they involve less "overhead" or something (i.e., they generally result in more efficient code).

    The main reason to make an argument ByVal is if the called procedure will be changing its value, the calling procedure will be continuing to use the passed variable after the called procedure is finished, and that continued use by the calling procedure should involve the variable with its original value (i.e. the value before the called procedure messed with it). Even in that circumstance you can pass the argument ByRef if you set up the called procedure in a way that the passed variable ends up unchanged (e.g., by having the called procedure assign its value to a 2nd variable and mess with the 2nd variable instead).

    As Stuart noted, ByRef arguments can be extremely useful because they can be output arguments as well as input arguments. Some ByRef arguments function solely as output arguments.

  4. #4
    3 Star Lounger
    Join Date
    Aug 2001
    Location
    Jeddah, Saudi Arabia
    Posts
    243
    Thanks
    0
    Thanked 1 Time in 1 Post

    Re: byVal vs. byRef (VB.NET)

    As is stated in the other posts, using ByRef allows a procedure, Sub or Function to modify the value of a passed parameter. .NET by default passes variables by value, ie, ByVal is the default. As a matter of good coding practise you should always specify ByVal or ByRef when declaring parameters to a procedure. To not do so can, and often does, introduce subtle bugs into programs.

    An example of ByRef usage could be the following. Imagine you have created a Function that populates a dataset from a database and you want to return the dataset, along with an indicator of success or failure to the calling program.

    Private Function GetMyDataset(DataSetToReturn as Dataset) As Boolean

    Attempt to fill the dataset

    If the database retrieval failed then
    DataSetToReturn = Nothing
    Return False
    Else
    Return True
    Endif

    This will compile and run fine (as long as no exceptions are thrown) but the calling program won't actually get the data in the dataset because the parameter is ByVal by default. You must declare the paramater as ByRef to allow the function to modify the parameter.

    In essence, when you pass a paramater by value the compiler creates a local copy when you call the procedure, this is achieved by either putting the actual value on the stack or putting a copy of the object into the local heap and a pointer to it on the stack (Yes I know this is not the complete picture because of Heap considerations but it's pretty much the truth). When the procedure returns to the calling program the stack pointers are modified so that the data put onto the stack is destroyed so any modifications that are made to it are lost. When you use ByRef a pointer to the paramater is put onto the stack and the compiler generates code to reference that data 'indirectly', ie, using the pointer so you are actually modifying the data in the caller.

    As for performance issues, depending on the parameter types and sizes ByVal and ByRef can be equally or unequally efficient.

    For calls to API functions, this is very important as a large number of API functions return data in parameters. In fact, in my experience with the programmers who work for me, this has been the number 1 problem (Marshalling is a close second) when calling API functions from .NET.

    I highly recommend the Microsoft Press book, Designing Enterprise Applications with Microsoft Visual Basic .NET by Robert Ian Oliver (ISBN 0-7356-1721-X) for people who want to call API functions from .NET along with a lot of other very useful information.

    Regards,
    Kevin Bell

  5. #5
    Platinum Lounger
    Join Date
    Nov 2001
    Location
    Melbourne, Victoria, Australia
    Posts
    5,016
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: byVal vs. byRef (VB.NET)

    Just to add to what st3333ve said, passing by reference is easier on overheads because it's only a reference (small pointer) that is passed across, rather than a second copy of whatever the variable happens to hold. The efficiency issue will depend very much on what the program does, but it's for this reason that arrays (potentially very large) can't be passed ByVal at all.

    I think that the ByRef default is a good idea, because generally, variables should be passed this way unless there's a particular reason for needing a second "working" copy. In C/C++ you can pass by ref and use a "constant qualifier" to ensure that the variable remains unaltered:

    FunctionName(myVariable const&);

    I've always wondered why VB didn't embrace this qualifier.

    Alan

  6. #6
    Gold Lounger
    Join Date
    Dec 2000
    Location
    New Hampshire, USA
    Posts
    3,386
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: byVal vs. byRef (VB.NET)

    In .NET, ByVal is more efficient.

    ByRef wrks differently than in VB 6.

    In .Net, when you say

    a = b

    You are not changing a independently of b.

    If then change a, that results in a change in b.

    Why?
    Because everything in .NET is an object.

    If you want to create a copy of b, then you have to use

    a.Clone = b

    Quite different than in VB.

  7. #7
    Gold Lounger
    Join Date
    Dec 2000
    Location
    New Hampshire, USA
    Posts
    3,386
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: byVal vs. byRef (VB.NET)

    ByRef works differently in .NET.

  8. #8
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: byVal vs. byRef (VB.NET)

    <img src=/S/blush.gif border=0 alt=blush width=15 height=15> Well, I noted I wasn't a .NET guy, but probably shouldn't have done such a fine job of demonstrating it!

    I get the feeling upgrading code from VB6 to .NET is likely to be a many-pots-of-coffee task.

  9. #9
    Plutonium Lounger
    Join Date
    Dec 2000
    Location
    Sacramento, California, USA
    Posts
    16,775
    Thanks
    0
    Thanked 1 Time in 1 Post

    Re: byVal vs. byRef (VB.NET)

    ByVal is the default in .Net.
    Charlotte

  10. #10
    Gold Lounger
    Join Date
    Dec 2000
    Location
    New Hampshire, USA
    Posts
    3,386
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: byVal vs. byRef (VB.NET)

    I get by on just OJ and water, each taken separately.

  11. #11
    Platinum Lounger
    Join Date
    Nov 2001
    Location
    Melbourne, Victoria, Australia
    Posts
    5,016
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: byVal vs. byRef (VB.NET)

    I'd add my <img src=/S/2cents.gif border=0 alt=2cents width=15 height=15> by saying that I'm entrenched in the traditions on non-.NET also.

    Alan

  12. #12
    Plutonium Lounger
    Join Date
    Dec 2000
    Location
    Sacramento, California, USA
    Posts
    16,775
    Thanks
    0
    Thanked 1 Time in 1 Post

    Re: byVal vs. byRef (VB.NET)

    It isn't bad once you make the mental jump. I like it much better than either VBA or VB, but you have to get used to everything being an object., including things like a string variable. Once you DO get used to it, it makes a lot of sense. If you do it right, you tend to write much more loosely coupled code than in VB/VBA, and it's a dream for n-tier stuff. <img src=/S/thumbup.gif border=0 alt=thumbup width=15 height=15>
    Charlotte

  13. #13
    Platinum Lounger
    Join Date
    Nov 2001
    Location
    Melbourne, Victoria, Australia
    Posts
    5,016
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: byVal vs. byRef (VB.NET)

    I actually just had my first serious squizz at a VB.NET article, since I'll eventually be forced to move out of the dark ages. <img src=/S/sad.gif border=0 alt=sad width=15 height=15> First impressions are that it's moved closer to the C++ OOP that I'm most comfortable with, so that's probably a good sign (for me). It also looks like even the primative types (integers for instance) have been wrapped up as objects, which goes even beyond Java's object orientation as I understand it.

    It looks like "real" inheritance has been addressed (although not the multiple inheritance of C++ ??) , try/catch exception handling, method overloading (and operator overloading ??) and other aspects o polymorphism. This looks pleasingly like pretty familiar territory. <img src=/S/smile.gif border=0 alt=smile width=15 height=15>

    Do you have any recommended links to summary overview of the new features?

    cheers
    Alan

  14. #14
    Plutonium Lounger
    Join Date
    Dec 2000
    Location
    Sacramento, California, USA
    Posts
    16,775
    Thanks
    0
    Thanked 1 Time in 1 Post

    Re: byVal vs. byRef (VB.NET)

    *All* types are objects and you handle them via their methods and properties. It is object oriented but there are some limits to this version, at least. Overloads are wonderful and there is no longer a real need for optional parameters, although they're still supported. However, if you DO use Optional, all arguments have to be declared as optional in the routine declaration. I"m not sure I understand why they bothered to keep it, except maybe for backward compatibility. The hardest thing for me to adapt to has been the lack of user-defined types to pass multiple pieces of information at once. You simply don't do it that way in .Net.

    At the moment, I'm busily writing unit tests for various data entities, and I absolutely LOVE that! Testing the logic before writing code to implement it is wild. Creating tests to uncover bugs in created code is way easier than trying to figure out where an error or weird result came from, and you can fix the bugs before you actually have to use the code that contains them. <img src=/S/groovin.gif border=0 alt=groovin width=21 height=21>

    Oops, sorry, I hit the wrong button. I can't suggest any links because the differences are so vast, I wouldn't know where to start. I think most of us trying to make the transition, try books, cbt, magazines, forums, etc., and pick it up as we go along. I found that working in it is the best way to really learn it. Of course, it helps to have someone around who knows more about it than you do .... <img src=/S/grin.gif border=0 alt=grin width=15 height=15>
    Charlotte

  15. #15
    3 Star Lounger
    Join Date
    Aug 2001
    Location
    Jeddah, Saudi Arabia
    Posts
    243
    Thanks
    0
    Thanked 1 Time in 1 Post

    Re: byVal vs. byRef (VB.NET)

    The hardest thing for me to adapt to has been the lack of user-defined types to pass multiple pieces of information at once. You simply don't do it that way in .Net.

    You can still define user types or Structures as they are known in VB .NET and pass them as parameters. In fact, Structures are like mini-classes and can contain public methods and can even implement interfaces, however structures lack other OOP functionality that make classes so versatile. Funnily enough for this thread, the key difference between structures and classes is that structures are value types and classes are reference types.

    HOWEVER, and here's the rub. The CLR does allow a value type to be treated as a reference type. This is because of the System.Object and something called boxing. All objects inherit from System.Object which itself is a reference type.

    Imagine where a function,for example Console.Writeline, lacks a specific overload for, lets say, a Date type (which is a value type) but has an overload for an Object type parameter. If it were possible to coerce the Date type into an Object the function would work just fine.

    What actually happens is that a wrapper for the value type, in this case a Date is created to make it look like a reference type. This wrapper is allocated on the heap and the value type's value is copied into the wrapper (so a copy is stored in the heap). The system marks the wrapper to identify it as a value type masquerading as a reference type. This process of moving a value type onto the heap and providing a reference type wrapper is known as boxing. The reverse process is known as unboxing. Essentially, the process of boxing and unboxing allows any type to be treated as an object.

    The caveat to all of this is performance. Loading value types onto the heap and generating a wrapper doesn't come without cost. Not understanding the impact of boxing and when it occurs can introduce performance bugs.

    Consider this code:

    Sub Main()
    Dim i as Integer = 5
    Console.Writeline("{0}, {1}", i, i)

    ' Manually box the integer
    Dim o As Object = i
    Console.Writeline("{0}, "{1}", o, o)
    End Sub

    The first Console.Writeline boxes the integer twice. A more efficient approach is to manually box the integer only once as shown.

    BUT, manual boxing is not always more efficient. There is a perfromance difference if you're dealing with an immutable value type (Date) versus a mutable type (Integer or Double). If the type to be boxed is immutable you're better off just passing the variable to a method and allowing the runtime to box it. You'll see a benefit to manually boxing your variables if you need to pass them repeatedly to functions that would otherwise result in boxing operations each time the variable was marshaled.

    Back to structures. Consider this example of a Point type structure to store coordinate pairs but we want to sort these pairs in order of distance from the origin (coordinates x=0, y=0). The calculation itself is pretty simple but we don't want to implement a sort algorithm with all of the other logic. The solution can be found in the ICompareable interface. Thus:

    Public Structue MyPoiint
    Implements IComparable
    Public x as Integer
    Public y as Integer

    Public Function CompareTo(obj as Object) As Integer _
    Implements IComparable.CompareTo

    Dim pt as MyPoint = CType(obj, MyPoint)
    Dim d1 as Double = (x^2) + (y^2)
    Dim d2 as Double = (pt.x^2) +(pt.y^2)

    Return CInt(d1 - d2)

    End Function

    End Structure

    We can now compare two MyPoint structures using the IComparable interface. Now let's say we have an array of MyPoint structures.

    Dim pts() as New MyPoint(100)

    To sort it we only need to use the System.Array.Sort method.

    System.Array.Sort(pts)

    Simple but using the IComparable interface when implemented on a structure would cause a lot of boxing and unboxing. In fact, with this example the boxing and unboxing overhead could very easily make a reference type a far better solution. In other words, because of the boxing overhead a class-based implementation would be far more efficient if you expect the IComparable interface to be used frequently.

    And we all thought programming was simple.

    Regards,
    Kevin Bell

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •