Referenzen in vb.net
-
23-08-2019 - |
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?
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