Jump to content
Xtreme .Net Talk

Recommended Posts

Posted
If I understand .NET correctly, all classes are passed by reference unless you specify otherwise.
Gamer extraordinaire. Programmer wannabe.
Posted
In VB.NET, parameters are passed ByVal by default (i.e., when you specify no ByVal/ByRef modifier). This behavior was changed from VB where parms are ByRef unless you explicitly declare them as ByVal. All classes (both value types and ref types) passed as parameters are subject to this rule.
Posted

All parameters are passed by val?

 

I was under the impression that complex objects are always passed by ref. Otherwise the runtime environment would need to perform a deep copy clone of each object.

.nerd
Posted

> I was under the impression that complex objects are always passed by ref.

 

Nope. I suppose by "complex objects" you meant reference types, right? Remember that ref types are just references. When you pass a ref type, you are passing a pointer ref and not the object itself.

 

When you pass a ref type byval, it means the ref will point to the same object. Try following the sample code below; the comments should guide you:

 

Public Class Tester
   Public Shared Sub Main()
       Dim t As New Tester(), referenceType As New MyRefType()
       referenceType.RefTypeProp = 1
       t.PassByVal(referenceType)
       '-referenceType.RefTypeProp will revert to 1 since it was passed ByVal.
       MsgBox("After PassByVal: MyRefType.RefTypeProp = " & referenceType.RefTypeProp)
       t.PassByRef(referenceType)
       '-referenceType.RefTypeProp will become 2000 since it was passed ByRef.
       MsgBox("After PassByRef: MyRefType.RefTypeProp = " & referenceType.RefTypeProp)
   End Sub

   Public Sub PassByVal(ByVal refType As MyRefType)
       Dim newRefType As New MyRefType()
       newRefType.RefTypeProp = 1000
       refType = newRefType
       '-This assignment will NOT persist after method call because of ByVal.
       MsgBox("Inside PassByVal: MyRefType.RefTypeProp = " & refType.RefTypeProp)
   End Sub
   Public Sub PassByRef(ByRef reftype As MyRefType)
       Dim newRefType As New MyRefType()
       newRefType.RefTypeProp = 2000
       '-This assignment will persist after method call because of ByRef.
       reftype = newRefType
       MsgBox("Inside PassByRef: MyRefType.RefTypeProp = " & reftype.RefTypeProp)
   End Sub
End Class

Public Class MyRefType
   Private m_intRefTypeProp As Integer
   Public Property RefTypeProp() As Integer
       Get
           Return m_intRefTypeProp
       End Get
       Set(ByVal Value As Integer)
           m_intRefTypeProp = Value
       End Set
   End Property
End Class

  • *Gurus*
Posted
Everything except the primitive data types and structures is passed by reference whether you like it or not. Primitive data types and structures are passed by value unless you specify otherwise (ByRef in vb, ref in C#).

MVP, Visual Developer - .NET

 

Now you see why evil will always triumph - because good is dumb.

 

My free .NET Windows Forms Controls and Articles

Posted

When you pass ref types, it's true that a reference is passed, not the object itself. I think it's not the same w/ the notion of the "pass-by-reference" term as commonly used in the terminology of programming languages.

 

When a ref type is passed byval, the ref type will point to the same object it pointed to prior to the function call, even if w/in the function, the ref is set to another object.

 

When a ref type is passed byref and the it's set to another object w/in the function, the ref type will no longer point to the original object after the function call.

Posted
In my humble opinion, reference types can be passed to methods either byval or byref (just like primitive or value types). My code snippet above demonstrates this where I have virtually the same sub except that PassByVal accepts a ref type byval while PassByRef accepts a ref type byref. As can be seen, the two subs exhibit different results even though they are passed the one and the same ref type variable.
Posted

No offense ment JABE, but you're flat out wrong. Paremeters are not passed by value by default.

 

To repeat divil, all objects are passed by reference, everything else is by value (enums, structs, basic types). Remember that arrays and strings are objects. Structs and enums are value types (no, a struct is not an object in .NET.. do not treat it as such!)

 

Sometimes there's confusion as to how passing by reference works. Instead of trying to explain it myself, I'll just toss out a few links on the MSDN library which will hopefully shed some light on things.

 

General method ref/out index:

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

 

Passing by ref:

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

 

Passing by out:

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

 

Passing arrays by ref and out:

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

Gamer extraordinaire. Programmer wannabe.
Posted

No offense taken, wyrd :) I've read the links you posted. In vclrf.Refasp, it states "To use a ref parameter, the argument must explicitly be passed to the method as a ref argument." If you don't explicitly use ref, then the parm will be passed byval, hence byval is the default.

 

Have you tried running my code above? Pleeeeease do. If you'd like a C# version, I could rewrite it (as I feel that most of you are in C#). It will actually settle once and for all that reference types can be passed byval OR byref to methods, just like primitive types.

Posted

*rubs his head and takes an advil*

 

To quote divil...

 

Everything except the primitive data types and structures is passed by reference whether you like it or not.

Gamer extraordinaire. Programmer wannabe.
Posted

*raises hands in the air and sighs*

 

Okay, no point taking this any further. I'll just take it to my grave :)

 

I have high regard for divil as most of you do but between anyone's words and what really happens in code, I'll go with the latter.

  • *Gurus*
Posted

Ok, I'll bite. Jabe, your code is not demonstrating how objects are passed per se, it's merely demonstrating out parameters. You can change the original class passed in in the latter procedure because you're passing byref, but either way you're creating a new instance so it doesn't prove much.

 

Take the code below, which is a cut down version of your. No matter whether the instance is passed byval or byref, it's a class so you're only passing a reference and the number will always be changed.

 

Public Class Tester
   Public Shared Sub Main()
       Dim t As New Tester, referenceType As New MyRefType
       referenceType.RefTypeProp = 1

       MessageBox.Show("Starting Value: " & referenceType.RefTypeProp.ToString())
       t.PassByVal(referenceType)
       MessageBox.Show("After being passed by value: " & referenceType.RefTypeProp.ToString())

       t.PassByRef(referenceType)
       MessageBox.Show("After being passed by reference: " & referenceType.RefTypeProp.ToString())

       MessageBox.Show("It's always being changed because you're only passing a reference of the same object, NOT a copy of the object. Q.E.D.")
   End Sub

   Public Sub PassByVal(ByVal refType As MyRefType)
       refType.RefTypeProp = 1000
   End Sub

   Public Sub PassByRef(ByRef reftype As MyRefType)
       reftype.RefTypeProp = 9999
   End Sub
End Class

Public Class MyRefType
   Private m_intRefTypeProp As Integer
   Public Property RefTypeProp() As Integer
       Get
           Return m_intRefTypeProp
       End Get
       Set(ByVal Value As Integer)
           m_intRefTypeProp = Value
       End Set
   End Property
End Class

MVP, Visual Developer - .NET

 

Now you see why evil will always triumph - because good is dumb.

 

My free .NET Windows Forms Controls and Articles

Posted

> your code is not demonstrating how objects are passed per se,

Correct, divil, because that is not the intention of the code. That is why my first post opened up w/:

 

In VB.NET, parameters are passed ByVal by default (i.e., when you specify no ByVal/ByRef modifier).

 

I also posted

 

When you pass ref types, it's true that a reference is passed, not the object itself. I think it's not the same w/ the notion of the "pass-by-reference" term as commonly used in the terminology of programming languages.

 

because I was getting the impression that there's a brewing confusion in the discussion between objects passed per se and objects passed as parameters. Usually, the terms pass-by-ref and pass-by-val are associated to the discussion of function parameter-passing.

Posted

JABE:

 

Pass by reference is the correct term for objects. When you pass an object to a parameter, it passes the pointer to the value of the object. The parameter now "references" the value via a pointer. What else would you call it, pass by pointer? That's not common terminology.

Gamer extraordinaire. Programmer wannabe.
  • *Experts*
Posted

I hate to jump in so late, but saying that non-primitive types (classes, not structs) are always passed by ref is misleading. While it's true you can change the contents of a class when passed to a function, you can't change the original pointer to the class inside of the function. Meaning, a class variable (pointer) is passed by value - but just the pointer, not the contents of the class.

 

So, if you have the following:

// First, a function
private void Test(Class1 c)
{
   c = null;
}

Class1 c1 = new Class1();
// Call a function - pass by value
Test(c1);
// c1 is NOT null and the contents are still intact

 

If the function Test were to modify any member variables in Class1, they WOULD show up as changed outside of Test() since only the pointer (c1) is passed by value.

 

Structs are copied when passed to a function (unless ref is added to the parameter) so changing a value inside the function only changes that local copy. Of course, if the parameter is a class, you'll again be changing the actual class's contents.

 

-Nerseus

"I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
Posted

Nerseus:

I think your example is exactly why there's confusion on the topic. People do what you did above, or sometimes rather do c = new Class1(); and expect it to effect the original variable outside the method. I made this assumption and mistake once with strings.

 

Despite this, I'd still view it as passing by reference. ALL objects have their pointers passed, not the values themselves, hence passed by reference. I know it's a thin line here, but what else would you call it, pass by pointer? It's certainly not pass by value.

Gamer extraordinaire. Programmer wannabe.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...