Andriy Shyrokoryadov

.Net developer, data scientist

Ссылочные и значимые типы - вопрос №11 на собеседование C# / .NET

Текст к видео "Ссылочные и значимые типы" на канале YouTube

Во время выполнения кода наш код и данные могут находиться в двух местах в памяти: stack (стек, стопка) и heap (куча). Или в одном или в другом месте. Стек в той или иной степени отвечает, что в данный момент выполняется в нашем коде, а в куче хранятся наши данные.

Стек можно представить как стопку коробок – всегда то, что выполняется в данный момент находится в самой верхней коробке. Как только операция выполнена – коробка удаляется, а мы берем коробку, которая находится ниже и выполняем код в ней. Во время выполнения у нас есть доступ только к самой верхней коробке. Стек можно назвать самоуправляемым – «коробки» добавляются и удаляются автоматически.

Куча – это место в памяти, которое можно представить в виде коробок, но в отличии от стопки, мы можем получить доступ к каждой доступной коробке в любой момент времени. Также то, что больше не используется в куче также будет удалено, при помощи сборщика мусора (Garbage Collector)

В языке существует 4 главных типа: значимые типы, ссылочные типы, указатели и инструкции.

Значимые типы – это типы, которые наследуют тип System.ValueType, например bool, int, long, decimal, enum и другие.

Ссылочные типы – это типы, которые наследуют тип System.Object, то есть class, interface, delegate, string. Object также является ссылочным типом, но он не наследует System.Object, а является этим типом.

Указатель или ссылка – это то, что связывает определенный тип с его значением в памяти. Указатель может находиться в стеке или в куче, но указывает на определенное место в куче. Программисты C# не используют указатели непосредственно. За них это делает Common Language Runtime. Возвращаясь к предыдущему пункту – если мы говорим, что что-то является ссылочным типом, то это означает, что мы обращаемся к этому типу через ссылку или указатель. Значением указателя может быть адрес памяти или null. Отсюда можно сделать выводы что значимые типы не могут иметь значение null – они всегда имеют значение по умолчанию для своего типа, например для int это 0.

Инструкции – по сути это наши методы с набором команд, которые необходимо выполнить.

Вопрос что и где хранится в памяти?

  • Ссылочные типы всегда хранятся в куче.
  • Значимые типы и указатели хранятся в том месте, где они были задекларированы. Что это значит? Это значит, что если значимый тип был задекларирован как часть метода, то он будет размещен в стеке, однако если значимый тип является часть ссылочного типа, то он будет размещен в куче.

Что еще необходимо знать о значимых и ссылочных типах?

  • работая со значимым типом, мы всегда работаем с его конкретным значением;
  • работая со ссылочным типом мы всегда работаем с указателем на этот тип в памяти – стоит помнить что таких указателей может быть несколько и соответственно значение в памяти может быть изменено в нескольких местах в коде.