References in VB.NET

痴心易碎 提交于 2019-12-04 01:56:08

问题


Somewhat unclear to me are references (pointers?) to classes in VB.NET. The question I am about to ask can be answered by a little bit of testing, but I was wondering if anybody could post a decent explanation (or links, too).

If you create a class:

Public Class ReferenceClass

    Private myBooleanValue As Boolean = False
    Public Property BooleanValue As Boolean
        Get
            Return myBooleanValue
        End Get
        Set(value As Boolean)
            myBooleanValue = value
        End Set
    End Property

End Class

And then a class which actually uses this class as a property:

Public Class UsingClass

     Private myReference As ReferenceClass
     Public Property Reference As ReferenceClass
        Get
             return myReference
         End Get
         Set(value As ReferenceClass)
             myReference = value
         End Set
     End Property

     Public Sub New(ByVal Reference As ReferenceClass)
         myReference = Reference
     End Sub

End Class

And then use it like this:

Public Class RuntimeOrSomething

     Public Shared myReference As ReferenceClass
     Public Shared ReadOnly Property Reference As ReferenceClass
         Get
             If myReference Is Nothing Then myReference = new ReferenceClass()
             return myReference
         End Get
     End Property

     Public Shared Function BooleanCheck() As Boolean
         Reference.BooleanValue = True
         Dim tempClass As New UsingClass(Reference)
         tempClass.Reference.BooleanValue = False

         Return (tempClass.Reference.BooleanValue = Reference.BooleanValue)
     End Sub

     Public Shared Sub DoNothing()
          Reference.BooleanValue = True
          Dim someBoolean As Boolean = BooleanCheck

          ' Now Reference.Booleanvalue is "False"
     End Sub

End Class

Now the function BooleanCheck will always return true, even though the reference is passed to the new class UsingClass "by value", not by reference. So a copy of the class is not made, but the local variable myReference in UsingClass still references/points to the property Reference in RuntimeOrSomething.

How can this be explained elegantly?


回答1:


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.




回答2:


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:

  • Reference types and value types
  • Parameter passing in .NET



回答3:


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).




回答4:


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.




回答5:


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



回答6:


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


来源:https://stackoverflow.com/questions/389426/references-in-vb-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!