Pergunta

Um pouco claro para mim são referências (ponteiros?) Para aulas no vb.net. A pergunta que estou prestes a fazer pode ser respondida por um pouco de teste, mas eu queria saber se alguém poderia postar uma explicação decente (ou links também).

Se você criar uma 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 então uma classe que realmente usa esta classe como uma propriedade:

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 então use assim:

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

Agora a função BooleanCheck sempre voltará true, mesmo que a referência seja passada para a nova classe UsingClass "Por valor", não por referência. Portanto, uma cópia da classe não é feita, mas a variável local myReference dentro UsingClass ainda referências/pontos para a propriedade Reference dentro RuntimeOrSomething.

Como isso pode ser explicado elegantemente?

Foi útil?

Solução

Uma referência aponta para uma instância de um objeto, não é uma instância de um objeto. Fazer uma cópia das instruções para o objeto não cria outro objeto, ele cria outra referência que também aponta para o mesmo objeto.

Outras dicas

Não posso dedicar muito tempo a essa resposta agora - digitando um trem com uma criança no meu joelho - mas tenho alguns artigos que podem ajudar. Eles estão escritos sobre C#, mas o mesmo se aplica ao VB.NET:

A partir de Msdn:

Se você passar em um argumento variável por valor usando a palavra -chave BYVAL, o procedimento não poderá modificar a própria variável. No entanto, se o argumento for um tipo de referência, você poderá modificar os membros do objeto ao qual ele aponta, mesmo que você não possa substituir o próprio objeto. Em particular, você pode modificar os membros do objeto. Por exemplo, se o argumento for uma variável de matriz, você não poderá atribuir uma nova matriz, mas poderá alterar um ou mais de seus elementos. Os elementos alterados são refletidos na variável de matriz subjacente no código de chamada.

Como o seu referenceClass é um tipo de referência, se você o passar pelo BYVAL, não poderá substituí -lo por um novo objeto (o que você não faz), mas poderá se movimentar com suas entranhas (o que você faz). Se você passa por Byref ou Byval, misturando com suas entranhas ainda "afetará" o objeto original (já que existe apenas um objeto na memória).

Nesta linha:

Dim tempClass as New UsingClass(Reference)

o objeto referido pelo Reference a propriedade é aprovada "por valor", mas não é o objeto que é copiado, é o referência para esse objeto que é copiado (isto tempClass.Reference = new ReferenceClass E então MyReference e TempClass.Reference ainda são dois "ponteiros" distintos, mas agora cada um aponta para dois objetos diferentes.

Ao passar as aulas BYVAL/BYREF em VB.NET, é possível pensar nisso em termos de programação e indicadores de tal forma que -

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

Tome cordas como exemplo

' 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 dito acima, definir uma variável de objeto igual a outro apenas define o "ponteiro" para uma instância do mesmo objeto na memória, se você quiser clonar o objeto, veja a implementação da interface iCloneable com algo como

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

Com e quando você alocando o objeto, use o método clone

Dim tempClass as ReferenceClass = Reference.Clone
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top