gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 04:38:22 25 4
gpt4 key购买 nike

我很好奇 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com