我出于好奇研究了一下object,意识到它没有GetType()方法。然而通常有人说语言中的每个对象都可以调用.GetType()方法。
事实上,是否每个对象都继承自Type而不是object?如果是这样的话,那typeof(object)
/ (object)val.GetType()
如何工作呢?
我出于好奇研究了一下object,意识到它没有GetType()方法。然而通常有人说语言中的每个对象都可以调用.GetType()方法。
事实上,是否每个对象都继承自Type而不是object?如果是这样的话,那typeof(object)
/ (object)val.GetType()
如何工作呢?
我在互联网上找到了Konrad Kokosa写的一篇文章,其中详细解释了Object.GetType()
如何工作:
以下是这篇文章中的引用,应该能回答你的问题:
回答你的“一切都是从Type继承而不是object吗?”这个问题- 绝对不是。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.