Связь между классом System.Object и структурами - PullRequest
5 голосов
/ 23 марта 2012

Я знаю, что мой вопрос кажется глупым, но я в замешательстве. Я ценю, если кто-то разъяснит мне это.

Я знаю, что структуры, например, Int32 являются типами значений и создаются в стеке, в то время как классы являются ссылочными типами и создаются в куче. Я также знаю, что все структуры являются производными от типа System.Object, который является классом. Интересно, как это возможно, что супертип System.Object является ссылочным типом, а подтип Int32 является типом значения? Куда мне обратиться, чтобы понять, как это работает?

Ответы [ 2 ]

11 голосов
/ 23 марта 2012

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

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

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

Что определяет, какое хранилище выделяется в куче, а какое - в стекеэто известные требования к сроку службы хранилища , а не что это за штука .Если известно, что переменная недолговечна, ее можно разместить в стеке;если неизвестно, что он недолговечный, он должен быть размещен в куче.

Я также знаю, что все структуры являются производными от типа System.Object, который является классом.Интересно, как это возможно, что супертип System.Object является ссылочным типом, а подтип Int32 является типом значения?

Я подозреваю, что вы не понимаете, что означает "наследовать от", если вас это смущает.Когда мы говорим, что System.Int32, тип значения, наследуется от System.Object, ссылочного типа, мы подразумеваем, что все члены Object также являются членами Int32 .Объект имеет метод "ToString".Это член Object.Поэтому Int32 также имеет метод ToString, поскольку Int32 наследует от Object.

То есть all , что означает наследование.Я подозреваю, что вы считаете, что наследование означает что-то другое, и что независимо от того, что это «что-то», препятствует типам значений расширять ссылочные типы.Какое бы у вас ни было убеждение, которое заставляет вас думать, что типы значений не могут наследовать от ссылочных типов, явно ложно, поскольку, очевидно, они это делают.

Мне интересно узнать, что люди верят в языки программирования;Что вы думаете неправильно о верных отношениях наследования, которые не позволяют типам значений наследоваться от ссылочных типов?

Вы должны прочитать и понять все эти статьи:

http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

http://blogs.msdn.com/b/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx

http://ericlippert.com/2011/09/19/inheritance-and-representation/

И дополнительный бонус, этот также может быть полезным для вас:

http://blogs.msdn.com/b/ericlippert/archive/2012/01/16/what-is-the-defining-characteristic-of-a-local-variable.aspx

2 голосов
/ 23 марта 2012

Прежде всего, отличительная особенность типов значений заключается не в том, где они хранятся, а в том, как они передаются в методы. Структуры передаются по значению; то есть копия аргумента создана и передана. Любые изменения в копии в методе не влияют на фактический аргумент (если они не используют одну и ту же ссылку). Типы ссылок передаются по ссылке; это указатель на фактический аргумент передается.

Да, структуры получены из ValueType. И ValueType является производным от Object. Таким образом, в конечном итоге структуры также получены из Object. (Например, методы ToString(), ==, Equals(), GetHashCode() и, возможно, некоторые другие определены в Object и, следовательно, также доступны в структурах)

Однако семантика передачи аргументов не определяется внутри самих классов; в определении Object нет кода, который говорит, что «любые экземпляры моих подтипов должны передаваться по ссылке», и в определении ValueType нет кода, который говорит, что «любые экземпляры моих подтипов должны передаваться» по значению ". [Возможно, есть специальный атрибут, но это не считается.] Ответственность за соблюдение этого лежит на компиляторе. (Где-то в компиляторах C # есть код, который говорит: «сгенерируйте код так, чтобы потомки ValueType передавались по значению, а другие передавались по ссылке»)

Блог Эрика Липперта является фантастическим ресурсом по многим вопросам, связанным с C #, и вы должны прочитать ссылку, предоставленную @Heinzi для дальнейших разъяснений.

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