如何在C#中的每个对象中实现GetType?
出于好奇,我看了一下,发现这个对象并没有get-type方法。然而,人们通常说,语言中的每个对象都可以调用如何在C#中的每个对象中实现GetType?,c#,reflection,C#,Reflection,出于好奇,我看了一下,发现这个对象并没有get-type方法。然而,人们通常说,语言中的每个对象都可以调用.GetType() 所有东西实际上都是从类型而不是从对象继承的吗?如果是这样的话,typeof(object)/(object)val.GetType()是如何工作的?我在互联网上找到了康拉德·科科萨(Konrad Kokosa)写的一篇文章,这篇文章对object.GetType()的工作原理给出了很好的解释: 以下是这篇文章的引文,可以回答您的问题: 如果我们看一下.NETFrame
.GetType()
所有东西实际上都是从类型而不是从对象继承的吗?如果是这样的话,
typeof(object)
/(object)val.GetType()
是如何工作的?我在互联网上找到了康拉德·科科萨(Konrad Kokosa)写的一篇文章,这篇文章对object.GetType()
的工作原理给出了很好的解释:
以下是这篇文章的引文,可以回答您的问题:
如果我们看一下.NETFramework引用源方法
GetType(),很快就会发现实际上什么都没有
有趣的是:
// Returns a Type object which represent this object instance.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Type GetType();
请注意,此方法未标记为虚拟,但其行为类似于
虚拟–对于每个对象,返回实际类型。这是由于
特别,内部执行。InternalCall的属性值
表示该方法在CLR中内部实现。幸亏
我们可以看得更深一些。如果我们想找到一个内部函数
实现InternalCall时,我们查看CoreCLR的源文件
\Src\vm\ecalllist.h,其中有足够的映射。就我们而言
是的
因此,我们得到了一个实现(在这里,我不省略)
相关代码):
简而言之,我们在这里看到的是所谓的对象的MethodTable
(Object::GetMethodTable)并返回相应的类型对象
(MethodTable::GetManagedClassObjectiveExists)或创建它(如果有)
不存在(GetClassHelper)1)。我们应该在这里停一会儿,等一会儿
清晰性将我们的讨论分为不同的步骤
回答你的“所有东西实际上都是从类型而不是对象继承的吗?”问题——绝对不是 老实说,我认为这不是全部情况。看一看,有趣的是,核心的物体要小得多。我在存储库中查找了所有属于部分对象类的内容,结果是空的。这是否意味着在完整的框架中,extern修饰符用于通过type类公开get type的实现?(这很酷)编译器和CLR将发挥巨大的作用,使我们能够以某种方式处理某些对象,即使这些对象没有在类/接口中声明或实现。很多时候,很多核心内部代码都是在外部库或clr本身中作为本机代码实现的。这个魔术的其他例子是针对数组和值类型的。这篇文章的作者似乎是一个非常好的用户::)谢谢你的文章,回答得很好!
FCFuncStart(gObjectFuncs)
FCIntrinsic("GetType", ObjectNative::GetClass, CORINFO_INTRINSIC_Object_GetType)
FCFuncElement("MemberwiseClone", ObjectNative::Clone)
FCFuncEnd()
// This routine is called by the Object.GetType() routine. It is a major way to get the Sytem.Type
FCIMPL1(Object*, ObjectNative::GetClass, Object* pThis)
{
// ...
OBJECTREF objRef = ObjectToOBJECTREF(pThis);
if (objRef != NULL)
{
MethodTable* pMT = objRef->GetMethodTable();
OBJECTREF typePtr = pMT->GetManagedClassObjectIfExists();
if (typePtr != NULL)
{
return OBJECTREFToObject(typePtr);
}
}
else
FCThrow(kNullReferenceException);
FC_INNER_RETURN(Object*, GetClassHelper(objRef));
}
FCIMPLEND