10

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 ?

Bob
  • 97,670
  • 29
  • 122
  • 130
waheed
  • 533
  • 5
  • 15
  • I am surprised that `GetType` is called at all. Since C# is statically typed and a *value type variable* cannot hold anything but objects of the value type, the type is determinable at compile type (it’s `typeof(int)`). So why issue a runtime call? – Konrad Rudolph Feb 01 '10 at 20:01
  • That's right but the intention here is to clear that, why things are not working the way they should. – waheed Feb 01 '10 at 20:55

3 Answers3

8

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
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
2

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.

Arve
  • 7,284
  • 5
  • 37
  • 41
  • So the functions which are not implemented on System.Int32 directly, like those from System.ValueType or System.Object cannot be called directly? – waheed Feb 01 '10 at 19:40
  • That is what ildasm has shown me so far.... When you call the base class function (like System.Object::GetType() boxing is needed. If you call a function implemented on the value object then no boxing is nessecary... – Arve Feb 01 '10 at 19:45
1

Seems very close to How is ValueType.GetType() able to determine the type of the struct?

Also related is GetType and TypeOf confusion

Community
  • 1
  • 1
Ruddy
  • 1,734
  • 10
  • 11