CIL指令“isinst”
ECMA 公共语言基础设施文档对 CIL“isinst class”指令有这样的描述:
正确的 CIL 确保 class 是指示类的有效 typeref 或 typedef 或 typespec 标记,并且 obj 始终为 null 或对象引用。
这意味着不允许使用值类型,对吧?但 mscorlib.dll 包含一个方法 System.RuntimeTypeHandle::Equals(object obj) ,其指令如下:
IL_0001: isinst System.RuntimeTypeHandle
并且 System.RuntimeTypeHandle 是 valuetype。有人可以把我放在这里吗?
The ECMA Common Language Infrastructure documentation says this about the CIL "isinst class" instruction:
Correct CIL ensures that class is a valid typeref or typedef or typespec token indicating a class, and
that obj is always either null or an object reference.
This implies that a valuetype is not allowed, right? But mscorlib.dll contains a method System.RuntimeTypeHandle::Equals(object obj) with the following instruction:
IL_0001: isinst System.RuntimeTypeHandle
And System.RuntimeTypeHandle is a valuetype. Can anybody put me right here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看一下
RuntimeTypeHandle
的声明:虽然
RuntimeTypeHandle
被声明为结构体,但它在 CIL 中的表示是某种特殊的类。换句话说,您可以将结构想象为继承自 System.ValueType 且其属性遵循严格顺序的特殊类。考虑到这一点,
isinst
可以通过RuntimeTypeHandle
进行调用。对于我的解释,isinst 根本不限于引用类型,只要有一个代表该类型的类即可。假设我们用 C# 编写:
我们收到编译器警告
会发生什么?我们将
4
分配给i
。i
变成一个int
。在下一行中,i
被自动装箱到其相应的ReferenceType
(类),因此警告是显而易见的。我们甚至可以写下“我希望这有助于澄清这个主题”。
Have a look at the declaration of
RuntimeTypeHandle
:Although
RuntimeTypeHandle
is declared as a struct its representation in CIL is some kind of special class. In other words, you can imagine structs as special classes that inherit fromSystem.ValueType
and whose attributes follow a strict order.With that in mind
isinst
would be callable withRuntimeTypeHandle
. For what I interpretisinst
is not limited to reference types at all as long as there is a class representing the type.Let's say we write in C#:
We get a compiler warning
What happens? We assign
4
toi
.i
becoms anint
. On the next linei
is being auto-boxed to its correspondingReferenceType
(class), so that the warning is obvious. We could even writeI hope this can contribute to some kind of clearification on this topic.
不,但他们的措辞令人困惑。这里的
class
是isinst
接受的第二个参数的名称。它是一个标记(可以认为是与类型相关的元数据表之一中的行的索引),表示接口、类或结构(基本上是任何类型
) 。有点隐藏的是从堆栈传递的第一个参数 - 对象引用。
如果
isinst
是一个 C# 方法,它将是这样的:在
RuntimeTypeHandle.Equals(object obj)
的示例中,您没有包含传递的第一行isinst
的对象参数:值类型的唯一问题是,从“假”
IsInst
的签名中,您会认识到我们需要box
我们的 valuetype 实例,然后才能传递它。例如,这个保证具有结构
value
的通用方法:在调用
isinst
之前将具有装箱代码:PS。
实际上,即使没有通用约束,我们也会进行装箱(参见 这个问题),但这更多地表明
isinst
总是需要对象引用。No, but they have worded it in a confusing way.
class
here is the name of second parameter thatisinst
accepts. It is a token (think an index of a row from one of the Type-related metadata tables) that represents an interface, a class or a struct (basically anyType
).What is a bit hidden is the first parameter that is passed from the stack - the object reference.
If
isinst
was a C# method it will be something like this:In your example with
RuntimeTypeHandle.Equals(object obj)
you didn't include the very first line which is passing of the object argument toisinst
:The only issue with value types is that from the signature of the "fake"
IsInst
you'd recognize that we need tobox
our valuetype instance before we can pass it.for example this generic method that is guaranteed to have a a struct
value
:will have boxing code before calling
isinst
:PS.
Actually we would have boxing even without the generic constraint (see this question), but that goes to show even more that
isinst
just always requires an object reference.