在C#中,每个对象是如何实现GetType方法的?

3

我出于好奇研究了一下object,意识到它没有GetType()方法。然而通常有人说语言中的每个对象都可以调用.GetType()方法。

事实上,是否每个对象都继承自Type而不是object?如果是这样的话,那typeof(object) / (object)val.GetType()如何工作呢?


说实话,我认为这不是全部情况。请查看referencesource - Lasse V. Karlsen
有趣的是,核心对象如此之小。我翻遍了存储库,寻找任何也是object的部分类,但都没有发现。这是否意味着在完整框架中,extern修饰符用于通过类型类公开get type的实现?(这非常酷) - Jlalonde
编译器和CLR会进行很多魔法操作,使我们能够以特定的方式处理某些对象,即使在类/接口中没有声明或实现。许多核心内部通常作为本地代码实现,可以是在外部库中或CLR本身中。对于数组和值类型,还有其他一些魔法操作的例子。 - Jeff Mercado
1个回答

4

我在互联网上找到了Konrad Kokosa写的一篇文章,其中详细解释了Object.GetType()如何工作:

http://tooslowexception.com/how-does-gettype-work/

以下是这篇文章中的引用,应该能回答你的问题:

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.

回答你的“一切都是从Type继承而不是object吗?”这个问题- 绝对不是。

1
看起来这篇文章的作者是一个 SO 用户:https://stackoverflow.com/users/2894974/konrad-kokosa :) - Yeldar Kurmangaliyev
感谢您的文章和出色的回答! - Jlalonde

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接