Я обнаружил это, если я выполняю следующие строки кода.
int i = 7;
i.GetHashCode(); //where GetHashCode() is the derived
//function from System.Object
Никакая упаковка не сделана, но если я звоню i.GetType()
(другая полученная функция от System.Object
) вместо GetHashCode()
, упаковка потребуется, чтобы звонить GetType()
, Почему не возможный звонить GetType()
на экземпляре типа примитива непосредственно, без упаковки, в то время как его возможное для вызова GetHashCode()
без упаковки?
Ключ здесь в том, что GetType()
не является виртуальной и не может быть переопределена. Так как структура фактически запечатана
, то методы не могут быть переопределены никак больше , чем структура, поэтому время выполнения и компилятор могут трактовать методы структуры , которые были переопределены, как статические вызовы.
Если Вы пишете структуру (редко), то по этой причине должны переопределить все методы, такие как ToString()
, Equals()
, GetHashCode()
. Если вы этого не сделаете, он должен быть установлен. Однако, GetType()
не может быть переопределена, следовательно, необходим бокс.
Это на самом деле приводит к некоторым нечетным крайним случаям с Nullable
и боксированием, так как пустые Nullable
боксы становятся null
, так что:
int i = obj.GetHashCode(); // fine
Type t = obj.GetType(); // boom
Кажется очень близким к Как ValueType.GetType() может определить тип структуры?
Также близким является Путаница с GetType и TypeOf
Я думаю, причина в том, что GetHashCode реализован непосредственно в System.Int32, вы вызываете System .Int32 :: GetHashCode (). Нет необходимости вставлять в бокс, если вы вызываете известную функцию-член для типа значения.