.NET: наследование типов значений - технические ограничения? - PullRequest
20 голосов
/ 13 февраля 2011

Мне интересно, есть ли какие-либо технические причины, по которым типы значений .NET не поддерживают наследование (не принимая во внимание реализацию интерфейса) ... На первый взгляд, я не могу придумать причину, по которой типы значений не должны разрешать одиннаследование базового класса.

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

Спасибо.

Ответы [ 3 ]

28 голосов
/ 13 февраля 2011

Рассмотрим память, выделенную для типа значения. CLR точно знает, сколько места нужно выделить для переменной типа значения, потому что оно знает, какие поля будут. Это не может в конечном итоге иметь значение подтипа с большим количеством полей.

Теперь мы можем иметь наследование типа значения, которое просто усекает вещи:

ExtendedValueType evt = new ExtendedValueType(...);
BaseValueType bvt = evt;
// Now you couldn't cast back to ExtendedValueType, because we'd have lost
// information

Точно так же не существует информации о типе, которая могла бы жить в самом значении, поэтому любые виртуальные методы, переопределенные расширенным типом, не будут вызываться через bvt, потому что для всех это значение равно просто значение BaseValueType. Другими словами, многие «естественные» функции наследования будут отсутствовать таким образом, который, я думаю, вызовет много путаницы.

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

Я считаю, что причина, по которой типы значений не поддерживают наследование, связана с тем, как они представлены в памяти. Размер и, следовательно, данные, представленные типом значения, зависят от составляющих его полей. То есть, если ваш тип значения содержит int и строку, общий размер в 32-битной системе будет 8 или 4 (размер int) + 4 (размер указателя). Это означает, что типы значений, представленные в памяти, представляют собой блок байтов без дополнительной информации.

Теперь контрастируйте, что с типами классов все они имеют размер указателей, или 4 на 32-битных системах. Поскольку экземпляры типов классов являются указателями, они могут ссылаться на вещи, необходимые для наследования, такие как VMT (таблица виртуальных методов) и ссылку на информацию о родительских классах. Это то, что тип значения не может сделать, и, следовательно, почему типы значений не поддерживают наследование.

3 голосов
/ 13 февраля 2011

Предположим, это можно сделать.

Вы могли бы повторно использовать некоторую реализацию.
Но реальными преимуществами наследования являются замещение и полиморфизм.Они требуют использования по ссылке.

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

...