Вопрос

Мне несколько неясно, есть ли ссылки (указатели?) К классам в vb.net. На вопрос, который я собираюсь задать, можно ответить на небольшое тестирование, но мне было интересно, может ли кто -нибудь опубликовать достойное объяснение (или ссылки тоже).

Если вы создаете класс:

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

А потом класс, который фактически использует этот класс в качестве свойства:

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

А потом используйте это так:

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

Теперь функция BooleanCheck всегда вернется true, хотя ссылка передается в новый класс UsingClass «По значению», а не по ссылке. Таким образом, копия класса не сделана, а локальная переменная myReference в UsingClass все еще ссылки/указывают на собственность Reference в RuntimeOrSomething.

Как это можно объяснить элегантно?

Это было полезно?

Решение

Ссылка указывает на экземпляр объекта, это не экземпляр объекта. Создание копии указаний в объект не создает другого объекта, он создает другую ссылку, которая также указывает на тот же объект.

Другие советы

Сейчас я не могу потратить много времени на этот ответ - набрать поезд с малышом на колене - но у меня есть пара статей, которые могут помочь. Они написаны о C#, но то же самое относится и к VB.net:

Из MSDN:

Если вы передаете аргумент переменной путем значения, используя ключевое слово Byval, процедура не может изменить саму переменную. Однако, если аргумент является ссылочным типом, вы можете изменить членов объекта, на который он указывает, даже если вы не можете заменить сам объект. В частности, вы можете изменить членов объекта. Например, если аргумент является переменной массива, вы не можете присвоить ему новый массив, но вы можете изменить один или несколько его элементов. Измененные элементы отражаются в основной переменной массива в вызовом коде.

Поскольку ваш ссылки является ссылочным типом, если вы передаете его Byval, вы не можете заменить его новым объектом (которого вы не делаете), но вы можете разбить его внутренностями (что вы делаете). Независимо от того, проходите ли вы ByRef или Byval, пронзительство с его внутренностями все еще «повлияет» на исходный объект (поскольку в памяти есть только один объект).

В этой линии:

Dim tempClass as New UsingClass(Reference)

объект, на который упоминается Reference собственность передается «стоимостью», но это не объект это скопировано, это ссылка к этому объекту, который скопирован (т. Е. MyReference и TempClass.Reference - это два различных «указателя» для одного и того же объекта. Вы можете тогда сделать tempClass.Reference = new ReferenceClass И затем MyReference и Tempclass.Reference все еще являются двумя различными «указателями», но теперь каждый указывает на два разных объекта.

При прохождении классов Byval/Byref в vb.net можно подумать об этом с точки зрения программирования C и указателей, таких как -

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

Принять струны в качестве примера

' 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

Как сказано выше, настройка переменной объекта, равная другой, просто устанавливает «указатель» на экземпляр одного и того же объекта в памяти, если вы хотите клонировать объект, посмотрите на реализацию интерфейса Iclonable с чем -то вроде

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

С и когда вы распределяете, объект использует метод клона

Dim tempClass as ReferenceClass = Reference.Clone
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top