Какая семантика памяти управляет назначением массива в c #?

c# .net

955 просмотра

7 ответа

Учитывая следующее: byte [] sData; и функция, объявленная как private byte [] construct_command ()

если бы я затем присвоить результат construct_command () к SDATA Would SDATA просто указывают на содержание того , что возвращается из функции или будет некоторое пространство быть alloctaed для SDATA в памяти и содержимого результата функции копируются в нее ?

Автор: Dark Star1 Источник Размещён: 12.11.2019 09:46

Ответы (7)


2 плюса

Решение

Предполагая, что sData является локальной переменной, она будет жить в стеке и будет ссылаться на массив, возвращаемый методом. Метод возвращает не содержимое самого массива, а ссылку на массив.

В .net массивы являются объектами первого класса, а все переменные типа массива фактически являются ссылками.

Автор: Rui Craveiro Размещён: 12.08.2009 02:43

6 плюса

Назначение просто назначит sData для ссылки на экземпляр, возвращаемый construct_command. Копирование данных не произойдет.

В целом, CLR разбивает мир на 2 типа

  • Типы значений: это все, что происходит от System.ValueType. Назначение между значениями этих типов происходит по значению и по существу приводит к копированию значений между местоположениями
  • Типы ссылок: все остальное. Назначение между значениями этих типов просто заставляет местоположение ссылаться на другой объект в памяти. Копирование значений не происходит

Массивы являются ссылочными типами в CLR и, следовательно, не вызывают копирования базового значения.

Автор: JaredPar Размещён: 12.08.2009 02:43

3 плюса

Массивы являются ссылочными типами, это означает, что фактический массив создается в куче (предположительно, с помощью construct_command ()), и функция возвращает ссылку на массив, и она хранится в (локальной переменной) sData.

Так что речь идет не о семантике памяти (возвращаемое значение может быть нулевым), а о семантике копирования ссылочных типов. Ситуация полностью равна, например:

StreamReader reader = System.IO.File.OpenText(filename);

Попросту говоря, вы вообще не можете передавать массив в .Net, вы можете только передавать, копировать и назначать ссылки на массивы.

Автор: Henk Holterman Размещён: 12.08.2009 02:47

2 плюса

sData будет указывать на содержимое того, что возвращается из функции. Массивы в C # являются ссылочными типами, что означает, что назначение одного массива из другого просто копирует ссылку, а не выделяет новые данные.

Автор: JSBձոգչ Размещён: 12.08.2009 02:42

2 плюса

Массив является ссылочным типом, поэтому копируется только ссылка. Нет манипулирования контентом.

Автор: Dewfy Размещён: 12.08.2009 02:43

0 плюса

sDataбудет указывать на массив, возвращаемый construct_command.

Автор: sepp2k Размещён: 12.08.2009 02:43

0 плюса

Хотя ответ Руи в целом хорош, я думаю, что часть его неверна. Это не имеет смысла (крайне противоречиво) для массива, который будет выделен из стековой памяти, а затем доступен по ссылке. Если бы это было правдой, базовая память могла быть освобождена из-под любых методов, на которые была передана ссылка.

Я считаю, что Хенк Холтерман правильно описал это, когда сказал очень прямо и недвусмысленно:

Массивы являются ссылочными типами, это означает, что конкретный массив создается в куче

Спасибо Хенк за этот комментарий; Я думаю, что это критически важная часть, в противном случае отсутствует (и противоречит) принятому ответу.

(Я бы ответил на комментарий, но у меня недостаточно очков, чтобы ответить, и я думаю, что достаточно важно указать, что принятый ответ имеет эту проблему для меня, чтобы добавить новый комментарий здесь.) Возможно, администратор может удалите ссылку на «локальная переменная, она будет жить в стеке» из ответа.

Автор: Appurist - Paul W Размещён: 28.01.2015 01:32
32x32