Как System.Object хранит «объекты» внутри? - PullRequest
2 голосов
/ 23 февраля 2011

Я читал о боксе, и в книге говорится, что «бокс можно формально определить как процесс явного преобразования типа значения в соответствующий ссылочный тип путем сохранения переменной в System.Object. " (выделение добавлено)

Мой вопрос не о боксе, но это заставило меня задуматься - как и где этот экземпляр System.Object хранит присвоенные ему значения / переменные / объекты. Так что меня интересует не только

object objShort = 5;

но также

object someOtherObj = someReallyComplicatedObject;

Я осматривался, включая здесь (MSDN System.Object) , и я не вижу нигде, где описано, как экземпляр System.Object действительно хранит свои данные.

Является ли объект просто хранящим указатель на объект, который был ему присвоен, или, в случае бокса, указателем на тип значения в стеке?

(Джон, прости меня, если это тоже есть в твоей книге. Я заказал это, и оно уже в пути!)

Ответы [ 3 ]

8 голосов
/ 23 февраля 2011

Это описание бокса неточно.Созданный объект не просто экземпляр голого System.Object;каждый тип значения фактически имеет свой собственный «скрытый» соответствующий ссылочный тип, который является просто классом, производным от ValueType, реализующим те же интерфейсы, что и тип значения, и с полем типа типа значения.Это, конечно, то, что я думаю об этом, по крайней мере, и это примерно так, как описывает спецификация CLI.System.Object само по себе не не имеет никакого хранилища для этого.

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

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

(О, и это покрыто несколько вC # в глубине, но не в мельчайших подробностях. Возможно, вас заинтересует пост Эрика Липперта «Правда о типах значений» , хотя.)

6 голосов
/ 24 февраля 2011

Представьте, что существует общий ссылочный тип, который выглядит следующим образом:

sealed class Box<T> : System.ValueType where T : struct
{
    private T value;
    public Box(T t) 
    {
        this.value = t;
    }
}

Плюс куча других хитрых вещей там:

  • оператор явного преобразования из Box<T> в T.
  • оператор неявного преобразования из T в Box<T>, который просто вызывает конструктор.
  • реализации ToString, GetHashcode и GetType, которые прокси для this.value.
  • и т. Д.

Концептуально , преобразование бокса из int в объект просто вызывает оператор неявного преобразования из int в Box<int>.

Конечно, в действительности нет такого типа, как Box<T>, и если бы он был, он был бы полон дурацких вещей; вы не можете нормально переопределять GetType, вы не можете нормально расширять ValueType в классе, его поведение с обнуляемыми типами странное, и так далее. Все эти детали являются деталями реализации CLR, но это помогает представить, что CLR просто создает экземпляр Особого Типа, который выполняет упаковку и распаковку.

2 голосов
/ 23 февраля 2011

Объект ссылочного типа в CLR (включая C #) хранится с некоторыми метаданными, которые описывают, какой это тип объекта, состояние его блокировки, информацию о сборке мусора и т. Д., А также фактические данные что объект хранит.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...