How is Reflection implemented in C#?

The most significant parts of reflection are implemented as part of the CLI itself. As such, you could look at either the MS CLI reference source (aka "Rotor"), or the mono source. But: it will mostly be C/C++. The public API implementation details (MethodInfo, Type etc) may be C#.


It might not answer you question directly. However, here is a little outline of how managed code knows everything about types.

  1. Whenever you compile code the compiler analyzes/parses the source files and collects information it encounters. For example take a look at class below.

    class A
    {
      public int Prop1 {get; private set;}
      protected bool Met2(float input) {return true;}
    }
    

    The compiler can see that this is an internal class with two members. Member one is a property of type int with private setter. Member 2 is a protected method with name Met2 and type boolean that takes float input (input name is 'input'). So, it has all this information.

  2. It stores this information in the assembly. There are a couple of tables. For example classes (types) all leave in one table, methods live in another table. Think in turms of SQL tables, though they are definitely are not.

  3. When a user (developer) wants to know information about a type it calls GetType method. This method relies on objects hidden field - type object pointer. This object is basically a pointer to a class table. Each class table will have a pointer to the first method in methods table. Each method record will have a pointer to the first parameter in the parameters table.

PS: this mechamism is key to making .NET assemblies more secure. You cannot replace pointers to methods. It will break the signature of the assebmly.

JIT compilation relies heavily on this tables as well


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

Tags:

C#

.Net