How is Reflection implemented in C#?

前端 未结 4 720
我寻月下人不归
我寻月下人不归 2020-12-09 09:54

I got curious as to where Type.GetType() is implemented, so I took a peek at the assembly and noticed Type.GetType() calls base.GetType()

4条回答
  •  时光说笑
    2020-12-09 10:29

    The ACTUAL source for .NET Framework 2.0 is available on the internet (for educational purposes) here: http://www.microsoft.com/en-us/download/details.aspx?id=4917

    This is the C# Language implementation. You can use 7zip to unpack it. You will find the reflection namespace here (relatively):

    .\sscli20\clr\src\bcl\system\reflection

    I am digging for the specific implementation you are asking about, but this is a good start.

    UPDATE: Sorry, but I think its a dead end. Type.GetType() calls to the base implementation which comes from System.Object. If you inspect that codefile (.\sscli20\clr\src\bcl\system\object.cs) you will find the method is extern (see code below). Further inspect could uncover the implementation, but its not in the BCL. I suspect it will be in C++ code somewhere.

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

    UPDATE (AGAIN): I dug deeper and found the answer in the implementation of the CLR virtual machine itself. (Its in C++).

    The first piece of puzzle is here:

    \sscli20\clr\src\vm\ecall.cpp

    Here we see the code that maps the external call to an C++ function.

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

    Now, we need to go find ObjectNative::GetClass ... which is here:

    \sscli20\clr\src\vm\comobject.cpp

    and here is the implementation of GetType:

        FCIMPL1(Object*, ObjectNative::GetClass, Object* pThis)
    {
        CONTRACTL
        {
            THROWS;
            SO_TOLERANT;
            DISABLED(GC_TRIGGERS); // FCallCheck calls ForbidenGC now
            INJECT_FAULT(FCThrow(kOutOfMemoryException););
            SO_TOLERANT;
            MODE_COOPERATIVE;
        }
        CONTRACTL_END;
    
        OBJECTREF   objRef   = ObjectToOBJECTREF(pThis);
        OBJECTREF   refType  = NULL;
        TypeHandle  typeHandle = TypeHandle();
    
        if (objRef == NULL) 
            FCThrow(kNullReferenceException);
    
        typeHandle = objRef->GetTypeHandle();
        if (typeHandle.IsUnsharedMT())
            refType = typeHandle.AsMethodTable()->GetManagedClassObjectIfExists();
        else
            refType = typeHandle.GetManagedClassObjectIfExists();
    
        if (refType != NULL)
            return OBJECTREFToObject(refType);
    
        HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_2(Frame::FRAME_ATTR_RETURNOBJ, objRef, refType);
    
        if (!objRef->IsThunking())
            refType = typeHandle.GetManagedClassObject();
        else
            refType = CRemotingServices::GetClass(objRef);
        HELPER_METHOD_FRAME_END();
    
        return OBJECTREFToObject(refType);
    }
    FCIMPLEND
    

    One last thing, the implementation of GetTypeHandle along with some other supporting functions can be found in here:

    \sscli20\clr\src\vm\object.cpp

提交回复
热议问题