Domanda

Un po 'poco chiaro a me sono riferimenti (puntatori?) Per le classi in VB.NET. La domanda che sto per chiedere può essere risolta da un po 'di prove, ma mi chiedevo se qualcuno potesse inviare una spiegazione decente (o link, troppo).

Se si crea una classe:

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

E poi una classe che in realtà utilizza questa classe come una proprietà:

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

E poi usare in questo modo:

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

Ora la funzione BooleanCheck restituirà sempre true, anche se è passato il riferimento alla nuova UsingClass di classe "per valore", non con riferimento. Quindi, una copia della classe non è fatta, ma la myReference variabile locale in UsingClass fa ancora riferimento / punti alla Reference proprietà a RuntimeOrSomething.

Come può essere spiegato con eleganza?

È stato utile?

Soluzione

A punti di riferimento a un'istanza di un oggetto, non è un'istanza di un oggetto. Fare una copia delle istruzioni per l'oggetto non crea un altro oggetto, si crea un altro riferimento che punta anche allo stesso oggetto.

Altri suggerimenti

Non riesco a mettere molto tempo in questa risposta ora - digitando su un treno con un bambino sul mio ginocchio - ma ho un paio di articoli che potrebbero aiutare. Sono scritti su C #, ma lo stesso vale per VB.NET:

MSDN :

  

Se si passa un argomento variabile   valore utilizzando la parola chiave ByVal, il   procedura non può modificare la variabile   si. Tuttavia, se l'argomento è un   tipo di riferimento, è possibile modificare la   membri dell'oggetto a cui   punti, anche se non si può sostituire   l'oggetto stesso. In particolare, è   può modificare i membri dell'oggetto.   Ad esempio, se l'argomento è un   variabile di matrice, non è possibile assegnare un   nuovo array ad esso, ma si può cambiare   uno o più dei suoi elementi. Il   elementi modificati sono riflesse nel   variabile di matrice sottostante nel   chiamando codice.

Dal momento che il ReferenceClass è un tipo di riferimento, se si passa ByVal, non è possibile sostituirlo con un nuovo oggetto (che non si fa), ma si può impazzire con le sue interiora (che si fa). Se si passa ByRef o ByVal, gingillarsi con le sue interiora sarà ancora "influenzare" l'oggetto originale (poiché non v'è sempre e solo un oggetto in memoria).

In questa riga:

Dim tempClass as New UsingClass(Reference)

l'oggetto a cui si riferisce la proprietà Reference viene passato "per valore", ma non è il oggetto che viene copiato, è il di riferimento a quell'oggetto che viene copiato (cioè MyReference e tempClass.Reference sono due "puntatori" distinti allo stesso oggetto. Si potrebbe quindi fare tempClass.Reference = new ReferenceClass e poi MyReference e tempClass.Reference sono ancora due "puntatori" distinti, ma ora ogni punto a due oggetti diversi.

Quando si passa classi ByVal / byref in VB.NET è possibile pensare ad esso in termini di programmazione C e puntatori in modo tale che -

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

Prendere le stringhe come esempio

' 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

Come detto sopra, l'impostazione di una variabile oggetto uguale ad un altro solo imposta il "puntatore" a un'istanza dello stesso oggetto in memoria, se si desidera clonare l'aspetto oggetto in che implementa l'interfaccia ICloneable con qualcosa di simile

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

Con e quando l'oggetto di allocazione utilizzare il metodo clone

Dim tempClass as ReferenceClass = Reference.Clone
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top