Question

Les références (pointeurs?) À VB.NET sont un peu peu difficiles. La question que je suis sur le point de poser peut être répondue par un peu de test, mais je me demandais si quelqu'un pouvait afficher une explication (ou des liens aussi).

Si vous créez une 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

Et puis une classe qui utilise réellement cette classe comme propriété:

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

Et puis utilisez-le comme ceci:

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

Maintenant la fonction BooleanCheck reviendra toujours true, même si la référence est transmise à la nouvelle classe UsingClass "par valeur", non par référence. Donc une copie de la classe n'est pas faite, mais la variable locale myReference dans UsingClass toujours références / pointes à la propriété Reference dans RuntimeOrSomething.

Comment cela peut-il être expliqué avec élégance?

Était-ce utile?

La solution

Une référence pointe vers une instance d'un objet, ce n'est pas une instance d'un objet. Faire une copie des directions vers l'objet ne crée pas un autre objet, il crée une autre référence qui pointe également vers le même objet.

Autres conseils

Je ne peux pas consacrer beaucoup de temps à cette réponse maintenant - taper dans un train avec un tout-petit sur mon genou - mais j'ai quelques articles qui pourraient aider. Ils sont écrits sur C #, mais il en va de même pour VB.NET:

De MSDN:

Si vous transmettez un argument de variable par valeur à l'aide du mot clé ByVal, la procédure ne peut pas modifier la variable elle-même. Cependant, si l'argument est un type de référence, vous pouvez modifier les membres de l'objet auxquels il pointe, même si vous ne pouvez pas remplacer l'objet lui-même. En particulier, vous pouvez modifier les membres de l'objet. Par exemple, si l'argument est une variable de tableau, vous ne pouvez pas y attribuer un nouveau tableau, mais que vous pouvez modifier un ou plusieurs de ses éléments. Les éléments modifiés sont reflétés dans la variable de tableau sous-jacente dans le code d'appel.

Étant donné que votre référence est un type de référence, si vous le transmettez par ByVal, vous ne pouvez pas le remplacer par un nouvel objet (que vous ne le faites pas), mais vous pouvez fouiller avec ses entrailles (ce que vous faites). Que vous passiez ByRef ou Byval, se détendre avec ses entrailles "affectera toujours" l'objet d'origine (car il n'y a jamais un seul objet en mémoire).

Dans cette ligne:

Dim tempClass as New UsingClass(Reference)

l'objet mentionné par le Reference la propriété est transmise "par valeur", mais ce n'est pas le objet qui est copié, C'est le référence à cet objet qui est copié (ie myreference et tempclass. tempClass.Reference = new ReferenceClass Et puis MyReference et TempClass.Reference sont encore deux "pointeurs" distincts, mais maintenant ils pointent chacun vers deux objets différents.

Lorsque vous passez des classes BYVAL / BYREF dans VB.NET, il est possible de le penser en termes de programmation C et de pointeurs de telle sorte que -

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

Prenez des cordes comme exemple

' 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

Comme dit ci-dessus, définir une variable d'objet égale à un autre définit simplement le "pointeur" sur une instance du même objet en mémoire, si vous souhaitez cloner l'objet, envisagez d'implémenter l'interface iclonable avec quelque chose comme

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

Avec et lorsque vous allocation de l'objet utilisez la méthode de clone

Dim tempClass as ReferenceClass = Reference.Clone
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top