На каком уровне происходит бокс объекта в.net?

Если у меня есть объект, такой как List<string> что я бросил в objectи снова вернемся, все строки будут также приведены или просто список, который их содержит?

Я думаю, что компилятор должен будет только проверить, если object был типа List<string> прежде чем бросить обратно в List<string> но я вырос на C#, поэтому я не совсем уверен, что происходит за кодом, который я пишу.

6 ответов

Решение

Когда вы бросаете List<string> для objectВы вообще не делаете кастинг. Вы назначаете одну ссылку на некоторые данные, на менее конкретную ссылку. string содержащиеся в нем объекты тоже не меняются.


Также, чтобы уточнить, в этом случае нет никакого бокса. Бокс происходит, когда вы создаете ссылку на тип значения, такой как int или несколько struct, присваивая его или передавая каким-либо образом переменной типа object,

Упаковка происходит, когда тип структуры / значения хранится в месте, которое типизировано для объекта или интерфейса, который реализует эта структура. В этом сценарии оба List<string> а также string являются ссылочными типами, поэтому бокс не происходит.

struct S1 : IComparable {
  ...
}

S1 local = new S1();  // No box. 
object obj = local;   // Box S1 instance into object
IComparable comp = local;  // Box S1 instance into IComparable
obj = "hello";  // String is a reference type, no boxing

string это ссылочный тип - экземпляр string никогда не будет в штучной упаковке.

Однако, если у вас был List<int>, список является ссылочным типом, поэтому здесь тоже не будет никакого бокса. int является типом значения и может быть упакован, если он был приведен к объекту (неявно или явно).

Бокс влияет только на типы значений - List<T> является классом, следовательно, ссылочным типом, изменение универсального типа T не влияет на то, передается ли экземпляр по значению или по ссылке.

Общие коллекции помогают предотвратить упаковку, так как она позволяет читать / записывать типы значений, не помещая их в object,

Для каждого типа значения существует соответствующий тип объекта с тем же именем, который является производным от ValueType. Всякий раз, когда необходимо создать место хранения (поле, переменную или параметр) данного типа, система выделяет пространство для хранения либо ссылки на кучу (если тип не является производным от ValueType), либо всех полей типа (если это "структура"), или биты, содержащие значение типов. Упаковка происходит, когда делается попытка сохранить экземпляр типа значения в ссылку на кучу. Распаковка происходит, когда делается попытка использовать ссылку на кучу, как если бы это был тип значения. Обратите внимание, что в некоторых контекстах распаковка копирует содержимое упакованного объекта в новое место хранения, но в других контекстах он будет рассматривать упакованный экземпляр как место хранения. Семантика этого не всегда ясна, что является одной из причин, по которой некоторые люди ненавидят изменчивые структуры. На практике изменяемые структуры хороши, если избегать сценариев использования, в которых семантика становится мутной, и даже неизменные структуры могут страдать от той же мутной семантики.

Только List<string> будет брошен.

Если вы хотите разыграть List<string> предметы делают это:

List<string> list = new List<string>{"first", "second"};
List<object> objectsList = list.Cast<object>();

PS string это ссылочный тип, поэтому он не может получить boxed а также unboxed

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

Это не так, это просто актерский состав.

Другие вопросы по тегам