Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is GetType implemented in every object in C#?

Tags:

c#

reflection

I was looking at object out of curiosity, and I realized that object doesn't have a get type method. Yet it's commonly stated that every object in the language can have .GetType() called on it.

Does everything actually inherit from Type instead of object? And if thats the case how does typeof(object) / (object)val.GetType() work?

like image 638
Jlalonde Avatar asked Dec 01 '25 02:12

Jlalonde


1 Answers

I have found an article on the Internet written by Konrad Kokosa, which gives great explanation of how Object.GetType() works: http://tooslowexception.com/how-does-gettype-work/

Here is the quote from this article, which should answer your question:

If we look at the .NET Framework Reference Source method Object.GetType(), it quickly turns out that there is nothing really interesting:

// Returns a Type object which represent this object instance.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Type GetType();

Note that this method is not marked as virtual, but behaves like a virtual – for each object returns the actual type. This is due to the special, internal implementation. Attribute value of InternalCall means that the method is implemented internally in the CLR. Thanks to CoreCLR we can look deeper. If we want to find an internal function implementation of InternalCall, we look at the CoreCLR’s source file .\Src\vm\ecalllist.h where there is an adequate mapping. In our case it is

FCFuncStart(gObjectFuncs) 
    FCIntrinsic("GetType", ObjectNative::GetClass, CORINFO_INTRINSIC_Object_GetType) 
    FCFuncElement("MemberwiseClone", ObjectNative::Clone) 
FCFuncEnd()

And thus we come to an implementation (here and further I omit not relevant code):

// This routine is called by the Object.GetType() routine. It is a major way to get the Sytem.Type 
FCIMPL1(Object*, ObjectNative::GetClass, Object* pThis) 
{ 
// ... 
OBJECTREF objRef = ObjectToOBJECTREF(pThis); 
if (objRef != NULL) 
{ 
    MethodTable* pMT = objRef->GetMethodTable(); 
    OBJECTREF typePtr = pMT->GetManagedClassObjectIfExists(); 
    if (typePtr != NULL) 
    { 
        return OBJECTREFToObject(typePtr); 
    } 
} 
else 
    FCThrow(kNullReferenceException); 
FC_INNER_RETURN(Object*, GetClassHelper(objRef)); 
} 
FCIMPLEND

In short, what we see here is getting so-called object’s MethodTable (Object::GetMethodTable) and returning the corresponding Type object (MethodTable::GetManagedClassObjectIfExists) or create it if one does not exist (GetClassHelper)1). Here we should stop for a moment and for clarity divide our discussion into separate steps.

Answering your "Does everything actually inherit from Type instead of object?" question - definitely not.

like image 76
Yeldar Kurmangaliyev Avatar answered Dec 08 '25 12:12

Yeldar Kurmangaliyev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!