Каково различие между Ссылкой C# и Указателем?

81
задан Wai Ha Lee 17 January 2018 в 10:14
поделиться

8 ответов

Ссылки C# могут, и перемещаться сборщиком "мусора", но нормальные указатели статичны. Поэтому мы используем fixed ключевое слово при получении указателя на элемент массива, для препятствования ему то, чтобы быть перемещенным.

РЕДАКТИРОВАНИЕ: Концептуально, да. Они - более или менее то же.

44
ответ дан Mehrdad Afshari 24 November 2019 в 09:30
поделиться

Существует небольшое, все же чрезвычайно важное, различие между указателем и ссылкой. Указатель указывает на место в памяти в то время как контрольные точки к объекту в памяти. Указатели не "безопасны с точки зрения типов" в том смысле, что Вы не можете гарантировать правильность памяти, на которую они указывают.

Берут, например, следующий код

int* p1 = GetAPointer();

, Это безопасно с точки зрения типов в том смысле, что GetAPointer должен возвратить тип, совместимый с int*. Все же нет все еще никакой гарантии, что *p1 на самом деле укажет на интервал. Это мог быть символ, дважды или просто указатель в случайную память.

ссылка А однако указывает на конкретный объект. Объекты могут быть перемещены в памяти, но ссылка не может делаться недействительным (если Вы не используете небезопасный код). Ссылки намного более безопасны в этом отношении, чем указатели.

string str = GetAString();

В этом случае str имеет один из с двумя состояниями 1) это не указывает ни на какой объект и следовательно является пустым или 2) это указывает на допустимую строку.Вот именно. CLR гарантирует это для имения место. Это не может и не быть для указателя.

126
ответ дан JaredPar 24 November 2019 в 09:30
поделиться

Ссылка является "абстрактным" указателем: Вы не можете сделать арифметики со ссылкой, и Вы не можете играть приемы низкого уровня с ее значением.

13
ответ дан Chris Conway 24 November 2019 в 09:30
поделиться

Сначала я думаю, что необходимо определить "Указатель" в sematics. Вы имеете в виду указатель, который можно создать в небезопасном коде с , зафиксировал ? Вы имеете в виду IntPtr, который Вы получаете от, возможно, собственного вызова или Маршал. AllocHGlobal? Вы имеете в виду GCHandle? Все являются по существу тем же самым - представление адреса памяти, где что-то хранится - быть им класс, число, структура, безотносительно. И для записи, они, конечно, могут быть на "куче".

указатель А (все вышеупомянутые версии) является фиксированным объектом. GC понятия не имеет, что в том адресе, и поэтому не имеет никакой способности управлять памятью или жизнью объекта. Это означает потерю всех преимуществ собравшей "мусор" системы. Необходимо вручную управлять объектной памятью, и у Вас есть потенциал для утечек.

ссылка А, с другой стороны, является в значительной степени "управляемым указателем", о котором знает GC. Это - все еще адрес объекта, но теперь GC знает детали цели, таким образом, это может переместить его, сделать уплотнения, завершить, расположить и весь другой хороший материал, управляемая среда делает.

существенное различие, действительно, находится в том, как и почему Вы использовали бы их. Для подавляющего большинства случаев на управляемом языке Вы собираетесь использовать ссылку на объект. Указатели становятся удобными для того, чтобы сделать interop и редкую потребность в действительно быстрой работе.

Редактирование: На самом деле вот хороший пример из когда Вы могли бы использовать "указатель" в управляемом коде - в этом случае, это - GCHandle, но та же самая вещь, возможно, была сделана с AllocHGlobal или при помощи закрепленного на массиве байтов или структуре. Я склонен предпочитать GCHandle becasue, это чувствует больше ".NET" мне.

6
ответ дан ctacke 24 November 2019 в 09:30
поделиться

Указатели указывают на местоположение в пространстве адреса памяти. Ссылки указывают на структуру данных. Структуры данных все перемещенные все время (хорошо, не, что часто, но время от времени) сборщиком "мусора" (для уплотнения пространства памяти). Кроме того, как Вы сказали, структуры данных без ссылок будут собраны "мусор" через некоторое время.

кроме того, указатели только применимы в небезопасном контексте.

5
ответ дан Tamas Czinege 24 November 2019 в 09:30
поделиться

Я думаю, что для разработчиков важно понять понятие pointer— то есть, понять косвенность. Это не означает, что они обязательно должны использовать указатели. Также важно понять, что понятие ссылки отличается от понятие указателя , хотя только тонко, но что реализация ссылки почти всегда указатель.

То есть переменная, содержащая ссылку, является просто блоком размера указателя памяти, содержащей указатель на объект. Однако эта переменная не может использоваться таким же образом, что переменная указателя может использоваться. В C# (и C и C++...), указатель может быть индексирован как массив, но ссылка не может. В C# ссылка прослежена сборщиком "мусора", указатель не может быть. В C++ может быть повторно присвоен указатель, ссылка не может. Синтаксически и семантически, указатели и ссылки очень отличаются, но механически, они - то же.

4
ответ дан P Daddy 24 November 2019 в 09:30
поделиться

Указатель может указать на любой байт в адресном пространстве приложения. Ссылку сильно ограничивает и управляет среда.NET.

5
ответ дан jdigital 24 November 2019 в 09:30
поделиться

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

1
ответ дан Robert C. Barth 24 November 2019 в 09:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: