Frage

Etwas unklar für mich sind Referenzen (Zeiger?) Auf Klassen in VB.NET. Die Frage, die ich stellen werde, kann durch ein wenig Test beantwortet werden, aber ich habe mich gefragt, ob jemand eine anständige Erklärung (oder auch Links) veröffentlichen könnte.

Wenn Sie eine Klasse erstellen:

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

Und dann eine Klasse, die diese Klasse tatsächlich als Eigenschaft verwendet:

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

Und dann benutze es so:

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

Jetzt die Funktion BooleanCheck wird immer zurückkehren true, obwohl die Referenz an die neue Klasse übergeben wird UsingClass "nach Wert", nicht durch Referenz. Es wird also nicht eine Kopie der Klasse gemacht, sondern die lokale Variable myReference in UsingClass immer noch Referenzen/Punkte auf die Eigenschaft Reference in RuntimeOrSomething.

Wie kann dies elegant erklärt werden?

War es hilfreich?

Lösung

Eine Referenz zeigt auf eine Instanz eines Objekts, es ist keine Instanz eines Objekts. Wenn Sie eine Kopie der Anweisungen zum Objekt erstellen, wird kein anderes Objekt erstellt, sondern eine weitere Referenz erstellt, die auch auf dasselbe Objekt zeigt.

Andere Tipps

Ich kann jetzt nicht viel Zeit in diese Antwort aufnehmen - in einem Zug mit einem Kleinkind auf meinem Knie einzugeben -, aber ich habe ein paar Artikel, die helfen könnten. Sie sind über C#geschrieben, aber dasselbe gilt für VB.NET:

Aus Msdn:

Wenn Sie ein variables Argument per Wert unter Verwendung des BYVAL -Schlüsselworts übergeben, kann die Prozedur die Variable selbst nicht ändern. Wenn das Argument jedoch ein Referenztyp ist, können Sie die Mitglieder des Objekts ändern, auf das es zeigt, obwohl Sie das Objekt selbst nicht ersetzen können. Insbesondere können Sie die Mitglieder des Objekts ändern. Wenn das Argument beispielsweise eine Array -Variable ist, können Sie ihm kein neues Array zuweisen, aber Sie können eine oder mehrere seiner Elemente ändern. Die geänderten Elemente spiegeln sich in der zugrunde liegenden Array -Variablen im aufrufenden Code wider.

Da Ihre ReferenceClass ein Referenztyp ist, können Sie ihn nicht durch ein neues Objekt ersetzen (das Sie nicht tun), aber Sie können mit seinen Innereien herumspielen (was Sie tun). Unabhängig davon, ob Sie an Byref oder Byval bestehen, wird es immer noch das ursprüngliche Objekt "beeinflussen" (da es immer nur ein Objekt im Speicher gibt).

In dieser Zeile:

Dim tempClass as New UsingClass(Reference)

das von dem verwiesene Objekt Reference Eigentum wird "nach Wert" verabschiedet, aber es ist nicht das Objekt das wird kopiert, es ist das Hinweis zu diesem Objekt, das kopiert wird (dh MyReference und Tempclass.Reference sind zwei verschiedene "Zeiger" auf dasselbe Objekt. Sie könnten dann tun tempClass.Reference = new ReferenceClass Und dann sind MyReference und Tempcass.Reference immer noch zwei verschiedene "Zeiger", aber jetzt zeigen sie jeweils zwei verschiedene Objekte.

Wenn Sie Klassen byval/byRef in vb.net bestanden haben

ByVal = passing arguments via - a pointer 
ByRef = passing arguments via - a pointer to a pointer

Nehmen Sie als Beispiel Saiten

' 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

Wie oben erwähnt, legt das Festlegen einer Objektvariablen gleich einem anderen den "Zeiger" auf eine Instanz desselben Objekts im Speicher fest, wenn Sie das Objekt klonen möchten, um die iClonable Schnittstelle mit so etwas wie zu implementieren

Public Function Clone() As Object Implements ICloneable.Clone
Return Me.MemberwiseClone()
End Function

Mit und wenn Sie zu Zuteilung das Objekt verwenden die Klonmethode

Dim tempClass as ReferenceClass = Reference.Clone
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top