I can't put much time into this answer now - typing on a train with a toddler on my knee - but I have a couple of articles which might help. They're written about C#, but the same applies to VB.NET:
A reference points to an instance of an object, it is not an instance of an object. Making a copy of the directions to the object does not create another object, it creates another reference that also points to the same object.
In this line:
Dim tempClass as New UsingClass(Reference)
the object referred to by the Reference
property is passed "by value", but it's not the object that is copied, it's the reference to that object that is copied (i.e. myReference and tempClass.Reference are two distinct "pointers" to the same object. You could then do tempClass.Reference = new ReferenceClass
and then myReference and tempClass.Reference are still two distinct "pointers", but now they each point to two different objects.
When passing classes byval/byref in VB.NET it is possible to think of it in terms of C programming and pointers such that -
ByVal = passing arguments via - a pointer ByRef = passing arguments via - a pointer to a pointer
Take strings as an example
' ByRef - modify str pointer to "point" to a new string Sub Test_Ref(ByRef str as string) str = "New String ByRef" End Sub ' ByVal - can't modify str pointer must return a (pointer to) new string Function Test_Val(ByVal str as String) as String return "New String ByVal" End Sub Sub Main() Dim strTest as String = "Hello World!" Console.WriteLine(strTest) Test_Ref(strTest) Console.WriteLine(strTest) Test_Val(strTest) Console.WriteLine(strTest) ' oops still pointing to same string strTest = Test_Val(strTest) Console.WriteLine(strTest) ' that's better :) End Sub
From msdn:
If you pass a variable argument by value using the ByVal keyword, the procedure cannot modify the variable itself. However, if the argument is a reference type, you can modify the members of the object to which it points, even though you cannot replace the object itself. In particular, you can modify the members of the object. For example, if the argument is an array variable, you cannot assign a new array to it, but you can change one or more of its elements. The changed elements are reflected in the underlying array variable in the calling code.
Since your ReferenceClass is a reference type, if you pass it ByVal, you can't replace it with a new object (which you don't), but you can muck around with its innards (which you do). Whether you pass ByRef or ByVal, mucking around with its innards will still "affect" the original object (since there is only ever one object in memory).
Like said above, setting a object variable equal to another just sets the "pointer" to an instance of the same object in memory, if you want to clone the object look at implementing the iCloneable interface with something like
Public Function Clone() As Object Implements ICloneable.Clone
Return Me.MemberwiseClone()
End Function
With and when you allocation the object use the clone method
Dim tempClass as ReferenceClass = Reference.Clone