Связь между классом System.Object и структурами

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

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

2 ответа

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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