Подтвердить что ты не робот

Почему ссылочные типы указателей?

На этой неделе я работал над некоторым кодом на основе отражения, и во время модульного тестирования обнаружилось неожиданное условие: указатели являются ссылочными типами. Код С# typeof(int).MakePointerType().IsClass возвращает true.

Я проверил в моем только что полученном стандартном стандарте CLI, и, конечно же, указатели четко определены как ссылочные типы.

Это было удивительно для меня, исходя из фона С++. Я только что предположил, что указатели будут типами значений.

Существует ли конкретная причина, по которой типы указателей являются ссылочными типами, а не типами значений?

Обновление (уточнение)

Говоря о указателях и ссылках, вещи часто путаются в отношении "указателя" и "указателя". Итак, здесь некоторые разъяснения.

Типы могут быть ссылочными типами или типами значений, но переменные немного отличаются. (Извините, у меня не было возможности прочитать мой стандарт CLI, поэтому терминология и концепции могут быть неправильными - исправьте меня, пожалуйста!)

Учитывая этот код (понятия локальной переменной для ссылочных типов):

var x = new MyClass();
var y = x;

Переменные x и y не являются ссылочными типами, но они являются ссылками на объект, который является ссылочным типом (MyClass является ссылочным типом). Другими словами, x и y не являются экземплярами ссылочного типа; они относятся только к экземпляру ссылочного типа.

Учитывая этот код (понятия локальной переменной для типов значений):

var x = 13;
var y = x;

Переменные x и y представляют собой типы значений экземпляров (или, по крайней мере, действуют как экземпляры).

Итак, мы приходим к этому коду:

var i = 13;
var x = &i;
var y = x;

Если тип указателя является ссылочным типом, тогда я интерпретирую оператор x = &i:

  • Создается экземпляр типа int*, указывающий на i.
  • Поскольку указатели являются ссылочными типами, этот экземпляр создается в куче (при условии, что все ссылочные типы помещаются в кучу, деталь реализации).
  • x - ссылка на этот экземпляр указателя.
  • Экземпляр указателя в конечном итоге будет собирать мусор, как и другие ссылочные типы.
  • Когда выполняется y = x, ссылка копируется. Оба y и x относятся к тому же экземпляру объекта-указателя.

Возможно, я полностью ошибаюсь в этой интерпретации.

Исходя из фона С++, для меня было бы разумнее, чтобы указатели были типами значений, поэтому оператор x = &i просто присваивает адрес i экземпляру типа значения x и y = x копирует значение адреса в y. В куче не будет создан "объект-указатель".

4b9b3361

Ответ 1

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

Я вынужден сделать вывод: указатели (например, int *) фактически являются типами значений; тот факт, что их Type return true для IsClass является ошибкой в ​​спецификации. Я подозреваю, что никто этого не заметил, потому что получение типа указателя - очень редкая операция.

Ответ 2

typeof (int).MakePointerType(). IsPointer

похоже, что существует различие.

Ответ 3

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

Обновление

Отличная статья Wesner Moise: " Указатели UNDOCUMENTED".

В статье описывается, как управляемые указатели корректируются во время уплотнения кучи.

Ответ 4

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

Ответ 5

Рассмотрим:

MyClass x = new MyClass();

Здесь MyClass является ссылочным типом, и если вы просмотрите отражение, x будет называться ссылочным типом. Но, под капотом, x на самом деле является указателем.