Как GetType реализован в каждом объекте в C #? - PullRequest
0 голосов
/ 04 марта 2019

Я смотрел на объект из любопытства и понял, что у объекта нет метода get type.Тем не менее, обычно утверждается, что каждый объект в языке может вызывать .GetType().

Действительно ли все наследуется от типа вместо объекта?И если это так, то как typeof(object) / (object)val.GetType() работает?

1 Ответ

0 голосов
/ 04 марта 2019

Я нашел в Интернете статью, написанную Конрадом Кокосой, в которой подробно объясняется, как работает 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 мы можем смотреть глубже.Если мы хотим найти реализацию внутренней функции InternalCall, мы смотрим на исходный файл 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 вместо object?»вопрос - точно нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...