Небольшая путаница по ссылочным типам и типам значений в спецификации C # - PullRequest
2 голосов
/ 10 июня 2011

Я пытаюсь переварить это утверждение в спецификации C #, в котором говорится (§4.2):

Тип ссылки - это тип класса, тип интерфейса , тип массива или тип делегата.

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

Итак, у меня проблемы с согласованием этой информации. Означает ли это, что структуры ведут себя как ссылочные типы при обработке через интерфейсный тип? Это будет означать, что вы можете получить ссылку на тип значения ...

Ответы [ 5 ]

3 голосов
/ 10 июня 2011

Да, вы можете получить ссылку на тип значения. Каждый раз, когда тип значения назначается переменной или передается в качестве параметра методу, который ожидает тип Object, тип значения неявно переносится в экземпляр объекта - процесс, называемый боксом. Бокс создает ссылку на объект, который содержит значение. Когда объект в штучной упаковке назначен или используется как тип значения, он распаковывается и значение извлекается.

3 голосов
/ 10 июня 2011

Это верно.Когда тип значения используется в контексте, где требуется ссылка на интерфейс, он упаковывается.То же самое происходит, если требуется System.Object.

Чего не может быть, так это ссылки интерфейса на экземпляр типа значения в стеке или внутри другого типа.Процесс бокса создает копию.

3 голосов
/ 10 июня 2011

Вот сообщение в блоге, которое может быть иллюстративным.

http://blogs.msdn.com/b/abhinaba/archive/2005/10/05/477238.aspx

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

1 голос
/ 06 октября 2011

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

void Compare<T>(T thing1, T Thing2) where T:IComparable<T>
{
   return thing1.CompareTo(Thing2);
}

Обратите внимание, что, хотя в приведенном выше коде при использовании структур избегается упаковка, сравнение двух объектов типа значения T потребует трех операций копирования. Если бы параметры передавались по ссылке, а не по значению, производительность с типами значений была бы улучшена за счет снижения производительности ссылочного типа (и, конечно, совместимости с существующими IComparable и IComparer ).

1 голос
/ 10 июня 2011

Да, struct s может реализовать интерфейс, НО они не являются типом интерфейса.struct является типом значения и, когда требуется, будет помещен в коробку.

...