3 Stimmen

Referenzen in VB.NET

Etwas unklar sind mir Verweise (Pointers?) auf Klassen in VB.NET. Die Frage, die ich stellen möchte, kann durch ein wenig Testen beantwortet werden, aber ich frage mich, ob jemand eine anständige Erklärung (oder Links, auch) posten 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 verwenden Sie 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 nach Referenz. Es wird also nicht eine Kopie der Klasse erstellt, sondern die lokale Variable myReference en UsingClass verweist noch auf die Eigenschaft Reference en RuntimeOrSomething .

Wie lässt sich das elegant erklären?

8voto

Gene Roberts Punkte 2162

Eine Referenz verweist auf eine Instanz eines Objekts, sie ist keine Instanz eines Objekts. Wenn Sie eine Kopie der Anweisungen für das Objekt erstellen, wird kein weiteres Objekt erzeugt, sondern eine weitere Referenz, die ebenfalls auf dasselbe Objekt verweist.

7voto

Jon Skeet Punkte 1325502

Ich kann jetzt nicht viel Zeit in diese Antwort investieren - ich tippe im Zug mit einem Kleinkind auf dem Knie - aber ich habe ein paar Artikel, die vielleicht helfen. Sie sind über C# geschrieben, aber das gleiche gilt für VB.NET:

2voto

Jeremy Frey Punkte 2310

Desde MSDN :

Wenn Sie ein variables Argument mit Wert mit dem Schlüsselwort ByVal übergeben, wird die Prozedur die Variable nicht verändern selbst nicht ändern. Ist das Argument jedoch ein Referenztyp ist, können Sie die Mitglieder des Objekts, auf das es verweist, ändern, auch wenn Sie nicht das Objekt selbst nicht ersetzen. Insbesondere müssen Sie können Sie die Mitglieder des Objekts ändern. Wenn das Argument zum Beispiel eine Array-Variable ist, können Sie ihm kein neues Array zuweisen, aber Sie können die eines oder mehrere seiner Elemente ändern. Die geänderten Elemente werden in der zugrunde liegenden Array-Variable im aufrufenden Code widergespiegelt.

Da Ihre ReferenceClass ein Referenztyp ist, können Sie sie nicht durch ein neues Objekt ersetzen (was Sie auch nicht tun), wenn Sie ihr ByVal übergeben, aber Sie können mit ihren Innereien herumspielen (was Sie tun). Unabhängig davon, ob Sie ByRef oder ByVal übergeben, wirkt sich das Herumpfuschen an den Innereien immer noch auf das ursprüngliche Objekt aus (da es immer nur ein Objekt im Speicher gibt).

1voto

chyne Punkte 682

In dieser Zeile:

Dim tempClass as New UsingClass(Reference)

das Objekt, auf das sich die Reference Eigenschaft wird "nach Wert" übergeben, aber es ist nicht die Objekt die kopiert wird, es ist die Referenz zu diesem Objekt, das kopiert wird (d.h. myReference und tempClass.Reference sind zwei verschiedene "Zeiger" auf dasselbe Objekt. Sie könnten dann tempClass.Reference = new ReferenceClass und dann sind myReference und tempClass.Reference immer noch zwei verschiedene "Zeiger", aber jetzt zeigen sie jeweils auf zwei verschiedene Objekte.

1voto

user21826 Punkte 3374

Bei der Übergabe von Klassen perval/byref in VB.NET ist es möglich, sich dies in Anlehnung an die C-Programmierung und Zeiger so vorzustellen, dass -

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

Beispiel: Zeichenketten

' 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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X