Контейнеры .NET - когда являются членами По ссылке, По Значению?
-
06-07-2019 - |
Вопрос
Я перехожу с C ++ на VB.NET в своих проектах по написанию кода...что приводит к случайной путанице в том, когда что-то находится по значению или по ссылке в VB.NET.
Предположим, например, что у меня есть массив MyObject, который заполнен кучей объектов.
dim MyArr(5000) of MyObject
Теперь предположим, что информация из этого массива передается по различным структурам данных:
dim MyList as new List(of MyObject)
for i as integer = 0 to 5000 step 1000
Mylist.add(MyArr(i))
next
тогда
dim MyTable as new HashTable
dim i as integer = 0
for each O as MyObject in Mylist
if i mod 2 = 0 then
MyTable.add(O.ToString(), O)
end if
next
В соответствии с приведенным выше сценарием, я полагаю, что все делается по ссылке.Если я извлеку запись из "MyTable" и изменю ее элементы MyObject, я думаю, что оригинал в myArr будет изменен.
Однако я сталкивался с ситуациями, когда я думал, что что-то было по ссылке, а это было по значению.
Всегда ли элементы добавляются в контейнеры по ссылке или иногда они добавляются по значению?
Я в замешательстве.
Решение
На самом деле это не тот случай, когда "по ссылке" или "по значению".Значение, которое вы передаете методу Add, копируется.Однако для ссылочных типов это значение является ссылка к объекту - и если вы будете манипулировать этим объектом с помощью других ссылок на него, вы сможете видеть эти изменения, как бы вы ни обращались к объекту.
Если вы когда-нибудь увидите независимые копии самих данных, это говорит о том, что вы используете тип значения...но если вы делаете Изменения, это говорит о том , что вы используете изменяемый тип значения, что является плохой идеей.Типы значений почти всегда должны быть неизменяемыми, в противном случае это приводит к большой путанице.(Ссылочные типы тоже могут быть неизменяемыми - string - хороший пример.)
Подробнее о ссылочных типах и типах значений читайте в моих статьях о ссылки и параметры.Они написаны с точки зрения C #, но основы применимы и к VB.
Я думаю, как только вы поймете различие между типом значения value и ссылкой, коллекции будут иметь для вас больше смысла.
Другие советы
Вы можете использовать это правило:если вы можете присвоить объекту значение null, то оно будет передано по ссылке.В противном случае он будет передан по значению.
Исключением из этого правила являются обнуляемые типы и структуры.Они всегда передаются по значению.
Я думаю, это зависит от типа предметов.Не в коллекциях.
Например.:
int[] целые числа = новый int[10];
целые числа [0] = 1;//-)
в этом случае 1 будет скопирован до тех пор, пока это ValueType .