wyrd Posted June 25, 2003 Posted June 25, 2003 If I understand .NET correctly, all classes are passed by reference unless you specify otherwise. Quote Gamer extraordinaire. Programmer wannabe.
aewarnick Posted June 25, 2003 Author Posted June 25, 2003 What about a struct? And how would I go about not passing something by reference? Quote C#
JABE Posted June 25, 2003 Posted June 25, 2003 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. Quote
aewarnick Posted June 25, 2003 Author Posted June 25, 2003 In c# I have ref to pass by reference but notinng like ByVal...that I know of. Quote C#
JABE Posted June 25, 2003 Posted June 25, 2003 In C#, parameters are passed-by-value unless ref is specified. Quote
Heiko Posted June 25, 2003 Posted June 25, 2003 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. Quote .nerd
JABE Posted June 25, 2003 Posted June 25, 2003 > 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 Quote
*Gurus* divil Posted June 25, 2003 *Gurus* Posted June 25, 2003 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#). Quote MVP, Visual Developer - .NET Now you see why evil will always triumph - because good is dumb. My free .NET Windows Forms Controls and Articles
JABE Posted June 25, 2003 Posted June 25, 2003 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. Quote
aewarnick Posted June 25, 2003 Author Posted June 25, 2003 I am assuming that a struct is always passed by ref, correct? (Without getting into any technicalities speaking) Quote C#
*Gurus* divil Posted June 25, 2003 *Gurus* Posted June 25, 2003 ...Primitive data types and structures are passed by value unless you specify otherwise... Quote MVP, Visual Developer - .NET Now you see why evil will always triumph - because good is dumb. My free .NET Windows Forms Controls and Articles
aewarnick Posted June 25, 2003 Author Posted June 25, 2003 Sorry divil. I didn't read it with my brain the first time...It didn't register in sector "common sense". Thanks. Quote C#
JABE Posted June 25, 2003 Posted June 25, 2003 What if a struct has a member w/c is of non-primitive type? Will the struct still be passed by value? Quote
*Gurus* divil Posted June 25, 2003 *Gurus* Posted June 25, 2003 Yes, but that member will still just point to the same object. Quote MVP, Visual Developer - .NET Now you see why evil will always triumph - because good is dumb. My free .NET Windows Forms Controls and Articles
JABE Posted June 25, 2003 Posted June 25, 2003 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. Quote
wyrd Posted June 25, 2003 Posted June 25, 2003 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 Quote Gamer extraordinaire. Programmer wannabe.
JABE Posted June 26, 2003 Posted June 26, 2003 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. Quote
wyrd Posted June 26, 2003 Posted June 26, 2003 *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. Quote Gamer extraordinaire. Programmer wannabe.
JABE Posted June 26, 2003 Posted June 26, 2003 *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. Quote
*Gurus* divil Posted June 26, 2003 *Gurus* Posted June 26, 2003 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 Quote MVP, Visual Developer - .NET Now you see why evil will always triumph - because good is dumb. My free .NET Windows Forms Controls and Articles
JABE Posted June 27, 2003 Posted June 27, 2003 > 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. Quote
wyrd Posted June 27, 2003 Posted June 27, 2003 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. Quote Gamer extraordinaire. Programmer wannabe.
*Experts* Nerseus Posted June 27, 2003 *Experts* Posted June 27, 2003 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 Quote "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
wyrd Posted June 27, 2003 Posted June 27, 2003 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. Quote Gamer extraordinaire. Programmer wannabe.
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.