Зачем вызывать некоторые функции класса объекта, на примитивном экземпляре типа нужны бокс?
-
24-09-2019 - |
Вопрос
Я обнаружил, что если у меня будет следующие строки кода.
int i = 7;
i.GetHashCode(); //where GetHashCode() is the derived
//function from System.Object
Без бокса не сделано, но если я позвоню i.GetType()
(другая производная функция из System.Object
) на месте GetHashCode()
, Бокс потребуется позвонить GetType()
, Почему его невозможно позвонить GetType()
на примитивный тип экземпляра напрямую, без бокса, в то время как можно позвонить GetHashCode()
Без бокса?
Решение
Ключ вот что GetType()
не виртуально и не может быть переопределен. Так как структура эффективно sealed
, методы не могут быть переопределены любой более чем структуру, поэтому время выполнения и компилятор могут лечить методы структуры которые были переопределены как статические звонки.
Если вы пишете структуру (редко) вы должен переопределить все методы, такие как ToString()
, Equals()
, GetHashCode()
Именно по этой причине. Если вы этого не сделаете, не должен. Однако, GetType()
не можем быть переопределенным, таким образом, нуждается в боксе.
Это на самом деле приводит к каким-то нечетным краям Nullable<T>
и бокс, так как пустой Nullable<T>
коробки к null
, так:
int i = obj.GetHashCode(); // fine
Type t = obj.GetType(); // boom
Другие советы
Я думаю, что причина в том, что GetHashCode реализуется на System.int32 напрямую, вы называете System.int32 :: GetHashCode (). Нет необходимости в коробке, если вы называете известную функцию члена в типе значений.
Кажется очень близко к Как ValueType.getType () может определить тип структуры?
Также связано Gettype и тип путаницы