VB.Net Новые объекты: куда они деваются? - PullRequest
1 голос
/ 26 октября 2011

Время от времени мне приходится изучать основы языка после долгих экскурсий по кодированию.В VB.Net я понимаю, что объявление переменной как типа объекта более или менее создает ссылку на него.

Возьмем следующий код:

Dim obj1 as Object
Dim obj2 as Object
obj1 = new Object
obj2 = new Object
obj1 = obj2

Очень простой набор задач,но я пытаюсь понять, что именно происходит на каждом этапе пути.Это мое понимание: строка 1, obj1 объявлена ​​как тип объекта, и компилятор создает ссылку для obj1 для хранения, но что такое ссылка на obj1 в конце строки 1? (являются nothing иnull синоним?) Строка 2 такая же, как и строка 1, за исключением другой переменной.В строке 3 компилятор выделяет пространство в куче для нового объекта и передает ссылку на obj1 1 для хранения.Строка 4 такая же, как и строка 3. Часть, о которой я никогда не понимал, это 5-я строка.obj1 назначается той же ссылке, что и obj2, поэтому они оба указывают на один и тот же объект в памяти.Так что же происходит с объектом, который obj1 был изначально назначен в строке 3? Если obj1 использует ту же ссылку, что и obj2, оставляет ли первый первый объект в памяти без доступа к нему (или, по крайней мере, до начала сбора мусора) ?

Ответы [ 4 ]

3 голосов
/ 26 октября 2011

Сначала не задан вопрос / ничего. Значение obj1 и obj2 до создания новых объектов равно Nothing, но это не совсем то же самое, что и C # null. VB.Net Nothing является более близким аналогом концепции C # default(T). В этом случае все сводится к одному и тому же, но стоит знать различие, потому что null и Nothing ведут себя очень по-разному, когда вы работаете с типами значений.

Следующее, что здесь необходимо понять, это присвоение в строке 5. На этом этапе ссылка на переменную obj2 скопирована в переменную obj1. Это важно, потому что они больше не являются одной и той же ссылкой, а скорее двумя ссылками, которые указывают (ссылаются) на одно и то же место. Это достаточно легко понять в этом коде, но я видел, как он запутывает людей в более сложных местах ... скажем, одна из переменных назначена в методе.

И наконец, да, объект, на который изначально ссылалась переменная obj1, теперь может быть использован для сборки мусора. Вам больше не нужно об этом беспокоиться.

2 голосов
/ 26 октября 2011

Что такое ссылка на obj1 в конце строки 1?

На языке VB он указывает на Nothing, что совпадает с null в C # (что в данном случае можно рассматривать как указание на нулевую ячейку памяти).

Как только obj1 берет ту же ссылку, что и obj2, остается ли это первым новый объект остался в памяти без доступа к нему (или, по крайней мере, до начинается сборка мусора)

Да, именно так и происходит. С капризами сборки мусора вы никогда не сможете определить, когда это будет на самом деле собрано, и, действительно, нет никакой гарантии, что оно когда-нибудь будет собрано.

Пусть GC беспокоится о подобных вещах, не пытайтесь «помочь», если только вам (а я не имею в виду, действительно, действительно ) это нужно.

1 голос
/ 26 октября 2011

В .net при создании переменной вы создаете ссылку или тип значения.Все ваши примеры являются ссылочными переменными, когда программа входит в функцию, она создает необходимое пространство для хранения локальных объектов (т. Е. Пространство, необходимое для хранения ссылок).


ILdasm

.method public static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       32 (0x20)
  .maxstack  1
  .locals init ([0] object obj1,
           [1] object obj2)
  IL_0000:  nop

Затем он создает объекты в управляемой куче, а не в "куче", и назначает их местным жителям.

 IL_0001:  newobj     instance void [mscorlib]System.Object::.ctor()
  IL_0006:  call       object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object)
  IL_000b:  stloc.0
  IL_000c:  newobj     instance void [mscorlib]System.Object::.ctor()
  IL_0011:  call       object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object)
  IL_0016:  stloc.1
  IL_0017:  ldloc.1
  IL_0018:  call       object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object)
  IL_001d:  stloc.0

Затем функция возвращает

 IL_001e:  nop
  IL_001f:  ret
} // end of method Module1::Mai

Сборщик мусора вызывается по прихоти времени выполнения (вы можете форсировать его руку) и будет собирать все недоступные объекты по поколениям..

1 голос
/ 26 октября 2011

После строки 1 obj1 будет содержать ссылку на значение null - Nothing.

Nothing в VB.NET совпадает с null в C #, по крайней мерекогда речь идет о ссылочных типах (см. комментарий Джоэла Коухорна).

Строка 5 - объект, на который ссылается obj1, - это тот, на который obj2 ссылается.На данный момент первый объект действительно больше недоступен и будет собирать мусор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...