Это из моего поста с другого форума, около двух лет назад. В то время как язык vb.net (в отличие от C #), понятия «тип значения и справочный тип» едины во всем .net, и примеры все еще сохраняются.
Также важно помнить, что в .net ВСЕ типы технически происходят от базового типа Object. Типы значений спроектированы так, чтобы они вели себя как таковые, но, в конце концов, они также наследуют функциональность базового типа Object.
A. Типы значений - это просто - они представляют отдельную область в памяти, где хранится дискретное ЗНАЧЕНИЕ. Типы значений имеют фиксированный размер памяти и хранятся в стеке, который представляет собой набор адресов фиксированного размера.
Когда вы делаете такое заявление:
Dim A as Integer
DIm B as Integer
A = 3
B = A
Вы сделали следующее:
- Создано 2 пробела в памяти, достаточных для хранения 32-битных целочисленных значений.
- Поместил значение 3 в выделенную память, назначенную A
- Поместил значение 3 в выделенную память, назначенную B, присвоив ему то же значение, что и в A.
Значение каждой переменной существует дискретно в каждой ячейке памяти.
B. Типы ссылок могут быть разных размеров. Следовательно, они не могут быть сохранены в «стеке» (помните, что стек представляет собой набор выделений памяти фиксированного размера?). Они хранятся в «Управляемой куче». Указатели (или «ссылки») на каждый элемент в управляемой куче поддерживаются в стеке (как адрес). Ваш код использует эти указатели в стеке для доступа к объектам, хранящимся в управляемой куче. Поэтому, когда ваш код использует ссылочную переменную, он на самом деле использует указатель (или «адрес» в ячейке памяти в управляемой куче).
Допустим, вы создали класс с именем clsPerson со строкой Property Person.Name
В этом случае, когда вы делаете заявление, подобное этому:
Dim p1 As clsPerson
p1 = New clsPerson
p1.Name = "Jim Morrison"
Dim p2 As Person
p2 = p1
В случае, указанном выше, свойство p1.Name вернет "Джим Моррисон", как и следовало ожидать. Свойство p2.Name ТАКЖЕ вернет "Джим Моррисон", как и следовало ожидать. Я считаю, что и p1, и p2 представляют разные адреса в стеке. Однако теперь, когда вы назначили p2 значение p1, и p1, и p2 указывают на ТО ЖЕ МЕСТО в управляемой куче.
Теперь рассмотрим эту ситуацию:
Dim p1 As clsPerson
Dim p2 As clsPerson
p1 = New clsPerson
p1.Name = "Jim Morrison"
p2 = p1
p2.Name = "Janis Joplin"
В этой ситуации вы создали один новый экземпляр класса «Человек» в управляемой куче с указателем p1 в стеке, который ссылается на объект, и снова присвоили свойству «Имя» экземпляра объекта значение «Джим Моррисон». , Затем вы создали еще один указатель p2 в стеке и указали его в том же адресе в управляемой куче, который указан в p1 (когда вы сделали присвоение p2 = p1).
А вот и поворот. Когда вы присваиваете свойству Name значение p2 значение «Janis Joplin», вы изменяете свойство Name для объекта REFERENCED на оба параметра p1 и p2, так что, если вы запустили следующий код:
MsgBox(P1.Name)
'Will return "Janis Joplin"
MsgBox(p2.Name)
'will ALSO return "Janis Joplin"Because both variables (Pointers on the Stack) reference the SAME OBJECT in memory (an Address on the Managed Heap).
Это имело смысл?
Последний. Если вы делаете это:
DIm p1 As New clsPerson
Dim p2 As New clsPerson
p1.Name = "Jim Morrison"
p2.Name = "Janis Joplin"
Теперь у вас есть два отдельных объекта персонажа. Однако, в ту минуту, когда вы делаете это снова:
p2 = p1
Теперь вы указали оба назад на "Джим Моррисон". (Я не совсем уверен, что случилось с Объектом в куче, на который ссылается p2 ... Я думаю, что теперь он вышел за рамки. Это одна из тех областей, где, надеюсь, кто-то может привести меня в порядок ...). -EDIT: Я ВЕРЮ, поэтому вы должны установить p2 = Ничего ИЛИ p2 = Новый clsPerson перед выполнением нового назначения.
Еще раз, если вы сейчас делаете ЭТО:
p2.Name = "Jimi Hendrix"
MsgBox(p1.Name)
MsgBox(p2.Name)
Оба msgBox-ов теперь будут возвращать "Jimi Hendrix"
Это может немного сбить с толку, и я скажу в последний раз, у меня могут быть некоторые детали неправильно.
Удачи, и, надеюсь, другие, кто знает лучше меня, придут, чтобы помочь прояснить кое-что из этого. , ,