Pregunta

Un poco poco claro para mí hay referencias (¿Pointers?) A las clases en VB.NET. La pregunta que estoy a punto de hacer puede ser respondida por un poco de pruebas, pero me preguntaba si alguien podría publicar una explicación decente (o enlaces también).

Si crea una clase:

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

Y luego una clase que realmente usa esta clase como propiedad:

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

Y luego úsalo así:

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

Ahora la función BooleanCheck siempre volverá true, a pesar de que la referencia se pasa a la nueva clase UsingClass "Por valor", no por referencia. Entonces no se hace una copia de la clase, sino la variable local myReference en UsingClass aún referencias/puntos a la propiedad Reference en RuntimeOrSomething.

¿Cómo se puede explicar esto elegantemente?

¿Fue útil?

Solución

Una referencia apunta a una instancia de un objeto, no es una instancia de un objeto. Hacer una copia de las instrucciones al objeto no crea otro objeto, crea otra referencia que también apunta al mismo objeto.

Otros consejos

No puedo dedicar mucho tiempo a esta respuesta, escribiendo en un tren con un niño pequeño en la rodilla, pero tengo un par de artículos que podrían ayudar. Están escritos sobre C#, pero lo mismo se aplica a VB.NET:

De MSDN:

Si pasa un argumento variable por valor utilizando la palabra clave BYVAL, el procedimiento no puede modificar la variable misma. Sin embargo, si el argumento es un tipo de referencia, puede modificar los miembros del objeto al que señala, aunque no puede reemplazar el objeto en sí. En particular, puede modificar los miembros del objeto. Por ejemplo, si el argumento es una variable de matriz, no puede asignarle una nueva matriz, pero puede cambiar uno o más de sus elementos. Los elementos cambiados se reflejan en la variable de matriz subyacente en el código de llamada.

Dado que su referenceClass es un tipo de referencia, si lo pasa, no puede reemplazarlo con un nuevo objeto (que no lo hace), pero puede meterse con sus entrañas (lo que hace). Ya sea que pase Byref o Byval, se mueve con sus entrañas aún "afectará" al objeto original (ya que solo hay un objeto en la memoria).

En esta línea:

Dim tempClass as New UsingClass(Reference)

el objeto referido por el Reference la propiedad se pasa "por valor", pero no es el objeto que se copia, es el referencia a ese objeto que se copia (es decir, myreference y tempclass.reference son dos "punteros" distintos al mismo objeto. Entonces podrías hacer tempClass.Reference = new ReferenceClass Y luego MyReference y Tempclass.Reference siguen siendo dos "punteros" distintos, pero ahora cada uno apuntan a dos objetos diferentes.

Al pasar las clases BYVAL/BYREF en VB.NET, es posible pensar en ello en términos de programación C y punteros de tal manera que -

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

Tome cuerdas como ejemplo

' 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

Como se dijo anteriormente, establecer una variable de objeto igual a otra simplemente establece el "puntero" en una instancia del mismo objeto en la memoria, si desea clonar el objeto, busque la implementación de la interfaz iCLonable con algo como

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

Con y cuando se asigna el objeto usa el método clon

Dim tempClass as ReferenceClass = Reference.Clone
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top