Solved

VB.NET return by reference?

Posted on 2003-11-20
32
2,589 Views
Last Modified: 2007-12-19
If I create a class and return a member of that class in a public function, does VB.NET do it by reference or value by default?
0
Comment
Question by:PLavelle
  • 9
  • 5
  • 4
  • +7
32 Comments
 
LVL 4

Expert Comment

by:brother7
ID: 9790278
I believe if the class member returned is a reference type (for example, an object, string or array), it is returned by reference.  If it's a value type (for example, a numeric primitive or structure), it's returned by value.
0
 
LVL 7

Expert Comment

by:Z_Beeblebrox
ID: 9790334
Hi,

A return value in all languages that I know of including .Net is by value and this is the only logical way it could be. This includes reference types. What this means is that using a function, you cannot change which object a member points to if it is a reference type, nor can you change its value if it is a value type. Of course, you can changes the data within the object that is pointed to if it is a reference type.

Zaphod.
0
 
LVL 10

Expert Comment

by:GoodJun
ID: 9790717
Just as all the parameters passed in .net, by default it is byval
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 9791017
Are talking about that annoying problem that VB6 had where it wouldn't update a value passed in as a parameter?

If so, then Micro$oft has fixed that with VB.NET.  Try this:

   Class has one property:  Test As String

   Private Sub TestStuff()

      test.Test = "This is a test"

      ModifyString(test.Test)

      MsgBox(test.Test)

   End Sub

   Private Sub ModifyString(ByRef s As String)

      s = "Test"

   End Sub

After the call to ModifyString, the value in the message box will be 'Test'.  In VB6, it would still be the original value.
0
 

Author Comment

by:PLavelle
ID: 9791237
No just VB.NET, I think brother7 is right but I wanted to see something to prove it.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 9791370
No, he is not completely correct.  

If you change all the strings in the above example to integers, and pass it to the ModifyString method, the value will be changed.  So, you see all ByRef parameters can be modified by a method if they are properties of a class.

It also applies if you use structures.
0
 
LVL 9

Expert Comment

by:malharone
ID: 9792001
the learnedone is correct ...

it's the custom property of the class
e.g.
public writeonly property password as string
 set (byval value as string)             '<--------- these are the ones that HAVE TO be byval. they can't be by ref.

  end set
end property

UNLESS you have
public password as string  '<--- in this case you lose the "writeonly" part of the property block

so you'd have to do this -- the traditional way


public function setPassword(byref password_ as string)  '<--- this would a reference
  password=password_
end function


and primitive types eventhough specified using byref, will always be passed as byval ... UNLESS you create a wrapper class ... e.g. if you want to pass an integer by ref... you'd have to do something like the following

public class MyInteger
  public value as Integer

  public sub new(optional byval value_ as Integer)
       value=value_
  end sub

end class

so .. asume i have a new object

public sub test()
   dim myInt as new MyInteger(100)
   msgbox(myInt.value)  '<---- 100
   changeInteger(myInt)
   msgbox(myInt.value)   '<---- 50

   dim x as integer=100
   msgbox(x) '<-- 100
   changeInteger(x)
   msgbox(x)  '<--- 100
end sub

public sub changeInteger(byref myInt as MyInteger)
   myInt.value=50
end sub

public sub changeInteger2(byref intVal as Integer)
    intVal=50
end sub
0
 
LVL 9

Expert Comment

by:malharone
ID: 9792004
oops ... i meant

public sub test()
   dim myInt as new MyInteger(100)
   msgbox(myInt.value)  '<---- 100
   changeInteger(myInt)
   msgbox(myInt.value)   '<---- 50

   dim x as integer=100
   msgbox(x) '<-- 100
   changeInteger2(x)         '<----------------------- this is changeInteger2 (NOT changeInteger)
   msgbox(x)  '<--- 100
end sub
0
 
LVL 5

Expert Comment

by:kuzco
ID: 9795249
As GoodJun said, all parameters are passed by value as default. So if objects are passed as parameters to methods, then a reference to the memory location in the heap will be created in the stack and since the reference of the object which is a value is only passed to the method, the object changes wont be reflected globally.

If you change the value of the reference itself, then it wont reflect globally unless ByRef is used.

Class has one property:  Test As String

   Private Sub TestStuff()

      test.Test = "This is a test"

      ModifyString(test.Test)

      MsgBox(test.Test)

   End Sub

   Private Sub ModifyString(ByRef s As String)

      s = "Test"

   End Sub

This will clear up all the basic doubts on how parameters both Value and Reference type work in .NET !

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vclrfpassingmethodparameters.asp

Hope this helps.
0
 
LVL 4

Expert Comment

by:brother7
ID: 9795375
The author's original question refers to the return value of a Function, not a Sub.
0
 
LVL 5

Expert Comment

by:kuzco
ID: 9796159
ahem return value of a function is exactly similar to how parameters to the function is passed. You could imagine a return value as a out param only that out params are passed ByRef by default which is the only difference from the return values which are passed as ByVal only.

Objects are reference types. So when you return an object from a function, the actual object's location in the heap is referenced and stored in a variable present in the stack. This value is what will be returned as the result of the function to the calling function. So you could say that all return values from functions are by default ByVal.
0
 
LVL 10

Expert Comment

by:GoodJun
ID: 9797930
Kuzco, you did good.
0
 
LVL 5

Expert Comment

by:mondayblueboy
ID: 9797937
PLavelle,

You meant, "Return by reference" or "Pass by reference" or “Return reference type”?

From what I know, C++ has the "Returning by Reference" features, and it's somewhat obscure because it allows using a function call on the left side of the equal sign.

Returning by reference sample:
==================================
[C++]

int x = 0;
int& ReturningByRef();  // function declaration

int main()
{
   ReturningByRef() = 100;  // function call on left side
   cout << "x=" << x << endl;
   return 0;
}

int& ReturningByRef()
{
   return x;
}

The output from the program, x = 100
==================================

This kind of feature is not supported by VB.NET and C#.
0
 
LVL 5

Expert Comment

by:mondayblueboy
ID: 9797944
brother7,

I agree with you, I hope the following quick sample can help to describe better for "Returning Reference Type".

Module Module1

    Private x As String = "Initial Value"
    Private i As Integer

    Sub Main()
        x = ReturningString()
        If TypeOf x Is String Then
            Console.WriteLine("yes x is a string")
        End If
        i = ReturningInteger()
        'If TypeOf i Is Integer Then
        '    Console.WriteLine("yes i is an integer")
        'End If
    End Sub

    Private Function ReturningString() As String
        Return x
    End Function

    Private Function ReturningInteger() As String
        Return x
    End Function

End Module

If I remove the commented lines, I got compile error message: "error BC30021: 'TypeOf ... Is' requires its left operand to have a reference type, but this operand has the value type 'Integer'."

I think the message tells everything..
0
 

Author Comment

by:PLavelle
ID: 9798055
I am talking stictly about returning by reference in VB.NET. I know if C++ you can specify the return type as a pointer to an object, but does VB.NET always return a copy of the object or does it sometimes return some kind of pointer to the object if it is not a primitive type.
0
 
LVL 10

Expert Comment

by:GoodJun
ID: 9798193
That message didn't tell it is byval or byref, it only tells that String is a reference type and the type of operator needs a reference type.
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 5

Expert Comment

by:mondayblueboy
ID: 9798275
Well, if I change to,

Module Module1

    Private x As String = "Initial Value"
    Private o As Object

    Sub Main()
        x = ReturningString()
        If TypeOf x Is String Then
            Console.WriteLine("yes x is a string")
        End If

        o = ReturningInteger()
        If TypeOf o Is Integer Then
            Console.WriteLine("yes o is an integer")
        End If
    End Sub

    Private Function ReturningString() As String
        Return x
    End Function

    Private Function ReturningInteger() As Integer
        Return x
    End Function

End Module

It is compile successfully. Because the integer is being boxed to a reference-type of object. By knowing the difference between value-type and reference-type, it should be clear by know.

Please read this:
http://www.vbdotnetheaven.com/Code/Jun2003/2034.asp
0
 
LVL 10

Expert Comment

by:GoodJun
ID: 9798297
Let's make sure that we all have the same definition of byref/byval for reference type.
1. no matter byval or byref, the reference type is in the heap and there is only one instance.
2. byref, the pointer itself is passed. No second location in stack is created.
3. byval, the pointer is copied and passed byval. a 2nd location in stack is created to point to the ONLY one object in the heap


When a function return a object, (byval or byref), we can all change the actual object in the heap. The question is how many point locations are created in the stack during the calling of the function. If only one, then by ref, if two, then by val.

I didn't see any official documentation says it byval or byref. (why?  it doesn't matter it is byval or byref anyway. the behavior is identical). I just Assuming that it follows the same way a parameters is passed bydefault.

function test() as class1
dim o as new class1
return o
end function

I assume, o is created and pointer is copied to the stack when it is returned. The 1st pointer is destroyed afer the return.
0
 
LVL 8

Expert Comment

by:zlatev
ID: 9798369
By default CLR assumes that all parameters are passed ByVal. When you pass parameter ByRef, actually you pass Referrence (pointer) ByVal.
If parameter is instance of a value type (e.g. System.Int32), a referrence to a COPY of this instance is passed.
If parameter is instance of a referrent type (e.g. System.String, System.Array, System.Object, System.Exception etc.), a referrence to the instance itself is passed.

Difference between byref and out parameters (out parameter is the value you return from function) is that out parameters are not needed to be initialized, but byref parameters MUST.
0
 
LVL 5

Expert Comment

by:mondayblueboy
ID: 9798906
I think the question does not concern about behind the scene when calling a function, but rather what is the final result. Merely saying that by declare a function to return a reference-type means a number of bytes associated with the type are allocated on the heap. Accessing the return value means working with a reference to that object instead of directly with the bits (as with value-types).
0
 
LVL 10

Expert Comment

by:GoodJun
ID: 9799128
No. The definition is as my previous comments. It is the definition by microsoft. You can see this from the link provided by kuzco, even though it talks about parameter not the function return.
0
 
LVL 4

Accepted Solution

by:
brother7 earned 375 total points
ID: 9799911
OK, I think I have the definitive answer, as it relates to Function return values in VB.NET.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vbtchmicrosoftvisualbasicnetinternals.asp

I quote from the section 'Storage Consumption - Copies of Variables':

"A variable is copied when it is assigned to another variable, when it is passed to a procedure ByVal, and when it is returned from a Function procedure. Visual Basic performs shallow copies, which means that it copies only the contents of a variable, and not any data to which those contents might refer. Therefore, a copy of a reference type variable duplicates only the four-byte pointer, and both the original and the copy point to the same data in memory. A copy of a value type variable replicates its entire contents in each new instance."

If I understand this correctly, it means that a Function's return value is always by value (for a value type, it's the actual value; for a reference type, it's the value of the four-byte pointer).
Hopefully, this is the clarity that the poster is looking for.
0
 

Author Comment

by:PLavelle
ID: 9800253
Thats exactly what I was looking for.
0
 
LVL 5

Expert Comment

by:mondayblueboy
ID: 9801461
Good job brother7!
0
 
LVL 4

Expert Comment

by:brother7
ID: 9801548
Aw, shucks... it was nuthin' (blush).
Is it time to divvy up the points?
0
 
LVL 5

Assisted Solution

by:kuzco
kuzco earned 125 total points
ID: 9801710
hey wasn't that the same thing i mentioned in my last post ?! hmm ... Didn't dig up this article from MSDN though to prove the fact but i knew i was right !

If you'd ask me, any function should always return variables by value only, in .NET. Logically, for a reference type, the reference pointer is in the stack of the method accessing the object. Now, if it is not an out param, then the object pointer value in the local stack will be returned by value and then the stack corresponding to that method will be destroyed. The caller function shall copy the value of the pointer obtained from the other function and shall assign the value of the pointer to the variable in its function, thereby creating an effect of maintaining the same object reference. You should understand that, this is the primary reason that objects were designed to be placed in the heap in .NET so that only object references are created and destroyed in the stacks and so the source object remains the same maintaining consistency in object handling.

Ok ! Anyway if you've understood what i'm trying to say, then well and good :)
0
 
LVL 5

Expert Comment

by:mondayblueboy
ID: 9803277
Hey, wait a minute. I didn't read the article until I realized the quote is not in the link given by brother7 - Visual Basic .NET Internals? Isn't that should be:

Using Classes and Structures in Visual Basic .NET
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vbtchuseclassstruct.asp

Let me re-quote,

>> A variable is copied when it is assigned to another variable,
>> when it is passed to a procedure ByVal, and when it is returned
>> from a Function procedure.
That's fine, but it didn't mention about "return from a function procedure ByVal", only "when passed to a procedure ByVal".

>> Visual Basic performs shallow copies, which means that it copies
>> only the contents of a variable, and not any data to which those
>> contents might refer.

And read this part carefully,
>> Therefore, a copy of a reference type variable duplicates only the four-byte
>> pointer, and both "the original and the copy point" to the same data in memory.
Is this the definition of returning from a function procedure ByVal??

And this,
>> A copy of a value type variable replicates its entire contents in each new instance.

Anyone..
0
 
LVL 5

Expert Comment

by:mondayblueboy
ID: 9803284
0
 
LVL 5

Expert Comment

by:mondayblueboy
ID: 9803317
And brother7, thanks for the direction. You da man!
0
 
LVL 5

Expert Comment

by:mondayblueboy
ID: 9803355
And don't forget the original question, PLavelle has rectified it to:

>> but does VB.NET always return a copy of the object or
>> does it sometimes return some kind of pointer to the
>> object if it is not a primitive type.
0
 

Author Comment

by:PLavelle
ID: 9804148
Ok, a great discussion by everyone but after reviewing I think I have to give the answer to brother7 and some points to kuzco for clarifying how it works.
0
 

Expert Comment

by:scotthagie
ID: 13947800
Interesting thread. It's a serious oversite that you can't return a vlue byref in VB.Net, but can in C#. One of the few times I have regretted my choice of languages in .Net. I guess I will have to pass an input parameter as byref, and change that, but that is very inelegant.
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Normally the drop down box control found in the .Net framework tools is able to select just one data and value at a time, which is displayed on the text area.   But what if you want to have multiple values to be selected in the drop down box? As …
This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now