c# - 反射在C#中是如何实现的?

标签 c# .net

我很好奇 Type.GetType() 是在哪里实现的,所以我看了一下程序集,注意到 Type.GetType() 调用了 base.GetType() 并且由于 Type 继承自 MemberInfo 我看了一下它被定义为 _MemberInfo.GetType()返回 this.GetType()。由于我找不到显示 C# 如何获取类型信息的实际代码,我想知道:

CLR 如何在运行时从对象中获取 Type 和 MemberInfo?

最佳答案

.NET Framework 2.0 的实际源代码可在互联网上获得(用于教育目的):http://www.microsoft.com/en-us/download/details.aspx?id=4917

这是 C# 语言实现。你可以使用 7zip 来解压它。您将在此处(相对)找到反射命名空间:

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

我正在研究您所询问的具体实现,但这是一个好的开始。

更新:抱歉,但我认为这是一条死胡同。 Type.GetType() 调用来自 System.Object 的基本实现。如果您检查该代码文件 (.\sscli20\clr\src\bcl\system\object.cs),您会发现该方法是 extern(请参阅下面的代码)。进一步检查可能会发现实现,但它不在 BCL 中。我怀疑它会在某处的 C++ 代码中。

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

更新(再次):我深入挖掘并在 CLR 虚拟机本身的实现中找到了答案。 (它在 C++ 中)。

第一 block 拼图在这里:

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

这里我们看到了将外部调用映射到 C++ 函数的代码。

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

现在,我们需要去寻找 ObjectNative::GetClass ...它在这里:

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

这里是 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

最后一件事,GetTypeHandle 的实现以及其他一些支持函数可以在这里找到:

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

关于c# - 反射在C#中是如何实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15105575/

相关文章:

c++ - 有没有可靠的方法可以在没有电子邮件客户端的情况下实现电子邮件功能?

c# - 使用客户端 Web 服务时出现内容错误

c# - 屏幕较小时增大字体大小

.net - 如何使用 PropertyDescriptor 实例作为绑定(bind)定义的一部分,而不是使用 PropertyPath?

c# - .NET 枚举类型实际上是可变值类型吗?

.net - 有人试过 FastReport .Net 吗?

c# - AJAX 页面的 EpiServer 本地化

c# - 跳过导航没有定义外键

c# - 通过 C# 代码打开 excel 时不执行宏,而手动打开 excel 时执行 VBA 代码

c# - 异步设计中的 session