На этой неделе я работал над некоторым кодом на основе отражения, и во время модульного тестирования обнаружилось неожиданное условие: указатели являются ссылочными типами. Код C# typeof(int).MakePointerType().IsClass
возвращает true
.Почему ссылочные типы указателей?
Я проверил в моем только что установленном стандарте CLI, и, конечно же, указатели четко определены как ссылочные типы.
Это было удивительно для меня, исходя из фона C++. Я только что предположил, что указатели будут типами значений.
Существует ли конкретная причина, по которой типы указателей являются ссылочными типами, а не типами значений?
Update (осветление)
Когда речь идет о указателях и ссылках, вещи часто запутаться в отношении "указателя" и "pointee". Итак, вот некоторые разъяснения.
Типы могут быть ссылки на типы или типы значений, но переменные немного отличаются. (К сожалению, у меня не было возможности прочитать мой 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
относятся к тому же экземпляру объекта-указателя.
Возможно, я полностью ошибаюсь в этой интерпретации.
Исходя из C++ фон, было бы больше смысла для меня, для указателей, чтобы быть типами значений, поэтому оператор x = &i
просто назначая адрес i
к экземпляру типа значения x
и y = x
копии, значение адреса в y
. В куче не будет создан «объект-указатель».
Из документов CLR на Type.IsClass - Получает значение, указывающее, является ли тип классом; то есть не тип значения или интерфейс ». Технически тип указателя не наследует «System.Object», поэтому он не является объектом, типом значений или интерфейсом, а является классом в соответствии с документами. – thecoop