如何在C#中的每个对象中实现GetType?

时间:2019-03-03 22:22:48

标签: c# reflection

出于好奇,我一直在看object,但我意识到对象没有get类型方法。然而,通常会说语言中的每个对象都可以调用.GetType()

所有内容实际上都继承自Type而不是对象吗?如果是这种情况,typeof(object) / (object)val.GetType()的工作原理是什么?

1 个答案:

答案 0 :(得分:4)

我在Internet上找到了Konrad Kokosa撰写的一篇文章,其中对Object.GetType()的工作方式进行了很好的解释: http://tooslowexception.com/how-does-gettype-work/

这是本文的引文,应该可以回答您的问题:

  

如果我们看一下.NET Framework Reference Source方法   Object.GetType(),很快就会发现实际上没有任何东西   有趣:

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

请注意,此方法未标记为虚拟方法,但其行为类似于   虚拟-每个对象都返回实际类型。这是由于   特殊的内部实施。 InternalCall的属性值   表示该方法在CLR内部实现。谢谢   我们可以更深入地了解CoreCLR。如果我们想找到一个内部功能   内部调用的实现,我们看一下CoreCLR的源文件   。\ Src \ vm \ ecalllist.h,那里有足够的映射。就我们而言   是

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

因此,我们开始执行(在此,我进一步省略了   相关代码):

// 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
     

简而言之,我们在这里看到的是所谓的对象的MethodTable   (Object :: GetMethodTable)并返回相应的Type对象   (MethodTable :: GetManagedClassObjectIfExists)或创建(如果存在)   不存在(GetClassHelper)1)。在这里,我们应该停下来片刻   为清楚起见,将我们的讨论分为不同的步骤。

回答“所有内容实际上都继承自Type而不是对象吗?”问题-绝对不是。