none
ByRef VS ByVal

    Question

  • Hi Guyz I want to know That either ByRef is better or ByVal

    Can You please help me!

    In VB Programming while assigning an object to a variable this assignment is mostly ByRef some time like ValueType

    I want that while assigning Object it should be assigned as ByVal Not ByRef

    Can You Please help me!


    ---------------------Do the Impossible--------------------- Great Software at http://atosoft.webs.com/

    Wednesday, May 15, 2013 5:50 AM

Answers

  • Neither is 'better' - they do different things.

    To understand the difference it is important to appreciate that, for an object, the variable being passed is already a reference.  That means that the difference is between whether what you do in the sub affects the variable (eg = New makes the variable point to a new object) or the object (such as changing an object property, which does not affect what the variable points to).

    For a reference variable passed ByVal:
        Changes made to the variable do not affect the original argument
        Changes made to the object it refers to do affect the original object
    For a reference variable passed ByRef:
        Changes made to the variable do affect the original argument
        Changes made to the object it refers to do affect the original object

    Wednesday, May 15, 2013 6:32 AM

All replies

  • Neither is 'better' - they do different things.

    To understand the difference it is important to appreciate that, for an object, the variable being passed is already a reference.  That means that the difference is between whether what you do in the sub affects the variable (eg = New makes the variable point to a new object) or the object (such as changing an object property, which does not affect what the variable points to).

    For a reference variable passed ByVal:
        Changes made to the variable do not affect the original argument
        Changes made to the object it refers to do affect the original object
    For a reference variable passed ByRef:
        Changes made to the variable do affect the original argument
        Changes made to the object it refers to do affect the original object

    Wednesday, May 15, 2013 6:32 AM
  • It is quite simple. 

    In value types a value is passes, in reference types (the most situations) a reference is passed.

    If you pass byval you pass the reference (the address) of the object. If you pass byref you pass the reference plus an extra reference.

    Take for instance that you don't want to use a function but a Sub and want to change the value in the Sub (be aware this is old style programming) then you can do.

    Sub X(byref A as String)

    If you do then in the sub.

    A  = "NaxAlpha" then the result will be that A in the passed value will be changed. Otherwise nothing changes in the original value. Be aware that a string is a special kind of reference type.

    Normally and with good programming ByRef is seldom used. 

    Keep in mind ByRef cost always a little bit more memory.

      


    Success
    Cor

    Wednesday, May 15, 2013 6:34 AM
  • It just depends.

    ByVal: It will pass the structure-based type as a "Copy" action, which WON'T effect the original value.

    ByRef: It will pass the ADDRESS of a certain type, so any changes to the value will be also applied to the original one.

    If you wanna change some part of a class, use either ByVal or ByRef is OK. But there's A HUGE DIFFERENCE:

    ByVal for a reference type, it will COPY a reference address to the value, but that's ALSO referring, so there's no difference between ByVal and ByRef, for the sake of value, if pointing to a reference type.

    Compared with this, if you wanna change the whole class value or change the structure-based type value, you HAVE TO USE ByRef instead of ByVal.

    Check this example:

    Imports System.Text.RegularExpressions
     
    Module Module1
     
        Sub ChangeObject(ByVal obj)
            obj = Nothing   'For a reference type, will it effect the original one??
        End Sub
        Sub ChangeObject2(ByRef obj)
            obj = Nothing   'For a reference type, will it effect the original one??
        End Sub
     
        Sub Main()
            Dim obj As New Object
            Console.WriteLine("Null or Not?" & (obj Is Nothing).ToString)
            ChangeObject(obj)
            Console.WriteLine("Null or Not?" & (obj Is Nothing).ToString)
            ChangeObject2(obj)
            Console.WriteLine("Null or Not?" & (obj Is Nothing).ToString)
        End Sub
     
    End Module
    

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    Wednesday, May 15, 2013 6:39 AM
  • PV,

    With Option Strict On your code won't compile.

    Be aware you are using the object as a value type. 

    With a Byval of a reference type then the members of an object are change.

    Module Module1
        Sub ChangeObject(ByVal obj As X)
            obj.Y = "NaxAlphaByVal"   'For a reference type, will it effect the original one??
        End Sub
        Sub ChangeObject2(ByRef obj As X)
            obj.Y = "NaxAlphaByRef"   'For a reference type, will it effect the original one??
        End Sub
    
        Sub Main()
            Dim obj As New X
            obj.Y = "Begin"
            Console.WriteLine(obj.Y)
            ChangeObject(obj)
            Console.WriteLine(obj.Y)
            ChangeObject2(obj)
            Console.WriteLine(obj.Y)
            Console.ReadKey()
        End Sub
        Public Class X
            Public Property Y As String
        End Class
    End Module


    Success
    Cor

    Wednesday, May 15, 2013 7:02 AM
  • @With a Byval of a reference type then the members of an object are change.

    In fact it won't effect on the whole instance, you can check my sample to see the result——Is "obj" null or not? Think it why??? ;)

    Bcoz:

    For a reference type in ByVal, it will copy the address into the function itself as a parameter, so the "copied" address will also point to the same object instance, any part member changes to the obj will effect the obj itself, but if you assign another thing "such as 'Nothing'" to the object, you've changed the "copied address" to "Nothing", so the original won't be effected.

    For "ByRef", it totally refer the original reference address, so it just means you've directly assigned "Nothing" to object.


    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    Wednesday, May 15, 2013 7:07 AM
  • I wrote that in your sample you threat the obj exactly in the meaning of a value type. A value type has no properties only methods beside the default value.

    Or in other words, your obj is no reference type, look and try the sample I created.

    Be aware that every value type is still derived from the class System.object.

     

    Success
    Cor

    Wednesday, May 15, 2013 7:16 AM
  • Hi Cor Ligthert,

    But why do you say "obj" is a value type? It should be reference type but used as a "value", and if you apply "ByVal", this means we only copy the address of the object instance in its inner function. So the inner's change won't effect the outer one;)


    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    Wednesday, May 15, 2013 7:29 AM
  • actually i also donno the difference between this 2 untill now.

    but wadever it is. use byval to play safe.

    Wednesday, May 15, 2013 8:14 AM
  • PVM

    Your program is not correct, it misses in the signature the type which is used. Put for that Option Strict On in top of your code.

    Then look at this.

    http://msdn.microsoft.com/en-us/library/system.object.aspx

    Derived classes can be value types or derived types. But an object direct instanced from the class object is for sure no reference type in the way like is meant in the context bellow. 

    http://msdn.microsoft.com/en-us/library/t63sy5hs(v=vs.110).aspx

    Object itself has no public properties like you can see in the first link. 



    Success
    Cor



    Wednesday, May 15, 2013 8:38 AM
  • Thanks, plz check this, it goes the same result;)

    Sub ChangeObject(ByVal obj As Object)
            obj = Nothing   'For a reference type, will it effect the original one??
        End Sub
        Sub ChangeObject2(ByRef obj As Object)
            obj = Nothing   'For a reference type, will it effect the original one??
        End Sub

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    Wednesday, May 15, 2013 8:42 AM
  • Thanks, plz check this, it goes the same result;)

    Sub ChangeObject(ByVal obj As Object)
            obj = Nothing   'For a reference type, will it effect the original one??
        End Sub
        Sub ChangeObject2(ByRef obj As Object)
            obj = Nothing   'For a reference type, will it effect the original one??
        End Sub

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    Yes I know but you set the Object itself to nothing, not a reference from object (if you would have cast it to a reference type you would have seen that the result is different).

    I'm not aware by the way what you want to proof by this. Read the links I've provided by you. 



    Success
    Cor

    Wednesday, May 15, 2013 8:48 AM
  • Wow Cool

    I Know this difference but thanks for clearing my conceptThe thing I want to ask is that For example I have any Object

    Dim x as MyObject

    And I have a collection of Object like

    Dim y as New List(Of MyObject)

    I Use y.Add(x)

    I have Changed Properties of x and Then I did y.Add(x)

    But When I checked Y There are 2 Objects in Y but They Are absolutely same. I want that I add Object Should be ByRef. I Think That If I Implement ICloneable in MyObject Class then It may be Work. Can You More Clearify


    ---------------------Do the Impossible--------------------- Great Software at http://atosoft.webs.com/

    Wednesday, May 15, 2013 9:10 AM
  • Wow Cool

    I Know this difference but thanks for clearing my conceptThe thing I want to ask is that For example I have any Object

    Dim x as MyObject

    And I have a collection of Object like

    Dim y as New List(Of MyObject)

    I Use y.Add(x)

    I have Changed Properties of x and Then I did y.Add(x)

    But When I checked Y There are 2 Objects in Y but They Are absolutely same. I want that I add Object Should be ByRef. I Think That If I Implement ICloneable in MyObject Class then It may be Work. Can You More Clearify


    ---------------------Do the Impossible--------------------- Great Software at http://atosoft.webs.com/

    But this is not related to byref or byval in any way. 

    It is related to the concept of what programming with objects means. 

    (programming with references to objects). 

    If you want to have cleared this problem from you, then make a new question handling it in this thread would only confuse others. Mark then a whatever reply which fits the best as answer in this thread as answer. I would suggest to take your last reply because otherwise I'm sure it will confuse others even who find this even more.

     


    Success
    Cor


    Wednesday, May 15, 2013 9:17 AM
  • Hi Cor;)

    That's what I wanna tell the user how to correctly use "ByVal" and "ByRef". Bcoz I find many customers or newbies will think "ClassType-based" object or related to this doesn't need ByRef, in fact they are wrong.

    Again:

    1) To change part of a reference object instance, ByVal can work, ByRef can work, too.

    2) To change the whole instance (I mean make the outer instance variable effected by the function's inner variable), you must use ByRef for an ABSOLUTE ADDRESS REFERENCE instead of using ByVal.


    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    Wednesday, May 15, 2013 9:17 AM
  • Maybe we misunderstand each other. 

    But the only thing which happens different at the end of a method when arguments are passed by ref is that the used senders address of the arguments are with ByRef replaced by the ByRef reference value. 

    Therefore if an object is created new or is set to nothing, the byref value will have the new or a nothing value which is created.

    Members are in no way affected. This cannot be used to change a whole instance. Members are only affected if those are changed inside a method.  


    Success
    Cor


    Wednesday, May 15, 2013 9:32 AM
  • Cor;)

    But according to my test, you can see that ByRef will effect the original one, while ByRef won't;)


    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    Wednesday, May 15, 2013 9:46 AM
  • Yes because you have set the ByRef value to nothing meaning that it replaces the original reference. But that I wrote.

    Therefore if an object is created new or is set to nothing, the byref value will have the new or a nothing value which is created.

    Try the sample I made.


    Success
    Cor



    Wednesday, May 15, 2013 9:56 AM
  • I haven't read all of the posts, but the mechanism that passes a parameter to a method is virtually identical whether or not you use ByRef or ByVal.  The difference lies in how the passed value is treated once the value is passed to a method, whether or not is treated directly as a structured value, or as a pointer to a structured value.

    An additional behavioral difference can be observed depending whether or not the variable being passed is a reference type or a value type.  To understand the differences in behavior and treatment, you need to understand how variables are stored. 

    Value Types:  Value Types are generally stored on the Stack, and are fixed in size.  When a Value Type is passed ByVal, a copy of the value on the Stack is made and passed to the method.  When a Value Type is passed ByRef, the method treats the passed value as a reference to the value's storage location on the Stack is passed.

    Reference Types:  Reference Types are stored on the Managed Heap, and are not always fixed in size.  The references to objects on the Heap are passed around as values, which stored on the Stack.  When a Reference Type is passed ByVal, a copy of the reference value on the Stack is made and passed to the method, where the value is treated as a reference to an object on the Heap.  When a Reference Type is passed ByRef, the method treats the passed value as a reference to the reference value stored on the Stack.

    It's the same mechanism in both cases, ByVal or ByRef, for both Value Types or Reference Types.  It is the difference in how the passed value is treated, and what the value on the Stack represents, that makes the differences.

    Hope this helps.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.com/


    • Edited by Rudedog2MVP Wednesday, May 15, 2013 5:32 PM
    Wednesday, May 15, 2013 2:06 PM
  • I have Changed Properties of x and Then I did y.Add(x)

    But When I checked Y There are 2 Objects in Y but They Are absolutely same.

    Then you need to clone the object when you get it from the list, This creates a new object.  Make the change to the clone and add the clone to end of the list.

    This has nothing to do with ByRef and ByVal.

    Wednesday, May 15, 2013 9:32 PM
  • NaxAlpha,

    In order to let you understand this deeply, Suppose we have this function, this has proved what I said above;)

    Imports System.Text.RegularExpressions
     
    Module Module1
     
        Class Student
            Public Property ID As Integer = 1
     
    #Region "Change Part of the class instance"
            Public Shared Sub ChangeID(ByVal stu As Student)
                stu.ID = 2      'Will this change?
            End Sub
            Public Shared Sub ChangeID2(ByRef stu As Student)
                stu.ID = 3      'Will this change?
            End Sub
    #End Region
     
    #Region "Change the whole instance"
            Public Shared Sub ChangeWhole(ByVal stu As Student)
                stu = Nothing     'Will this change?
            End Sub
            Public Shared Sub ChangeWhole2(ByRef stu As Student)
                stu = Nothing     'Will this change?
            End Sub
    #End Region
     
        End Class
     
        Sub Main()
            Dim stu As New Student
            Console.WriteLine("Null or Not?" & (stu Is Nothing).ToString)
            Student.ChangeWhole(stu)
            Console.WriteLine("Null or Not?" & (stu Is Nothing).ToString)
            Student.ChangeWhole2(stu)
            Console.WriteLine("Null or Not?" & (stu Is Nothing).ToString)
     
            stu = New Student
            Console.WriteLine("ID=" & stu.ID)
            Student.ChangeID(stu)
            Console.WriteLine("ID=" & stu.ID)
            Student.ChangeID2(stu)
            Console.WriteLine("ID=" & stu.ID)
        End Sub
     
    End Module
    

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report


    Thursday, May 16, 2013 2:05 AM