Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is Reflection implemented in C#?

Tags:

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() and since Type inherits from MemberInfo I took a look and it is defined as _MemberInfo.GetType() which returns this.GetType(). Since I cannot find the actual code that shows how C# can get type information I would like to know:

How does the CLR get Type and MemberInfo from objects at Runtime?

like image 469
Dustin Kingen Avatar asked Feb 27 '13 06:02

Dustin Kingen


People also ask

How is reflection implemented in C#?

You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. If you are using attributes in your code, reflection enables you to access them.

Is there reflection in C?

A C reflection API provides access to runtime reflection metadata for C structure declarations with support for arbitrarily nested combinations of: intrinsic, set, enum, struct, union, field, array, constant, variable.

What is C in reflection?

Angle B is the angle of incidence (angle between the incident ray and the normal). Angle C is the angle of reflection (angle between the reflected ray and the normal). 2. A ray of light is incident towards a plane mirror at an angle of 30-degrees with the mirror surface.

What is reflection in C# Geeksforgeeks?

Reflection is the process of describing the metadata of types, methods and fields in a code. The namespace System.Reflection enables you to obtain data about the loaded assemblies, the elements within them like classes, methods and value types.


1 Answers

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

like image 62
Glenn Ferrie Avatar answered Oct 05 '22 02:10

Glenn Ferrie