简体   繁体   中英

Why calling some functions of the Object class, on a primitive type instance, need boxing?

I have discovered that if i run following lines of code.

int i = 7;
i.GetHashCode(); //where GetHashCode() is the derived
                 //function from System.Object

No boxing is done, but if i call i.GetType() (another derived function from System.Object ) in place of GetHashCode() , a boxing will be required to call GetType() , Why its not possible to call GetType() on primitive type instance directly, without boxing, while its possible to call GetHashCode() without boxing ?

The key here is that GetType() is not virtual and cannot be overridden. Since a struct is effectively sealed , methods cannot be overridden any more than the struct, so the runtime and compiler can treat struct methods that have been overridden as static calls.

If you write a struct (rare) you should override all the methods like ToString() , Equals() , GetHashCode() for exactly this reason. If you don't it must box. However, GetType() cannot be overridden, thus needs boxing.

This actually leads to some odd edge-cases with Nullable<T> and boxing, since an empty Nullable<T> boxes to null , so:

int i = obj.GetHashCode(); // fine
Type t = obj.GetType(); // boom

I think the reason is that GetHashCode is implemented on System.Int32 directly, you call System.Int32::GetHashCode(). No need to box if you call a known member function on a value type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM